• 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 HDF_AUDIO_KADM
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 
AudioPlatformDevInit(const struct AudioCard * audioCard)78 static int32_t AudioPlatformDevInit(const struct AudioCard *audioCard)
79 {
80     struct AudioRuntimeDeivces *rtd = NULL;
81     struct PlatformDevice *platform = NULL;
82 
83     if (audioCard == NULL) {
84         ADM_LOG_ERR("input param is NULL.");
85         return HDF_ERR_IO;
86     }
87     ADM_LOG_DEBUG("entry.");
88 
89     rtd = audioCard->rtd;
90     if (rtd == NULL) {
91         ADM_LOG_ERR("Platform rtd is NULL.");
92         return HDF_ERR_IO;
93     }
94     platform = rtd->platform;
95     if (platform != NULL && platform->devData != NULL && platform->devData->PlatformInit != NULL) {
96         /* platform initialization */
97         int32_t ret = platform->devData->PlatformInit(audioCard, platform);
98         if (ret != HDF_SUCCESS) {
99             ADM_LOG_ERR("platform initialization fail ret=%d", ret);
100             return HDF_ERR_IO;
101         }
102     }
103 
104     ADM_LOG_INFO("success.");
105     return HDF_SUCCESS;
106 }
107 
AudioDspDevInit(const struct AudioCard * audioCard)108 static int32_t AudioDspDevInit(const struct AudioCard *audioCard)
109 {
110     struct AudioRuntimeDeivces *rtd = NULL;
111     struct DspDevice *dsp = NULL;
112 
113     if (audioCard == NULL) {
114         ADM_LOG_ERR("audioCard 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("audioCard rtd object is NULL.");
122         return HDF_ERR_IO;
123     }
124 
125     dsp = rtd->dsp;
126     if (dsp != NULL && dsp->devData != NULL && dsp->devData->DspInit != NULL) {
127         /* dsp initialization */
128         int32_t ret = dsp->devData->DspInit(dsp);
129         if (ret != HDF_SUCCESS) {
130             ADM_LOG_ERR("dsp initialization fail ret=%d", ret);
131             return HDF_ERR_IO;
132         }
133     }
134 
135     ADM_LOG_INFO("success.");
136     return HDF_SUCCESS;
137 }
138 
AudioCodecDaiDevInit(struct AudioCard * audioCard)139 static int32_t AudioCodecDaiDevInit(struct AudioCard *audioCard)
140 {
141     struct AudioRuntimeDeivces *rtd = NULL;
142     struct DaiDevice *codecDai = NULL;
143 
144     if (audioCard == NULL) {
145         ADM_LOG_ERR("audioCard is NULL.");
146         return HDF_ERR_IO;
147     }
148     ADM_LOG_DEBUG("entry.");
149 
150     rtd = audioCard->rtd;
151     if (rtd == NULL) {
152         ADM_LOG_ERR("CodecDai rtd is NULL.");
153         return HDF_ERR_IO;
154     }
155     codecDai = rtd->codecDai;
156     if (codecDai != NULL && codecDai->devData != NULL && codecDai->devData->DaiInit != NULL) {
157         /* codec dai initialization */
158         int32_t ret = codecDai->devData->DaiInit(audioCard, codecDai);
159         if (ret != HDF_SUCCESS) {
160             ADM_LOG_ERR("codec dai initialization fail ret=%d", ret);
161             return HDF_ERR_IO;
162         }
163     }
164 
165     ADM_LOG_INFO("success.");
166     return HDF_SUCCESS;
167 }
168 
AudioCpuDaiDevInit(struct AudioCard * audioCard)169 static int32_t AudioCpuDaiDevInit(struct AudioCard *audioCard)
170 {
171     struct AudioRuntimeDeivces *rtd = NULL;
172     struct DaiDevice *cpuDai = 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("cpuDai rtd is NULL.");
183         return HDF_ERR_IO;
184     }
185     cpuDai = rtd->cpuDai;
186     if (cpuDai != NULL && cpuDai->devData != NULL && cpuDai->devData->DaiInit != NULL) {
187         /* cpu dai initialization */
188         int32_t ret = cpuDai->devData->DaiInit(audioCard, cpuDai);
189         if (ret != HDF_SUCCESS) {
190             ADM_LOG_ERR("cpu 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 
AudioDspDaiDevInit(struct AudioCard * audioCard)199 static int32_t AudioDspDaiDevInit(struct AudioCard *audioCard)
200 {
201     struct AudioRuntimeDeivces *rtd = NULL;
202     struct DaiDevice *dspDai = NULL;
203     int32_t ret;
204 
205     if (audioCard == NULL) {
206         ADM_LOG_ERR("audioCard is NULL.");
207         return HDF_ERR_IO;
208     }
209     ADM_LOG_DEBUG("dsp init entry.");
210 
211     rtd = audioCard->rtd;
212     if (rtd == NULL) {
213         ADM_LOG_ERR("dspDai rtd is NULL.");
214         return HDF_ERR_IO;
215     }
216 
217     dspDai = rtd->dspDai;
218     if (dspDai != NULL && dspDai->devData != NULL && dspDai->devData->DaiInit != NULL) {
219         ret = dspDai->devData->DaiInit(audioCard, dspDai);
220         if (ret != HDF_SUCCESS) {
221             ADM_LOG_ERR("dsp dai initialization fail ret=%d", ret);
222             return HDF_ERR_IO;
223         }
224     }
225 
226     ADM_LOG_INFO("success.");
227     return HDF_SUCCESS;
228 }
229 
AudioInitDaiLink(struct AudioCard * audioCard)230 static int32_t AudioInitDaiLink(struct AudioCard *audioCard)
231 {
232     if (audioCard == NULL) {
233         ADM_LOG_ERR("audioCard is NULL.");
234         return HDF_ERR_IO;
235     }
236     ADM_LOG_DEBUG("entry.");
237 
238     if (AudioPlatformDevInit(audioCard) || AudioCpuDaiDevInit(audioCard)) {
239         ADM_LOG_ERR("Platform and CpuDai init fail.");
240         return HDF_FAILURE;
241     }
242 
243     if ((AudioCodecDevInit(audioCard) || AudioCodecDaiDevInit(audioCard))) {
244         ADM_LOG_ERR("codec Device init fail.");
245         return HDF_FAILURE;
246     }
247 
248     if (AudioDspDevInit(audioCard) || AudioDspDaiDevInit(audioCard)) {
249         ADM_LOG_ERR("Dsp Device init fail.");
250         return HDF_FAILURE;
251     }
252 
253     ADM_LOG_DEBUG("success.");
254     return HDF_SUCCESS;
255 }
256 
AudioHostCreateAndBind(struct HdfDeviceObject * device)257 struct AudioHost *AudioHostCreateAndBind(struct HdfDeviceObject *device)
258 {
259     struct AudioHost *audioHost = NULL;
260 
261     if (device == NULL) {
262         ADM_LOG_ERR("device is NULL!");
263         return NULL;
264     }
265 
266     audioHost = (struct AudioHost *)OsalMemCalloc(sizeof(*audioHost));
267     if (audioHost == NULL) {
268         ADM_LOG_ERR("Malloc audio host fail!");
269         return NULL;
270     }
271     audioHost->device = device;
272     device->service = &audioHost->service;
273     return audioHost;
274 }
275 
276 /* HdfDriverEntry implementations */
AudioDriverBind(struct HdfDeviceObject * device)277 static int32_t AudioDriverBind(struct HdfDeviceObject *device)
278 {
279     struct AudioHost *audioHost = NULL;
280 
281     ADM_LOG_DEBUG("entry.");
282     if (device == NULL) {
283         ADM_LOG_ERR("device is NULL.");
284         return HDF_ERR_INVALID_OBJECT;
285     }
286 
287     audioHost = AudioHostCreateAndBind(device);
288     if (audioHost == NULL) {
289         ADM_LOG_ERR("audioHost create failed!");
290         return HDF_FAILURE;
291     }
292 
293     ADM_LOG_INFO("success.");
294     return HDF_SUCCESS;
295 }
296 
AudioCardInit(struct HdfDeviceObject * device,struct AudioHost * audioHost)297 static int32_t AudioCardInit(struct HdfDeviceObject *device, struct AudioHost *audioHost)
298 {
299     int32_t ret;
300     struct AudioCard *audioCard = NULL;
301     if (device == NULL || audioHost == NULL) {
302         ADM_LOG_ERR("device or audioHost is NULL.");
303         return HDF_FAILURE;
304     }
305 
306     audioCard = (struct AudioCard *)OsalMemCalloc(sizeof(*audioCard));
307     if (audioCard == NULL) {
308         ADM_LOG_ERR("Malloc audioCard fail!");
309         return HDF_FAILURE;
310     }
311     audioHost->priv = audioCard;
312     /* Get node information through HCS file */
313     ret = AudioFillConfigData(device, &(audioCard->configData));
314     if (ret != HDF_SUCCESS) {
315         ADM_LOG_ERR("AudioFillConfigData fail ret=%d", ret);
316         return HDF_ERR_IO;
317     }
318 
319     audioCard->device = device;
320     audioCard->standbyMode = AUDIO_SAPM_TURN_STANDBY_LATER;
321 
322     /* Bind specific codec、platform and dai device */
323     ret = AudioBindDaiLink(audioCard, &(audioCard->configData));
324     if (ret != HDF_SUCCESS) {
325         ADM_LOG_ERR("AudioBindDaiLink fail ret=%d", ret);
326         return HDF_FAILURE;
327     }
328     if (audioCard->rtd == NULL || (!audioCard->rtd->complete)) {
329         ADM_LOG_ERR("AudioBindDaiLink fail!");
330         return HDF_ERR_IO;
331     }
332 
333     /* Initialize controls list */
334     DListHeadInit(&audioCard->controls);
335     DListHeadInit(&audioCard->components);
336     DListHeadInit(&audioCard->paths);
337     DListHeadInit(&audioCard->sapmDirty);
338     /* Initialize hardware device */
339     ret = AudioInitDaiLink(audioCard);
340     if (ret != HDF_SUCCESS) {
341         ADM_LOG_ERR("AudioInitDaiLink fail ret=%d", ret);
342         return HDF_ERR_IO;
343     }
344 
345     /* sound card added to list */
346     DListInsertHead(&audioCard->list, &cardManager);
347 
348     return HDF_SUCCESS;
349 }
350 
AudioDriverInit(struct HdfDeviceObject * device)351 static int32_t AudioDriverInit(struct HdfDeviceObject *device)
352 {
353     struct AudioHost *audioHost = NULL;
354 
355     ADM_LOG_DEBUG("entry.");
356     if (device == NULL) {
357         ADM_LOG_ERR("device is NULL.");
358         return HDF_ERR_INVALID_OBJECT;
359     }
360     if (!HdfDeviceSetClass(device, DEVICE_CLASS_AUDIO)) {
361         ADM_LOG_ERR("set audio class failed.");
362         return HDF_FAILURE;
363     }
364     audioHost = (struct AudioHost *)device->service;
365     if (AudioCardInit(device, audioHost) != HDF_SUCCESS) {
366         ADM_LOG_ERR("set audio class failed.");
367         return HDF_FAILURE;
368     }
369     ADM_LOG_INFO("success.");
370     return HDF_SUCCESS;
371 }
372 
AudioDriverRelease(struct HdfDeviceObject * device)373 static void AudioDriverRelease(struct HdfDeviceObject *device)
374 {
375     struct AudioHost *audioHost = NULL;
376     struct AudioCard *audioCard = NULL;
377     struct DListHead *componentHead = NULL;
378     struct DListHead *controlHead = NULL;
379     struct AudioSapmComponent *componentReq = NULL;
380     struct AudioSapmComponent *componentTmp = NULL;
381     struct AudioKcontrol *ctrlReq = NULL;
382     struct AudioKcontrol *ctrlTmp = NULL;
383 
384     ADM_LOG_DEBUG("entry.");
385     if (device == NULL) {
386         ADM_LOG_ERR("device is NULL.");
387         return;
388     }
389     audioHost = (struct AudioHost *)device->service;
390     if (audioHost == NULL) {
391         ADM_LOG_ERR("audioHost is NULL.");
392         return;
393     }
394 
395     if (audioHost->priv != NULL) {
396         audioCard = (struct AudioCard *)audioHost->priv;
397 
398         componentHead = &audioCard->components;
399         DLIST_FOR_EACH_ENTRY_SAFE(componentReq, componentTmp, componentHead, struct AudioSapmComponent, list) {
400             DListRemove(&componentReq->list);
401             if (componentReq->componentName != NULL) {
402                 OsalMemFree(componentReq->componentName);
403             }
404             OsalMemFree(componentReq);
405         }
406 
407         controlHead = &audioCard->controls;
408         DLIST_FOR_EACH_ENTRY_SAFE(ctrlReq, ctrlTmp, controlHead, struct AudioKcontrol, list) {
409             DListRemove(&ctrlReq->list);
410             if (ctrlReq->privateData != NULL) {
411                 OsalMemFree(ctrlReq->privateData);
412             }
413             OsalMemFree(ctrlReq);
414         }
415 
416         if (audioCard->rtd != NULL) {
417             OsalMemFree(audioCard->rtd);
418         }
419 
420         if (audioHost->priv != NULL) {
421             OsalMemFree(audioHost->priv);
422         }
423     }
424 
425     OsalMemFree(audioHost);
426     ADM_LOG_INFO("success.");
427 }
428 
429 /* HdfDriverEntry definitions */
430 struct HdfDriverEntry g_audioDriverEntry = {
431     .moduleVersion = 1,
432     .moduleName = "HDF_AUDIO",
433     .Bind = AudioDriverBind,
434     .Init = AudioDriverInit,
435     .Release = AudioDriverRelease,
436 };
437 HDF_INIT(g_audioDriverEntry);
438