1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
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
9 #include "audio_host.h"
10 #include "audio_codec_if.h"
11 #include "audio_core.h"
12 #include "audio_parse.h"
13
14 #define HDF_LOG_TAG audio_host
15
16 AUDIO_LIST_HEAD(cardManager);
17
18 /* Get a sound card instance */
GetCardInstance(const char * serviceName)19 struct AudioCard *GetCardInstance(const char *serviceName)
20 {
21 struct AudioCard *audioCard = NULL;
22
23 if (serviceName == NULL) {
24 ADM_LOG_ERR("serviceName is NULL.");
25 return NULL;
26 }
27
28 if (DListIsEmpty(&cardManager)) {
29 ADM_LOG_ERR("cardManager is empty.");
30 return NULL;
31 }
32
33 DLIST_FOR_EACH_ENTRY(audioCard, &cardManager, struct AudioCard, list) {
34 if (audioCard->configData.cardServiceName == NULL) {
35 ADM_LOG_ERR("cardServiceName is NULL.");
36 return NULL;
37 }
38
39 if (strcmp(audioCard->configData.cardServiceName, serviceName) == 0) {
40 return audioCard;
41 }
42 }
43 return NULL;
44 }
45
AudioCodecDevInit(struct AudioCard * audioCard)46 static int32_t AudioCodecDevInit(struct AudioCard *audioCard)
47 {
48 if (audioCard == NULL) {
49 ADM_LOG_ERR("audioCard is NULL.");
50 return HDF_ERR_IO;
51 }
52
53 ADM_LOG_DEBUG("entry.");
54 struct AudioRuntimeDeivces *rtd = NULL;
55 struct CodecDevice *codec = NULL;
56 rtd = audioCard->rtd;
57 if (rtd == NULL) {
58 ADM_LOG_ERR("rtd is NULL.");
59 return HDF_ERR_IO;
60 }
61 codec = rtd->codec;
62 if (codec != NULL && codec->devData != NULL && codec->devData->Init != NULL) {
63 /* codec initialization */
64 int32_t ret = codec->devData->Init(audioCard, codec);
65 if (ret != HDF_SUCCESS) {
66 ADM_LOG_ERR("codec initialization fail ret=%d", ret);
67 return HDF_ERR_IO;
68 }
69 }
70
71 ADM_LOG_INFO("success.");
72 return HDF_SUCCESS;
73 }
74
AudioAccessoryDevInit(struct AudioCard * audioCard)75 static int32_t AudioAccessoryDevInit(struct AudioCard *audioCard)
76 {
77 if (audioCard == NULL) {
78 ADM_LOG_ERR("audioCard is NULL.");
79 return HDF_ERR_IO;
80 }
81
82 ADM_LOG_DEBUG("entry.");
83 struct AudioRuntimeDeivces *rtd = NULL;
84 struct AccessoryDevice *accessory = NULL;
85 rtd = audioCard->rtd;
86 if (rtd == NULL) {
87 ADM_LOG_ERR("rtd is NULL.");
88 return HDF_ERR_IO;
89 }
90 accessory = rtd->accessory;
91 if (accessory != NULL && accessory->devData != NULL && accessory->devData->Init != NULL) {
92 /* codec initialization */
93 int32_t ret = accessory->devData->Init(audioCard, accessory);
94 if (ret != HDF_SUCCESS) {
95 ADM_LOG_ERR("accessory initialization fail ret=%d", ret);
96 return HDF_ERR_IO;
97 }
98 }
99
100 ADM_LOG_INFO("success.");
101 return HDF_SUCCESS;
102 }
103
AudioPlatformDevInit(const struct AudioCard * audioCard)104 static int32_t AudioPlatformDevInit(const struct AudioCard *audioCard)
105 {
106 struct AudioRuntimeDeivces *rtd = NULL;
107 struct PlatformDevice *platform = NULL;
108
109 if (audioCard == NULL) {
110 ADM_LOG_ERR("input param is NULL.");
111 return HDF_ERR_IO;
112 }
113 ADM_LOG_DEBUG("entry.");
114
115 rtd = audioCard->rtd;
116 if (rtd == NULL) {
117 ADM_LOG_ERR("Platform rtd is NULL.");
118 return HDF_ERR_IO;
119 }
120 platform = rtd->platform;
121 if (platform != NULL && platform->devData != NULL && platform->devData->PlatformInit != NULL) {
122 /* platform initialization */
123 int32_t ret = platform->devData->PlatformInit(audioCard, platform);
124 if (ret != HDF_SUCCESS) {
125 ADM_LOG_ERR("platform initialization fail ret=%d", ret);
126 return HDF_ERR_IO;
127 }
128 }
129
130 ADM_LOG_INFO("success.");
131 return HDF_SUCCESS;
132 }
133
AudioDspDevInit(const struct AudioCard * audioCard)134 static int32_t AudioDspDevInit(const struct AudioCard *audioCard)
135 {
136 struct AudioRuntimeDeivces *rtd = NULL;
137 struct DspDevice *dsp = NULL;
138
139 if (audioCard == NULL) {
140 ADM_LOG_ERR("audioCard is NULL.");
141 return HDF_ERR_IO;
142 }
143 ADM_LOG_DEBUG("entry.");
144
145 rtd = audioCard->rtd;
146 if (rtd == NULL) {
147 ADM_LOG_ERR("audioCard rtd object is NULL.");
148 return HDF_ERR_IO;
149 }
150
151 dsp = rtd->dsp;
152 if (dsp != NULL && dsp->devData != NULL && dsp->devData->DspInit != NULL) {
153 /* dsp initialization */
154 int32_t ret = dsp->devData->DspInit(dsp);
155 if (ret != HDF_SUCCESS) {
156 ADM_LOG_ERR("dsp initialization fail ret=%d", ret);
157 return HDF_ERR_IO;
158 }
159 }
160
161 ADM_LOG_INFO("success.");
162 return HDF_SUCCESS;
163 }
164
AudioCodecDaiDevInit(const struct AudioCard * audioCard)165 static int32_t AudioCodecDaiDevInit(const struct AudioCard *audioCard)
166 {
167 struct AudioRuntimeDeivces *rtd = NULL;
168 struct DaiDevice *codecDai = NULL;
169
170 if (audioCard == NULL) {
171 ADM_LOG_ERR("audioCard is NULL.");
172 return HDF_ERR_IO;
173 }
174 ADM_LOG_DEBUG("entry.");
175
176 rtd = audioCard->rtd;
177 if (rtd == NULL) {
178 ADM_LOG_ERR("CodecDai rtd is NULL.");
179 return HDF_ERR_IO;
180 }
181 codecDai = rtd->codecDai;
182 if (codecDai != NULL && codecDai->devData != NULL && codecDai->devData->DaiInit != NULL) {
183 /* codec dai initialization */
184 int32_t ret = codecDai->devData->DaiInit(audioCard, codecDai);
185 if (ret != HDF_SUCCESS) {
186 ADM_LOG_ERR("codec dai initialization fail ret=%d", ret);
187 return HDF_ERR_IO;
188 }
189 }
190
191 ADM_LOG_INFO("success.");
192 return HDF_SUCCESS;
193 }
194
AudioAccessoryDaiDevInit(const struct AudioCard * audioCard)195 static int32_t AudioAccessoryDaiDevInit(const struct AudioCard *audioCard)
196 {
197 struct AudioRuntimeDeivces *rtd = NULL;
198 struct DaiDevice *accessoryDai = NULL;
199
200 if (audioCard == NULL) {
201 ADM_LOG_ERR("audioCard is NULL.");
202 return HDF_ERR_IO;
203 }
204 ADM_LOG_DEBUG("entry.");
205
206 rtd = audioCard->rtd;
207 if (rtd == NULL) {
208 ADM_LOG_ERR("accessoryDai rtd is NULL.");
209 return HDF_ERR_IO;
210 }
211 accessoryDai = rtd->accessoryDai;
212 if (accessoryDai != NULL && accessoryDai->devData != NULL && accessoryDai->devData->DaiInit != NULL) {
213 /* codec dai initialization */
214 int32_t ret = accessoryDai->devData->DaiInit(audioCard, accessoryDai);
215 if (ret != HDF_SUCCESS) {
216 ADM_LOG_ERR("accessory dai initialization fail ret=%d", ret);
217 return HDF_ERR_IO;
218 }
219 }
220
221 ADM_LOG_INFO("success.");
222 return HDF_SUCCESS;
223 }
224
AudioCpuDaiDevInit(const struct AudioCard * audioCard)225 static int32_t AudioCpuDaiDevInit(const struct AudioCard *audioCard)
226 {
227 struct AudioRuntimeDeivces *rtd = NULL;
228 struct DaiDevice *cpuDai = NULL;
229
230 if (audioCard == NULL) {
231 ADM_LOG_ERR("audioCard is NULL.");
232 return HDF_ERR_IO;
233 }
234 ADM_LOG_DEBUG("entry.");
235
236 rtd = audioCard->rtd;
237 if (rtd == NULL) {
238 ADM_LOG_ERR("cpuDai rtd is NULL.");
239 return HDF_ERR_IO;
240 }
241 cpuDai = rtd->cpuDai;
242 if (cpuDai != NULL && cpuDai->devData != NULL && cpuDai->devData->DaiInit != NULL) {
243 /* cpu dai initialization */
244 int32_t ret = cpuDai->devData->DaiInit(audioCard, cpuDai);
245 if (ret != HDF_SUCCESS) {
246 ADM_LOG_ERR("cpu dai initialization fail ret=%d", ret);
247 return HDF_ERR_IO;
248 }
249 }
250
251 ADM_LOG_INFO("success.");
252 return HDF_SUCCESS;
253 }
254
AudioDspDaiDevInit(const struct AudioCard * audioCard)255 static int32_t AudioDspDaiDevInit(const struct AudioCard *audioCard)
256 {
257 struct AudioRuntimeDeivces *rtd = NULL;
258 struct DaiDevice *dspDai = NULL;
259 int ret;
260
261 if (audioCard == NULL) {
262 ADM_LOG_ERR("audioCard is NULL.");
263 return HDF_ERR_IO;
264 }
265 ADM_LOG_DEBUG("dsp init entry.");
266
267 rtd = audioCard->rtd;
268 if (rtd == NULL) {
269 ADM_LOG_ERR("dspDai rtd is NULL.");
270 return HDF_ERR_IO;
271 }
272
273 dspDai = rtd->dspDai;
274 if (dspDai != NULL && dspDai->devData != NULL && dspDai->devData->DaiInit != NULL) {
275 ret = dspDai->devData->DaiInit(audioCard, dspDai);
276 if (ret != HDF_SUCCESS) {
277 ADM_LOG_ERR("dsp dai initialization fail ret=%d", ret);
278 return HDF_ERR_IO;
279 }
280 }
281
282 ADM_LOG_INFO("success.");
283 return HDF_SUCCESS;
284 }
285
AudioInitDaiLink(struct AudioCard * audioCard)286 static int32_t AudioInitDaiLink(struct AudioCard *audioCard)
287 {
288 if (audioCard == NULL) {
289 ADM_LOG_ERR("audioCard is NULL.");
290 return HDF_ERR_IO;
291 }
292 ADM_LOG_DEBUG("entry.");
293
294 if (AudioPlatformDevInit(audioCard) || AudioCpuDaiDevInit(audioCard)) {
295 ADM_LOG_ERR("Platform and CpuDai init fail.");
296 return HDF_ERR_IO;
297 }
298
299 if ((AudioCodecDevInit(audioCard) || AudioCodecDaiDevInit(audioCard))) {
300 ADM_LOG_ERR("codec init fail.");
301 return HDF_ERR_IO;
302 }
303
304 if (AudioAccessoryDevInit(audioCard) || AudioAccessoryDaiDevInit(audioCard)) {
305 ADM_LOG_ERR("Accessory init fail.");
306 return HDF_ERR_IO;
307 }
308
309 if (AudioDspDevInit(audioCard) || AudioDspDaiDevInit(audioCard)) {
310 ADM_LOG_ERR("Dsp Dai init fail.");
311 return HDF_ERR_IO;
312 }
313
314 ADM_LOG_DEBUG("success.");
315 return HDF_SUCCESS;
316 }
317
AudioHostCreateAndBind(struct HdfDeviceObject * device)318 struct AudioHost *AudioHostCreateAndBind(struct HdfDeviceObject *device)
319 {
320 struct AudioHost *audioHost = NULL;
321
322 if (device == NULL) {
323 ADM_LOG_ERR("device is NULL!");
324 return NULL;
325 }
326
327 audioHost = (struct AudioHost *)OsalMemCalloc(sizeof(*audioHost));
328 if (audioHost == NULL) {
329 ADM_LOG_ERR("Malloc audio host fail!");
330 return NULL;
331 }
332 audioHost->device = device;
333 device->service = &audioHost->service;
334 return audioHost;
335 }
336
337 /* HdfDriverEntry implementations */
AudioDriverBind(struct HdfDeviceObject * device)338 static int32_t AudioDriverBind(struct HdfDeviceObject *device)
339 {
340 struct AudioHost *audioHost = NULL;
341
342 ADM_LOG_DEBUG("entry.");
343 if (device == NULL) {
344 ADM_LOG_ERR("device is NULL.");
345 return HDF_ERR_INVALID_OBJECT;
346 }
347
348 audioHost = AudioHostCreateAndBind(device);
349 if (audioHost == NULL) {
350 ADM_LOG_ERR("audioHost create failed!");
351 return HDF_FAILURE;
352 }
353
354 ADM_LOG_INFO("success.");
355 return HDF_SUCCESS;
356 }
357
AudioDriverInit(struct HdfDeviceObject * device)358 static int32_t AudioDriverInit(struct HdfDeviceObject *device)
359 {
360 struct AudioCard *audioCard = NULL;
361 struct AudioHost *audioHost = NULL;
362 int32_t ret;
363
364 ADM_LOG_DEBUG("entry.");
365 if (device == NULL) {
366 ADM_LOG_ERR("device is NULL.");
367 return HDF_ERR_INVALID_OBJECT;
368 }
369 audioHost = AudioHostFromDevice(device);
370 if (audioHost == NULL) {
371 ADM_LOG_ERR("audioHost is NULL.");
372 return HDF_FAILURE;
373 }
374
375 audioCard = (struct AudioCard *)OsalMemCalloc(sizeof(*audioCard));
376 if (audioCard == NULL) {
377 ADM_LOG_ERR("Malloc audioCard fail!");
378 return HDF_FAILURE;
379 }
380 audioHost->priv = audioCard;
381 /* Get node information through HCS file */
382 ret = AudioFillConfigData(device, &(audioCard->configData));
383 if (ret != HDF_SUCCESS) {
384 ADM_LOG_ERR("AudioFillConfigData fail ret=%d", ret);
385 return HDF_ERR_IO;
386 }
387
388 /* Bind specific codec、platform and dai device */
389 AudioBindDaiLink(audioCard, &(audioCard->configData));
390 if (!audioCard->rtd->complete) {
391 ADM_LOG_ERR("AudioBindDaiLink fail!");
392 return HDF_ERR_IO;
393 }
394
395 /* Initialize controls list */
396 DListHeadInit(&audioCard->controls);
397 DListHeadInit(&audioCard->components);
398 DListHeadInit(&audioCard->paths);
399 DListHeadInit(&audioCard->sapmDirty);
400 /* Initialize hardware device */
401 ret = AudioInitDaiLink(audioCard);
402 if (ret != HDF_SUCCESS) {
403 ADM_LOG_ERR("AudioInitDaiLink fail ret=%d", ret);
404 return HDF_ERR_IO;
405 }
406
407 /* sound card added to list */
408 DListInsertHead(&audioCard->list, &cardManager);
409
410 ADM_LOG_INFO("success.");
411 return HDF_SUCCESS;
412 }
413
AudioDriverRelease(struct HdfDeviceObject * device)414 static void AudioDriverRelease(struct HdfDeviceObject *device)
415 {
416 struct AudioHost *audioHost = NULL;
417 struct AudioCard *audioCard = NULL;
418
419 ADM_LOG_DEBUG("entry.");
420 if (device == NULL) {
421 ADM_LOG_ERR("device is NULL.");
422 return;
423 }
424 audioHost = AudioHostFromDevice(device);
425 if (audioHost == NULL) {
426 ADM_LOG_ERR("audioHost is NULL.");
427 return;
428 }
429
430 if (audioHost->priv != NULL) {
431 audioCard = (struct AudioCard *)audioHost->priv;
432 if (audioCard->rtd != NULL) {
433 OsalMemFree(audioCard->rtd);
434 }
435 OsalMemFree(audioHost->priv);
436 }
437 OsalMemFree(audioHost);
438
439 ADM_LOG_INFO("success.");
440 }
441
442 /* HdfDriverEntry definitions */
443 struct HdfDriverEntry g_audioDriverEntry = {
444 .moduleVersion = 1,
445 .moduleName = "HDF_AUDIO",
446 .Bind = AudioDriverBind,
447 .Init = AudioDriverInit,
448 .Release = AudioDriverRelease,
449 };
450 HDF_INIT(g_audioDriverEntry);
451