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_sapm.h"
13 #include "audio_driver_log.h"
14 #include "audio_parse.h"
15
16 #define HDF_LOG_TAG audio_host
17
18 AUDIO_LIST_HEAD(cardManager);
19
20 /* Get a sound card instance */
GetCardInstance(const char * serviceName)21 struct AudioCard *GetCardInstance(const char *serviceName)
22 {
23 struct AudioCard *audioCard = NULL;
24
25 if (serviceName == NULL) {
26 ADM_LOG_ERR("serviceName is NULL.");
27 return NULL;
28 }
29
30 if (DListIsEmpty(&cardManager)) {
31 ADM_LOG_ERR("cardManager is empty.");
32 return NULL;
33 }
34
35 DLIST_FOR_EACH_ENTRY(audioCard, &cardManager, struct AudioCard, list) {
36 if (audioCard->configData.cardServiceName == NULL) {
37 ADM_LOG_ERR("cardServiceName is NULL.");
38 return NULL;
39 }
40
41 if (strcmp(audioCard->configData.cardServiceName, serviceName) == 0) {
42 return audioCard;
43 }
44 }
45 ADM_LOG_ERR("serviceName is %s.", serviceName);
46 return NULL;
47 }
48
AudioCodecDevInit(struct AudioCard * audioCard)49 static int32_t AudioCodecDevInit(struct AudioCard *audioCard)
50 {
51 struct AudioRuntimeDeivces *rtd = NULL;
52 struct CodecDevice *codec = NULL;
53 ADM_LOG_DEBUG("entry.");
54
55 if (audioCard == NULL) {
56 ADM_LOG_ERR("audioCard is NULL.");
57 return HDF_ERR_IO;
58 }
59 rtd = audioCard->rtd;
60 if (rtd == NULL) {
61 ADM_LOG_ERR("rtd is NULL.");
62 return HDF_ERR_IO;
63 }
64 codec = rtd->codec;
65 if (codec != NULL && codec->devData != NULL && codec->devData->Init != NULL) {
66 /* codec initialization */
67 int32_t ret = codec->devData->Init(audioCard, codec);
68 if (ret != HDF_SUCCESS) {
69 ADM_LOG_ERR("codec initialization fail ret=%d", ret);
70 return HDF_ERR_IO;
71 }
72 }
73
74 ADM_LOG_INFO("success.");
75 return HDF_SUCCESS;
76 }
77
AudioAccessoryDevInit(struct AudioCard * audioCard)78 static int32_t AudioAccessoryDevInit(struct AudioCard *audioCard)
79 {
80 struct AudioRuntimeDeivces *rtd = NULL;
81 struct AccessoryDevice *accessory = NULL;
82 ADM_LOG_DEBUG("entry.");
83
84 if (audioCard == NULL) {
85 ADM_LOG_ERR("audioCard is NULL.");
86 return HDF_ERR_IO;
87 }
88
89 rtd = audioCard->rtd;
90 if (rtd == NULL) {
91 ADM_LOG_ERR("rtd is NULL.");
92 return HDF_ERR_IO;
93 }
94 accessory = rtd->accessory;
95 if (accessory != NULL && accessory->devData != NULL && accessory->devData->Init != NULL) {
96 /* codec initialization */
97 int32_t ret = accessory->devData->Init(audioCard, accessory);
98 if (ret != HDF_SUCCESS) {
99 ADM_LOG_ERR("accessory initialization fail ret=%d", ret);
100 return HDF_ERR_IO;
101 }
102 }
103
104 ADM_LOG_INFO("success.");
105 return HDF_SUCCESS;
106 }
107
AudioPlatformDevInit(const struct AudioCard * audioCard)108 static int32_t AudioPlatformDevInit(const struct AudioCard *audioCard)
109 {
110 struct AudioRuntimeDeivces *rtd = NULL;
111 struct PlatformDevice *platform = NULL;
112
113 if (audioCard == NULL) {
114 ADM_LOG_ERR("input param is NULL.");
115 return HDF_ERR_IO;
116 }
117 ADM_LOG_DEBUG("entry.");
118
119 rtd = audioCard->rtd;
120 if (rtd == NULL) {
121 ADM_LOG_ERR("Platform rtd is NULL.");
122 return HDF_ERR_IO;
123 }
124 platform = rtd->platform;
125 if (platform != NULL && platform->devData != NULL && platform->devData->PlatformInit != NULL) {
126 /* platform initialization */
127 int32_t ret = platform->devData->PlatformInit(audioCard, platform);
128 if (ret != HDF_SUCCESS) {
129 ADM_LOG_ERR("platform initialization fail ret=%d", ret);
130 return HDF_ERR_IO;
131 }
132 }
133
134 ADM_LOG_INFO("success.");
135 return HDF_SUCCESS;
136 }
137
AudioDspDevInit(const struct AudioCard * audioCard)138 static int32_t AudioDspDevInit(const struct AudioCard *audioCard)
139 {
140 struct AudioRuntimeDeivces *rtd = NULL;
141 struct DspDevice *dsp = NULL;
142
143 if (audioCard == NULL) {
144 ADM_LOG_ERR("audioCard is NULL.");
145 return HDF_ERR_IO;
146 }
147 ADM_LOG_DEBUG("entry.");
148
149 rtd = audioCard->rtd;
150 if (rtd == NULL) {
151 ADM_LOG_ERR("audioCard rtd object is NULL.");
152 return HDF_ERR_IO;
153 }
154
155 dsp = rtd->dsp;
156 if (dsp != NULL && dsp->devData != NULL && dsp->devData->DspInit != NULL) {
157 /* dsp initialization */
158 int32_t ret = dsp->devData->DspInit(dsp);
159 if (ret != HDF_SUCCESS) {
160 ADM_LOG_ERR("dsp initialization fail ret=%d", ret);
161 return HDF_ERR_IO;
162 }
163 }
164
165 ADM_LOG_INFO("success.");
166 return HDF_SUCCESS;
167 }
168
AudioCodecDaiDevInit(struct AudioCard * audioCard)169 static int32_t AudioCodecDaiDevInit(struct AudioCard *audioCard)
170 {
171 struct AudioRuntimeDeivces *rtd = NULL;
172 struct DaiDevice *codecDai = NULL;
173
174 if (audioCard == NULL) {
175 ADM_LOG_ERR("audioCard is NULL.");
176 return HDF_ERR_IO;
177 }
178 ADM_LOG_DEBUG("entry.");
179
180 rtd = audioCard->rtd;
181 if (rtd == NULL) {
182 ADM_LOG_ERR("CodecDai rtd is NULL.");
183 return HDF_ERR_IO;
184 }
185 codecDai = rtd->codecDai;
186 if (codecDai != NULL && codecDai->devData != NULL && codecDai->devData->DaiInit != NULL) {
187 /* codec dai initialization */
188 int32_t ret = codecDai->devData->DaiInit(audioCard, codecDai);
189 if (ret != HDF_SUCCESS) {
190 ADM_LOG_ERR("codec dai initialization fail ret=%d", ret);
191 return HDF_ERR_IO;
192 }
193 }
194
195 ADM_LOG_INFO("success.");
196 return HDF_SUCCESS;
197 }
198
AudioAccessoryDaiDevInit(struct AudioCard * audioCard)199 static int32_t AudioAccessoryDaiDevInit(struct AudioCard *audioCard)
200 {
201 struct AudioRuntimeDeivces *rtd = NULL;
202 struct DaiDevice *accessoryDai = NULL;
203
204 if (audioCard == NULL) {
205 ADM_LOG_ERR("audioCard is NULL.");
206 return HDF_ERR_IO;
207 }
208 ADM_LOG_DEBUG("entry.");
209
210 rtd = audioCard->rtd;
211 if (rtd == NULL) {
212 ADM_LOG_ERR("accessoryDai rtd is NULL.");
213 return HDF_ERR_IO;
214 }
215 accessoryDai = rtd->accessoryDai;
216 if (accessoryDai != NULL && accessoryDai->devData != NULL && accessoryDai->devData->DaiInit != NULL) {
217 /* codec dai initialization */
218 int32_t ret = accessoryDai->devData->DaiInit(audioCard, accessoryDai);
219 if (ret != HDF_SUCCESS) {
220 ADM_LOG_ERR("accessory dai initialization fail ret=%d", ret);
221 return HDF_ERR_IO;
222 }
223 }
224
225 ADM_LOG_INFO("success.");
226 return HDF_SUCCESS;
227 }
228
AudioCpuDaiDevInit(struct AudioCard * audioCard)229 static int32_t AudioCpuDaiDevInit(struct AudioCard *audioCard)
230 {
231 struct AudioRuntimeDeivces *rtd = NULL;
232 struct DaiDevice *cpuDai = NULL;
233
234 if (audioCard == NULL) {
235 ADM_LOG_ERR("audioCard is NULL.");
236 return HDF_ERR_IO;
237 }
238 ADM_LOG_DEBUG("entry.");
239
240 rtd = audioCard->rtd;
241 if (rtd == NULL) {
242 ADM_LOG_ERR("cpuDai rtd is NULL.");
243 return HDF_ERR_IO;
244 }
245 cpuDai = rtd->cpuDai;
246 if (cpuDai != NULL && cpuDai->devData != NULL && cpuDai->devData->DaiInit != NULL) {
247 /* cpu dai initialization */
248 int32_t ret = cpuDai->devData->DaiInit(audioCard, cpuDai);
249 if (ret != HDF_SUCCESS) {
250 ADM_LOG_ERR("cpu dai initialization fail ret=%d", ret);
251 return HDF_ERR_IO;
252 }
253 }
254
255 ADM_LOG_INFO("success.");
256 return HDF_SUCCESS;
257 }
258
AudioDspDaiDevInit(struct AudioCard * audioCard)259 static int32_t AudioDspDaiDevInit(struct AudioCard *audioCard)
260 {
261 struct AudioRuntimeDeivces *rtd = NULL;
262 struct DaiDevice *dspDai = NULL;
263 int ret = HDF_SUCCESS;
264
265 if (audioCard == NULL) {
266 ADM_LOG_ERR("audioCard is NULL.");
267 return HDF_ERR_IO;
268 }
269 ADM_LOG_DEBUG("dsp init entry.");
270
271 rtd = audioCard->rtd;
272 if (rtd == NULL) {
273 ADM_LOG_ERR("dspDai rtd is NULL.");
274 return HDF_ERR_IO;
275 }
276
277 dspDai = rtd->dspDai;
278 if (dspDai != NULL && dspDai->devData != NULL && dspDai->devData->DaiInit != NULL) {
279 ret = dspDai->devData->DaiInit(audioCard, dspDai);
280 if (ret != HDF_SUCCESS) {
281 ADM_LOG_ERR("dsp dai initialization fail ret=%d", ret);
282 return HDF_ERR_IO;
283 }
284 }
285
286 ADM_LOG_INFO("success.");
287 return HDF_SUCCESS;
288 }
289
AudioInitDaiLink(struct AudioCard * audioCard)290 static int32_t AudioInitDaiLink(struct AudioCard *audioCard)
291 {
292 if (audioCard == NULL) {
293 ADM_LOG_ERR("audioCard is NULL.");
294 return HDF_ERR_IO;
295 }
296 ADM_LOG_DEBUG("entry.");
297
298 if (AudioPlatformDevInit(audioCard) || AudioCpuDaiDevInit(audioCard)) {
299 ADM_LOG_ERR("Platform and CpuDai init fail.");
300 }
301
302 if ((AudioCodecDevInit(audioCard) || AudioCodecDaiDevInit(audioCard))) {
303 ADM_LOG_ERR("codec Device init fail.");
304 }
305
306 if (AudioAccessoryDevInit(audioCard) || AudioAccessoryDaiDevInit(audioCard)) {
307 ADM_LOG_ERR("Accessory Device init fail.");
308 }
309
310 if (AudioDspDevInit(audioCard) || AudioDspDaiDevInit(audioCard)) {
311 ADM_LOG_ERR("Dsp Device init fail.");
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 = (struct AudioHost *)device->service;
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 audioCard->device = device;
389 audioCard->standbyMode = AUDIO_SAPM_TURN_STANDBY_LATER;
390
391 /* Bind specific codec、platform and dai device */
392 ret = AudioBindDaiLink(audioCard, &(audioCard->configData));
393 if (ret != HDF_SUCCESS) {
394 ADM_LOG_ERR("AudioBindDaiLink fail ret=%d", ret);
395 return HDF_FAILURE;
396 }
397 if (audioCard->rtd == NULL || (!audioCard->rtd->complete)) {
398 ADM_LOG_ERR("AudioBindDaiLink fail!");
399 return HDF_ERR_IO;
400 }
401
402 /* Initialize controls list */
403 DListHeadInit(&audioCard->controls);
404 DListHeadInit(&audioCard->components);
405 DListHeadInit(&audioCard->paths);
406 DListHeadInit(&audioCard->sapmDirty);
407 /* Initialize hardware device */
408 ret = AudioInitDaiLink(audioCard);
409 if (ret != HDF_SUCCESS) {
410 ADM_LOG_ERR("AudioInitDaiLink fail ret=%d", ret);
411 return HDF_ERR_IO;
412 }
413
414 /* sound card added to list */
415 DListInsertHead(&audioCard->list, &cardManager);
416
417 ADM_LOG_INFO("success.");
418 return HDF_SUCCESS;
419 }
420
AudioDriverRelease(struct HdfDeviceObject * device)421 static void AudioDriverRelease(struct HdfDeviceObject *device)
422 {
423 struct AudioHost *audioHost = NULL;
424 struct AudioCard *audioCard = NULL;
425 struct DListHead *componentHead = NULL;
426 struct DListHead *controlHead = NULL;
427 struct AudioSapmComponent *componentReq = NULL;
428 struct AudioSapmComponent *componentTmp = NULL;
429 struct AudioKcontrol *ctrlReq = NULL;
430 struct AudioKcontrol *ctrlTmp = NULL;
431
432 ADM_LOG_DEBUG("entry.");
433 if (device == NULL) {
434 ADM_LOG_ERR("device is NULL.");
435 return;
436 }
437 audioHost = (struct AudioHost *)device->service;
438 if (audioHost == NULL) {
439 ADM_LOG_ERR("audioHost is NULL.");
440 return;
441 }
442
443 if (audioHost->priv != NULL) {
444 audioCard = (struct AudioCard *)audioHost->priv;
445
446 componentHead = &audioCard->components;
447 DLIST_FOR_EACH_ENTRY_SAFE(componentReq, componentTmp, componentHead, struct AudioSapmComponent, list) {
448 DListRemove(&componentReq->list);
449 if (componentReq->componentName != NULL) {
450 OsalMemFree(componentReq->componentName);
451 }
452 OsalMemFree(componentReq);
453 }
454
455 controlHead = &audioCard->controls;
456 DLIST_FOR_EACH_ENTRY_SAFE(ctrlReq, ctrlTmp, controlHead, struct AudioKcontrol, list) {
457 DListRemove(&ctrlReq->list);
458 if (ctrlReq->pri != NULL) {
459 OsalMemFree(ctrlReq->pri);
460 }
461 if (ctrlReq->privateData != NULL) {
462 OsalMemFree(ctrlReq->privateData);
463 }
464 OsalMemFree(ctrlReq);
465 }
466
467 if (audioCard->rtd != NULL) {
468 OsalMemFree(audioCard->rtd);
469 }
470
471 if (audioHost->priv != NULL) {
472 OsalMemFree(audioHost->priv);
473 }
474 }
475
476 if (audioHost != NULL) {
477 OsalMemFree(audioHost);
478 }
479 ADM_LOG_INFO("success.");
480 }
481
482 /* HdfDriverEntry definitions */
483 struct HdfDriverEntry g_audioDriverEntry = {
484 .moduleVersion = 1,
485 .moduleName = "HDF_AUDIO",
486 .Bind = AudioDriverBind,
487 .Init = AudioDriverInit,
488 .Release = AudioDriverRelease,
489 };
490 HDF_INIT(g_audioDriverEntry);
491