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