1 /*
2 * Copyright (C) 2022 HiHope Open Source Organization .
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8 #include <linux/io.h>
9 #include <linux/delay.h>
10 #include "audio_core.h"
11 #include "audio_host.h"
12 #include "audio_platform_base.h"
13 #include "osal_io.h"
14 #include "audio_driver_log.h"
15 #include "rk3568_dai_ops.h"
16 #include "audio_dai_base.h"
17
18 struct AudioDaiOps g_daiDeviceOps = {
19 .Startup = Rk3568DaiStartup,
20 .HwParams = Rk3568DaiHwParams,
21 .Trigger = Rk3568NormalTrigger,
22 };
23
24 /* HdfDriverEntry implementations */
DaiDriverBind(struct HdfDeviceObject * device)25 static int32_t DaiDriverBind(struct HdfDeviceObject *device)
26 {
27 struct DaiHost *daiHost = NULL;
28 AUDIO_DRIVER_LOG_DEBUG("entry!");
29
30 if (device == NULL) {
31 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
32 return HDF_FAILURE;
33 }
34
35 daiHost = (struct DaiHost *)OsalMemCalloc(sizeof(*daiHost));
36 if (daiHost == NULL) {
37 AUDIO_DEVICE_LOG_ERR("malloc host fail!");
38 return HDF_FAILURE;
39 }
40
41 daiHost->device = device;
42 device->service = &daiHost->service;
43
44 AUDIO_DRIVER_LOG_DEBUG("success!");
45 return HDF_SUCCESS;
46 }
47
48
DaiGetServiceName(const struct HdfDeviceObject * device,struct DaiData * daiData)49 static int32_t DaiGetServiceName(const struct HdfDeviceObject *device, struct DaiData *daiData)
50 {
51 const struct DeviceResourceNode *node = NULL;
52 struct DeviceResourceIface *drsOps = NULL;
53 int32_t ret;
54 AUDIO_DRIVER_LOG_DEBUG("entry!");
55
56 if (device == NULL || daiData == NULL) {
57 AUDIO_DEVICE_LOG_ERR("input para is nullptr.");
58 return HDF_FAILURE;
59 }
60
61 node = device->property;
62 if (node == NULL) {
63 AUDIO_DEVICE_LOG_ERR("drs node is nullptr.");
64 return HDF_FAILURE;
65 }
66 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
67 if (drsOps == NULL || drsOps->GetString == NULL) {
68 AUDIO_DEVICE_LOG_ERR("invalid drs ops fail!");
69 return HDF_FAILURE;
70 }
71
72 ret = drsOps->GetString(node, "serviceName", &daiData->drvDaiName, 0);
73 if (ret != HDF_SUCCESS) {
74 AUDIO_DEVICE_LOG_ERR("read serviceName fail!");
75 return ret;
76 }
77
78 AUDIO_DRIVER_LOG_DEBUG("success!");
79 return HDF_SUCCESS;
80 }
81
DaiDriverInit(struct HdfDeviceObject * device)82 static int32_t DaiDriverInit(struct HdfDeviceObject *device)
83 {
84 int32_t ret = 0;
85 struct DaiData *daiData = NULL;
86 struct DaiHost *daiHost = NULL;
87
88 AUDIO_DRIVER_LOG_DEBUG("entry!");
89 if (device == NULL) {
90 AUDIO_DEVICE_LOG_ERR("device is nullptr.");
91 return HDF_ERR_INVALID_OBJECT;
92 }
93
94 daiHost = (struct DaiHost *)device->service;
95 if (daiHost == NULL) {
96 AUDIO_DEVICE_LOG_ERR("daiHost is NULL");
97 return HDF_FAILURE;
98 }
99
100 daiData = (struct DaiData *)OsalMemCalloc(sizeof(*daiData));
101 if (daiData == NULL) {
102 AUDIO_DEVICE_LOG_ERR("malloc DaiData fail!");
103 return HDF_FAILURE;
104 }
105 daiData->Read = Rk3568DeviceReadReg,
106 daiData->Write = Rk3568DeviceWriteReg,
107 daiData->DaiInit = Rk3568DaiDeviceInit,
108 daiData->ops = &g_daiDeviceOps,
109 daiData->daiInitFlag = false;
110 OsalMutexInit(&daiData->mutex);
111 daiHost->priv = daiData;
112
113 if (DaiGetConfigInfo(device, daiData) != HDF_SUCCESS) {
114 AUDIO_DEVICE_LOG_ERR("get dai data fail.");
115 OsalMemFree(daiData);
116 return HDF_FAILURE;
117 }
118
119 if (DaiGetServiceName(device, daiData) != HDF_SUCCESS) {
120 AUDIO_DEVICE_LOG_ERR("get service name fail.");
121 OsalMemFree(daiData);
122 return HDF_FAILURE;
123 }
124
125 ret = AudioSocRegisterDai(device, (void *)daiData);
126 if (ret != HDF_SUCCESS) {
127 AUDIO_DEVICE_LOG_ERR("register dai fail.");
128 OsalMemFree(daiData);
129 return ret;
130 }
131
132 AUDIO_DRIVER_LOG_DEBUG("success.\n");
133 return HDF_SUCCESS;
134 }
135
DaiDriverRelease(struct HdfDeviceObject * device)136 static void DaiDriverRelease(struct HdfDeviceObject *device)
137 {
138 struct DaiHost *daiHost = NULL;
139 struct DaiData *daiData = NULL;
140
141 AUDIO_DRIVER_LOG_DEBUG("entry!");
142 if (device == NULL) {
143 AUDIO_DEVICE_LOG_ERR("device is NULL");
144 return;
145 }
146
147 daiHost = (struct DaiHost *)device->service;
148 if (daiHost == NULL) {
149 AUDIO_DEVICE_LOG_ERR("daiHost is NULL");
150 return;
151 }
152
153 daiData = (struct DaiData *)daiHost->priv;
154 if (daiData != NULL) {
155 OsalMutexDestroy(&daiData->mutex);
156 OsalMemFree(daiData);
157 }
158
159 OsalMemFree(daiHost);
160 AUDIO_DRIVER_LOG_DEBUG("success!");
161 }
162
163 /* HdfDriverEntry definitions */
164 struct HdfDriverEntry g_daiDriverEntry = {
165 .moduleVersion = 1,
166 .moduleName = "DAI_RK3568",
167 .Bind = DaiDriverBind,
168 .Init = DaiDriverInit,
169 .Release = DaiDriverRelease,
170 };
171 HDF_INIT(g_daiDriverEntry);
172