• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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