• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021–2022 Beijing OSWare Technology Co., Ltd
3  * This file contains confidential and proprietary information of
4  * OSWare Technology Co., Ltd
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include "audio_core.h"
20 #include "audio_driver_log.h"
21 #include "imx8mm_platform.h"
22 #include "imx8mm_common.h"
23 #include "osal_mem.h"
24 #include "imx8mm_platform_ops.h"
25 
26 #define HDF_LOG_TAG imx8mm_platform_adapter
27 
28 #define PLATFORM_FIND_SUCCESS 2
29 #define PLATFORM_FIND_NEXT    0
30 
31 static int32_t AudioPlatformDeviceInit(const struct AudioCard *card, const struct PlatformDevice *platform);
32 static int32_t PlatformDmaPrvDataInit(struct PlatformData *data, struct HdfDeviceObject *device);
33 
34 struct AudioDmaOps g_platform_device_ops = {
35     .DmaBufAlloc = Imx8mmDmaBufAlloc,
36     .DmaBufFree = Imx8mmDmaBufFree,
37     .DmaRequestChannel = Imx8mmDmaRequestChannel,
38     .DmaConfigChannel = Imx8mmDmaConfigChannel,
39     .DmaPrep = Imx8mmDmaPrep,
40     .DmaSubmit = Imx8mmDmaSubmit,
41     .DmaPending = Imx8mmDmaPending,
42     .DmaPause = Imx8mmDmaPause,
43     .DmaResume = Imx8mmDmaResume,
44     .DmaPointer = Imx8mmDmaPointer,
45 };
46 
47 struct PlatformData g_platform_data = {
48     .PlatformInit = AudioPlatformDeviceInit,
49     .ops = &g_platform_device_ops,
50     .platformInitFlag = false,
51 };
52 
53 /* HdfDriverEntry implementations */
PlatformDriverBind(struct HdfDeviceObject * device)54 static int32_t PlatformDriverBind(struct HdfDeviceObject *device)
55 {
56     struct PlatformHost *platformHost = NULL;
57     AUDIO_DRIVER_LOG_DEBUG("entry!");
58 
59     if (device == NULL) {
60         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
61         return HDF_FAILURE;
62     }
63 
64     platformHost = (struct PlatformHost *)OsalMemCalloc(sizeof(*platformHost));
65     if (platformHost == NULL) {
66         AUDIO_DRIVER_LOG_ERR("malloc host fail!");
67         return HDF_FAILURE;
68     }
69 
70     platformHost->device = device;
71     device->service = &platformHost->service;
72 
73     AUDIO_DRIVER_LOG_DEBUG("success!");
74     return HDF_SUCCESS;
75 }
76 
PlatformGetServiceName(const struct HdfDeviceObject * device)77 static int32_t PlatformGetServiceName(const struct HdfDeviceObject *device)
78 {
79     const struct DeviceResourceNode *node = NULL;
80     struct DeviceResourceIface *drsOps = NULL;
81     int32_t ret;
82 
83     if (device == NULL) {
84         AUDIO_DRIVER_LOG_ERR("para is NULL.");
85         return HDF_FAILURE;
86     }
87 
88     node = device->property;
89     if (node == NULL) {
90         AUDIO_DRIVER_LOG_ERR("node is NULL.");
91         return HDF_FAILURE;
92     }
93 
94     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
95     if (drsOps == NULL || drsOps->GetString == NULL) {
96         AUDIO_DRIVER_LOG_ERR("get drsops object instance fail!");
97         return HDF_FAILURE;
98     }
99 
100     ret = drsOps->GetString(node, "serviceName", &g_platform_data.drvPlatformName, 0);
101     if (ret != HDF_SUCCESS) {
102         AUDIO_DRIVER_LOG_ERR("read serviceName fail!");
103         return ret;
104     }
105 
106     return HDF_SUCCESS;
107 }
108 
PlatformDriverInit(struct HdfDeviceObject * device)109 static int32_t PlatformDriverInit(struct HdfDeviceObject *device)
110 {
111     int32_t ret;
112 
113     AUDIO_DRIVER_LOG_DEBUG("entry.\n");
114     struct PlatformHost *platformHost = NULL;
115 
116     if (device == NULL) {
117         AUDIO_DRIVER_LOG_ERR("device is NULL.");
118         return HDF_ERR_INVALID_OBJECT;
119     }
120 
121     ret = PlatformGetServiceName(device);
122     if (ret !=  HDF_SUCCESS) {
123         AUDIO_DRIVER_LOG_ERR("get service name fail.");
124         return ret;
125     }
126 
127     ret = AudioSocRegisterPlatform(device, (struct PlatformData *)(&g_platform_data));
128     if (ret !=  HDF_SUCCESS) {
129         AUDIO_DRIVER_LOG_ERR("register dai fail.");
130         return ret;
131     }
132 
133     platformHost = (struct PlatformHost *)device->service;
134     if (platformHost != NULL) {
135         OsalMutexInit(&g_platform_data.renderBufInfo.buffMutex);
136         OsalMutexInit(&g_platform_data.captureBufInfo.buffMutex);
137     }
138 
139     ret = PlatformDmaPrvDataInit(&g_platform_data, device);
140     if (ret != HDF_SUCCESS) {
141         AUDIO_DRIVER_LOG_ERR("platform soc init fail");
142         return ret;
143     }
144 
145     AUDIO_DRIVER_LOG_INFO("success.\n");
146     return HDF_SUCCESS;
147 }
148 
PlatformDriverRelease(struct HdfDeviceObject * device)149 static void PlatformDriverRelease(struct HdfDeviceObject *device)
150 {
151     struct PlatformHost *platformHost = NULL;
152 
153     if (device == NULL) {
154         AUDIO_DRIVER_LOG_ERR("device is NULL");
155         return;
156     }
157 
158     platformHost = (struct PlatformHost *)device->service;
159     if (platformHost == NULL) {
160         AUDIO_DRIVER_LOG_ERR("platformHost is NULL");
161         return;
162     }
163 
164     OsalMutexDestroy(&g_platform_data.renderBufInfo.buffMutex);
165     OsalMutexDestroy(&g_platform_data.captureBufInfo.buffMutex);
166     OsalMemFree(platformHost);
167 }
168 
AudioPlatformDeviceInit(const struct AudioCard * card,const struct PlatformDevice * platform)169 static int32_t AudioPlatformDeviceInit(const struct AudioCard *card, const struct PlatformDevice *platform)
170 {
171     AUDIO_DRIVER_LOG_ERR("ENTRY");
172     if (card == NULL || platform == NULL || platform->devData == NULL) {
173         AUDIO_DRIVER_LOG_ERR("platform is NULL.");
174         return HDF_FAILURE;
175     }
176     if (platform->devData->platformInitFlag == true) {
177         AUDIO_DRIVER_LOG_DEBUG("platform init complete!");
178         return HDF_SUCCESS;
179     }
180     platform->devData->platformInitFlag = true;
181 
182     SaiDaiProbe(platform->devData);
183 
184     return HDF_SUCCESS;
185 }
186 
PlatformGetInfoFromHcs(struct PrivPlatformData * ppd,const struct DeviceResourceNode * node)187 static int32_t PlatformGetInfoFromHcs(struct PrivPlatformData *ppd,
188                                       const struct DeviceResourceNode *node)
189 {
190     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
191     if (ppd == NULL || node == NULL || iface == NULL || iface->GetString == NULL) {
192         AUDIO_DRIVER_LOG_ERR("face is invalid");
193         return HDF_FAILURE;
194     }
195 
196     if (iface->GetString(node, "sai_name", &ppd->sai_name, NULL) != HDF_SUCCESS) {
197         AUDIO_DRIVER_LOG_ERR("read sai_name fail");
198         return HDF_FAILURE;
199     }
200 
201     AUDIO_DRIVER_LOG_ERR("sai name = %s", ppd->sai_name);
202 
203     return HDF_SUCCESS;
204 }
205 
PlatformFindDeviceFromBus(struct device * dev,void * para)206 static int32_t PlatformFindDeviceFromBus(struct device *dev, void *para)
207 {
208     struct platform_device *pdev = NULL;
209     struct PrivPlatformData *ppd = (struct PrivPlatformData*)para;
210 
211     if (dev == NULL || para == NULL) {
212         AUDIO_DRIVER_LOG_ERR("invalid param");
213         return HDF_ERR_INVALID_PARAM;
214     }
215 
216     pdev = to_platform_device(dev);
217     if (pdev->name == NULL) {
218         AUDIO_DRIVER_LOG_ERR("pdev name NULL");
219         return HDF_ERR_INVALID_PARAM;
220     }
221 
222     if (!strstr(pdev->name, ppd->sai_name)) {
223         return PLATFORM_FIND_NEXT;
224     }
225     ppd->pdev = pdev;
226 
227     return PLATFORM_FIND_SUCCESS;
228 }
229 
PlatformDmaPrvDataInit(struct PlatformData * data,struct HdfDeviceObject * device)230 static int32_t PlatformDmaPrvDataInit(struct PlatformData *data, struct HdfDeviceObject *device)
231 {
232     int32_t ret;
233     struct PrivPlatformData *ppd = NULL;
234 
235     if (device->property == NULL|| data == NULL) {
236         AUDIO_DRIVER_LOG_ERR("property is null");
237         return HDF_FAILURE;
238     }
239 
240     ppd = (struct PrivPlatformData *)OsalMemCalloc(sizeof(struct PrivPlatformData));
241     if (ppd == NULL) {
242         AUDIO_DRIVER_LOG_ERR("OsalMemCalloc malloc error");
243         return HDF_ERR_MALLOC_FAIL;
244     }
245 
246     ret = PlatformGetInfoFromHcs(ppd, device->property);
247     if (ret != HDF_SUCCESS) {
248         AUDIO_DRIVER_LOG_ERR("PlatformGetInfoFromHcs error");
249         OsalMemFree(ppd);
250         return HDF_FAILURE;
251     }
252 
253     data->dmaPrv = ppd;
254 
255     ret = bus_for_each_dev(&platform_bus_type, NULL, (void*)ppd, PlatformFindDeviceFromBus);
256     if (ret != PLATFORM_FIND_SUCCESS) {
257         AUDIO_DRIVER_LOG_ERR("platform find fail, ret is %d", ret);
258         return HDF_FAILURE;
259     }
260 
261     AUDIO_DRIVER_LOG_ERR("sai_name = %s", ppd->pdev->name);
262 
263     ret = SaiDriverInit(data);
264     AUDIO_DRIVER_LOG_ERR("RET = %d", ret);
265     ret = DmaInit(data);
266     AUDIO_DRIVER_LOG_ERR("RET = %d", ret);
267 
268     return HDF_SUCCESS;
269 }
270 
271 /* HdfDriverEntry definitions */
272 struct HdfDriverEntry g_platform_driver_entry = {
273     .moduleVersion = 1,
274     .moduleName = "SAI_IMX8",
275     .Bind = PlatformDriverBind,
276     .Init = PlatformDriverInit,
277     .Release = PlatformDriverRelease,
278 };
279 HDF_INIT(g_platform_driver_entry);
280