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_control_dispatch.h"
10 #include "audio_control.h"
11 #include "audio_dai_if.h"
12 #include "audio_driver_log.h"
13 #include "devsvc_manager_clnt.h"
14 #include "hdf_device_object.h"
15 #include "osal_uaccess.h"
16 
17 #define HDF_LOG_TAG HDF_AUDIO_KADM
18 #define MAX_USER_SPACE_SIZE 0x4000
19 
AudioGetKctrlInstance(const struct AudioCtrlElemId * ctrlElemId)20 static struct AudioKcontrol *AudioGetKctrlInstance(const struct AudioCtrlElemId *ctrlElemId)
21 {
22     struct AudioKcontrol *kctrl = NULL;
23     struct AudioCard *audioCard = NULL;
24 
25     if (ctrlElemId == NULL || ctrlElemId->itemName == NULL || ctrlElemId->cardServiceName == NULL) {
26         ADM_LOG_ERR("input params check error: ctrlElemId is NULL.");
27         return NULL;
28     }
29 
30     audioCard = GetCardInstance(ctrlElemId->cardServiceName);
31     if (audioCard == NULL) {
32         ADM_LOG_ERR("get kcontrol instance fail!");
33         return NULL;
34     }
35 
36     DLIST_FOR_EACH_ENTRY(kctrl, &audioCard->controls, struct AudioKcontrol, list) {
37         if (kctrl->name == NULL) {
38             continue;
39         }
40         if (strcmp(kctrl->name, ctrlElemId->itemName) != 0) {
41             continue;
42         }
43         if (kctrl->iface != ctrlElemId->iface) {
44             continue;
45         }
46         return kctrl;
47     }
48     return NULL;
49 }
50 
FillElemInfoBuf(struct HdfSBuf * rspData,struct AudioCtrlElemInfo * eInfo)51 static int32_t FillElemInfoBuf(struct HdfSBuf *rspData, struct AudioCtrlElemInfo *eInfo)
52 {
53     if (!HdfSbufWriteInt32(rspData, eInfo->type)) {
54         ADM_LOG_ERR("Write response data type failed!");
55         return HDF_FAILURE;
56     }
57 
58     if (!HdfSbufWriteInt32(rspData, eInfo->max)) {
59         ADM_LOG_ERR("Write response data max failed!");
60         return HDF_FAILURE;
61     }
62 
63     if (!HdfSbufWriteInt32(rspData, eInfo->min)) {
64         ADM_LOG_ERR("Write response data min failed!");
65         return HDF_FAILURE;
66     }
67 
68     if (!HdfSbufWriteUint32(rspData, eInfo->count)) {
69         ADM_LOG_ERR("Write response data count failed!");
70         return HDF_FAILURE;
71     }
72 
73     return HDF_SUCCESS;
74 }
75 
ControlHostElemInfoSub(struct HdfSBuf * rspData,const struct AudioCtrlElemId id)76 static int32_t ControlHostElemInfoSub(struct HdfSBuf *rspData, const struct AudioCtrlElemId id)
77 {
78     int32_t result;
79     struct AudioCtrlElemInfo elemInfo;
80     struct AudioKcontrol *kctrl = NULL;
81 
82     if (rspData == NULL) {
83         ADM_LOG_ERR("Input rspData is null.");
84         return HDF_FAILURE;
85     }
86 
87     ADM_LOG_DEBUG("cardServiceName: %s, iface: %d, itemName: %s.",
88         id.cardServiceName, id.iface, id.itemName);
89     kctrl = AudioGetKctrlInstance(&id);
90     if (kctrl == NULL || kctrl->Info == NULL) {
91         ADM_LOG_ERR("itemname: %s iface: %d kctrl or Info not support!", id.itemName, id.iface);
92         return HDF_ERR_NOT_SUPPORT;
93     }
94 
95     (void)memset_s(&elemInfo, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
96     result = kctrl->Info(kctrl, &elemInfo);
97     if (result != HDF_SUCCESS) {
98         ADM_LOG_ERR("Get control info fail result=%d", result);
99         return HDF_FAILURE;
100     }
101 
102     result = FillElemInfoBuf(rspData, &elemInfo);
103     if (result != HDF_SUCCESS) {
104         return result;
105     }
106     ADM_LOG_DEBUG("success.");
107 
108     return HDF_SUCCESS;
109 }
110 
ControlHostElemInfo(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)111 static int32_t ControlHostElemInfo(const struct HdfDeviceIoClient *client,
112     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
113 {
114     ADM_LOG_DEBUG("entry.");
115     struct AudioCtrlElemId id;
116 
117     if (reqData == NULL) {
118         ADM_LOG_ERR("Input ElemInfo params check error: reqData is NULL.");
119         return HDF_FAILURE;
120     }
121     if (client == NULL) {
122         ADM_LOG_ERR("Input ElemInfo params check error: client is NULL.");
123         return HDF_FAILURE;
124     }
125 
126     (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId));
127     if (!HdfSbufReadInt32(reqData, &id.iface)) {
128         ADM_LOG_ERR("Read ElemInfo request id failed!");
129         return HDF_FAILURE;
130     }
131 
132     id.cardServiceName = HdfSbufReadString(reqData);
133     if (id.cardServiceName == NULL) {
134         ADM_LOG_ERR("Read ElemInfo request cardServiceName failed!");
135         return HDF_FAILURE;
136     }
137 
138     id.itemName = HdfSbufReadString(reqData);
139     if (id.itemName == NULL) {
140         ADM_LOG_ERR("Read ElemInfo request itemName failed!");
141         return HDF_FAILURE;
142     }
143 
144     return ControlHostElemInfoSub(rspData, id);
145 }
146 
ControlHostElemUnloadCard(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)147 static int32_t ControlHostElemUnloadCard(const struct HdfDeviceIoClient *client,
148     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
149 {
150     const char *driverName = NULL;
151     struct HdfDeviceObject *audioDriverService = NULL;
152     (void)client;
153     (void)rspData;
154 
155     if (reqData == NULL) {
156         ADM_LOG_ERR("reqData is null!");
157         return HDF_ERR_INVALID_PARAM;
158     }
159 
160     driverName = HdfSbufReadString(reqData);
161     if (driverName == NULL) {
162         ADM_LOG_ERR("read driver name is null!");
163         return HDF_FAILURE;
164     }
165 
166     audioDriverService = DevSvcManagerClntGetDeviceObject(driverName);
167     if (audioDriverService == NULL) {
168         ADM_LOG_ERR("get hdmi device fail! %s", driverName);
169         return HDF_FAILURE;
170     }
171 
172     HdfDeviceObjectRelease(audioDriverService);
173     return HDF_SUCCESS;
174 }
175 
WritePcmInfoToRspData(struct HdfSBuf * rspData,const struct AudioPcmStream * pcmInfo)176 static int32_t WritePcmInfoToRspData(struct HdfSBuf *rspData, const struct AudioPcmStream *pcmInfo)
177 {
178     if (rspData == NULL || pcmInfo == NULL) {
179         ADM_LOG_ERR("params rspData or pcmInfo is null.");
180         return HDF_FAILURE;
181     }
182 
183     if (pcmInfo->portDirection != PORT_IN && pcmInfo->portDirection != PORT_OUT) {
184         ADM_LOG_DEBUG("pcmInfo->portDirection nonsupport  PORT_IN or PORT_OUT");
185         return HDF_SUCCESS;
186     }
187 
188     if (!HdfSbufWriteUint8(rspData, (uint8_t)pcmInfo->portDirection)) {
189         ADM_LOG_ERR("Write response data portDirection=%llu failed!", pcmInfo->portDirection);
190         return HDF_FAILURE;
191     }
192 
193     return HDF_SUCCESS;
194 }
195 
WriteCardInfoToRspData(struct HdfSBuf * rspData,struct AudioCard * audioCard)196 static int32_t WriteCardInfoToRspData(struct HdfSBuf *rspData, struct AudioCard *audioCard)
197 {
198     struct AudioPortInfo *portInfo = NULL;
199 
200     if (rspData == NULL || audioCard == NULL) {
201         ADM_LOG_ERR("param is null!");
202         return HDF_ERR_INVALID_PARAM;
203     }
204 
205     if (audioCard->rtd == NULL || audioCard->rtd->codecDai == NULL ||
206         audioCard->rtd->codecDai->devData == NULL) {
207         ADM_LOG_ERR("audio card initialized error!");
208         return HDF_ERR_INVALID_PARAM;
209     }
210 
211     portInfo = &(audioCard->rtd->codecDai->devData->portInfo);
212     if (portInfo->render.portDirection != PORT_OUT && portInfo->capture.portDirection != PORT_IN) {
213         ADM_LOG_ERR("audio card not initialized! %s", audioCard->configData.cardServiceName);
214         return HDF_FAILURE;
215     }
216 
217     if (!HdfSbufWriteString(rspData, audioCard->configData.cardServiceName)) {
218         ADM_LOG_ERR("Write response data cardServiceName=%s failed!", audioCard->configData.cardServiceName);
219         return HDF_FAILURE;
220     }
221 
222     if (!HdfSbufWriteUint8(rspData, portInfo->render.portDirection | portInfo->capture.portDirection)) {
223         ADM_LOG_ERR("Write response data failed!");
224         return HDF_FAILURE;
225     }
226 
227     if (WritePcmInfoToRspData(rspData, &portInfo->render) != HDF_SUCCESS) {
228         return HDF_FAILURE;
229     }
230 
231     if (WritePcmInfoToRspData(rspData, &portInfo->capture) != HDF_SUCCESS) {
232         return HDF_FAILURE;
233     }
234 
235     return HDF_SUCCESS;
236 }
237 
ControlHostElemGetCard(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)238 static int32_t ControlHostElemGetCard(const struct HdfDeviceIoClient *client,
239     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
240 {
241     int32_t sndCardNum = 0;
242     struct AudioCard *audioCard = NULL;
243     const struct DListHead *cardManager = NULL;
244 
245     (void)client;
246     (void)reqData;
247 
248     if (rspData == NULL) {
249         ADM_LOG_ERR("params rspData is null.");
250         return HDF_FAILURE;
251     }
252 
253     ADM_LOG_DEBUG("entry.");
254 
255     cardManager = GetAllCardInstance();
256     if (cardManager == NULL) {
257         ADM_LOG_ERR("cardManager is NULL fail.");
258         return HDF_FAILURE;
259     }
260 
261     sndCardNum = DListGetCount(cardManager);
262     if (sndCardNum == 0) {
263         ADM_LOG_ERR("card count is zero fail.");
264         return HDF_FAILURE;
265     }
266 
267     if (!HdfSbufWriteInt32(rspData, sndCardNum)) {
268         ADM_LOG_ERR("Write response data cardCount=%d failed!", sndCardNum);
269         return HDF_FAILURE;
270     }
271 
272     DLIST_FOR_EACH_ENTRY(audioCard, cardManager, struct AudioCard, list) {
273         if (WriteCardInfoToRspData(rspData, audioCard) != HDF_SUCCESS) {
274             return HDF_FAILURE;
275         }
276     }
277 
278     return HDF_SUCCESS;
279 }
280 
ControlHostElemRead(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)281 static int32_t ControlHostElemRead(const struct HdfDeviceIoClient *client, struct HdfSBuf *reqData,
282     struct HdfSBuf *rspData)
283 {
284     int32_t result;
285     struct AudioCtrlElemId id;
286     struct AudioCtrlElemValue elemValue;
287     struct AudioKcontrol *kctrl = NULL;
288 
289     if (client == NULL || reqData == NULL || rspData == NULL) {
290         ADM_LOG_ERR("params client or reqData or rspData is null.");
291         return HDF_FAILURE;
292     }
293 
294     (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId));
295     if (!HdfSbufReadInt32(reqData, &id.iface)) {
296         ADM_LOG_ERR("ElemRead request id failed!");
297         return HDF_FAILURE;
298     }
299 
300     id.cardServiceName = HdfSbufReadString(reqData);
301     if (id.cardServiceName == NULL) {
302         ADM_LOG_ERR("ElemRead request cardServiceName failed!");
303         return HDF_FAILURE;
304     }
305 
306     id.itemName = HdfSbufReadString(reqData);
307     if (id.itemName == NULL) {
308         ADM_LOG_ERR("ElemRead request itemName failed!");
309         return HDF_FAILURE;
310     }
311     ADM_LOG_DEBUG("itemName: %s cardServiceName: %s iface: %d ", id.itemName, id.cardServiceName, id.iface);
312 
313     kctrl = AudioGetKctrlInstance(&id);
314     if (kctrl == NULL || kctrl->Get == NULL) {
315         ADM_LOG_ERR("itemname: %s iface: %d kctrl or Get not support!", id.itemName, id.iface);
316         return HDF_ERR_NOT_SUPPORT;
317     }
318 
319     (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue));
320     result = kctrl->Get(kctrl, &elemValue);
321     if (result != HDF_SUCCESS) {
322         ADM_LOG_ERR("Get elemValue fail result=%d", result);
323         return HDF_FAILURE;
324     }
325 
326     if (!HdfSbufWriteInt32(rspData, elemValue.value[0])) {
327         ADM_LOG_ERR("Write response data value[0]=%d failed!", elemValue.value[0]);
328         return HDF_FAILURE;
329     }
330     if (!HdfSbufWriteInt32(rspData, elemValue.value[1])) {
331         ADM_LOG_ERR("Write response data value[1]=%d failed!", elemValue.value[1]);
332         return HDF_FAILURE;
333     }
334     return HDF_SUCCESS;
335 }
336 
ControlHostElemWrite(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)337 static int32_t ControlHostElemWrite(const struct HdfDeviceIoClient *client,
338     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
339 {
340     int32_t result;
341     struct AudioCtrlElemValue elemValue;
342     struct AudioKcontrol *kctrl = NULL;
343 
344     (void)rspData;
345     if (client == NULL) {
346         ADM_LOG_ERR("Input params check error: client is NULL.");
347         return HDF_FAILURE;
348     }
349     if (reqData == NULL) {
350         ADM_LOG_ERR("Input params check error: reqData is NULL.");
351         return HDF_FAILURE;
352     }
353 
354     (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue));
355     if (!HdfSbufReadInt32(reqData, &elemValue.value[0])) {
356         ADM_LOG_ERR("Read request elemValue failed!");
357         return HDF_FAILURE;
358     }
359     elemValue.value[1] = elemValue.value[0];
360 
361     if (!HdfSbufReadInt32(reqData, &elemValue.id.iface)) {
362         ADM_LOG_ERR("Read request id failed!");
363         return HDF_FAILURE;
364     }
365 
366     elemValue.id.cardServiceName = HdfSbufReadString(reqData);
367     if (elemValue.id.cardServiceName == NULL) {
368         ADM_LOG_ERR("Read request cardServiceName failed!");
369         return HDF_FAILURE;
370     }
371 
372     if (!(elemValue.id.itemName = HdfSbufReadString(reqData))) {
373         ADM_LOG_ERR("Read request itemName failed!");
374         return HDF_FAILURE;
375     }
376 
377     ADM_LOG_DEBUG("itemName: %s, cardServiceName: %s, iface: %d, value: %d.",
378         elemValue.id.itemName, elemValue.id.cardServiceName, elemValue.id.iface, elemValue.value[0]);
379 
380     kctrl = AudioGetKctrlInstance(&elemValue.id);
381     if (kctrl == NULL || kctrl->Set == NULL) {
382         ADM_LOG_ERR("itemname: %s iface: %d kctrl or Set not support!", elemValue.id.itemName, elemValue.id.iface);
383         return HDF_ERR_NOT_SUPPORT;
384     }
385 
386     result = kctrl->Set(kctrl, &elemValue);
387     if (result != HDF_SUCCESS) {
388         ADM_LOG_ERR("Get control value fail result=%d", result);
389         return HDF_FAILURE;
390     }
391     return HDF_SUCCESS;
392 }
393 
CodecElemListReqDataDeserialization(struct HdfSBuf * reqData,struct AudioCtlElemList * list,uint64_t * listAddress)394 static int32_t CodecElemListReqDataDeserialization(struct HdfSBuf *reqData, struct AudioCtlElemList *list,
395     uint64_t *listAddress)
396 {
397     if (reqData == NULL || list == NULL) {
398         ADM_LOG_ERR("Input params is NULL.");
399         return HDF_FAILURE;
400     }
401     (void)memset_s(list, sizeof(struct AudioCtlElemList), 0, sizeof(struct AudioCtlElemList));
402 
403     list->cardServiceName = HdfSbufReadString(reqData);
404     if (list->cardServiceName == NULL) {
405         ADM_LOG_ERR("Read request cardServiceName failed!");
406         return HDF_FAILURE;
407     }
408 
409     if (!HdfSbufReadUint32(reqData, &list->space)) {
410         ADM_LOG_ERR("Read request space failed!");
411         return HDF_FAILURE;
412     }
413 
414     if (!HdfSbufReadUint64(reqData, listAddress)) {
415         ADM_LOG_ERR("Read request space failed!");
416         return HDF_FAILURE;
417     }
418 
419     if (list->space > MAX_USER_SPACE_SIZE) {
420         ADM_LOG_ERR("list->space(%d) > MAX_USER_SPACE_SIZE!", list->space);
421         return HDF_FAILURE;
422     }
423 
424     return HDF_SUCCESS;
425 }
426 
CodecSetCtlElemListReportInfo(struct AudioCtlElemList * ctlEleList,struct AudioCtlElemListReport * dst)427 static int32_t CodecSetCtlElemListReportInfo(struct AudioCtlElemList *ctlEleList, struct AudioCtlElemListReport *dst)
428 {
429     struct AudioCard *audioCard = NULL;
430     struct AudioKcontrol *kctrl = NULL;
431 
432     if (ctlEleList == NULL || dst == NULL) {
433         ADM_LOG_ERR("Input params is NULL.");
434         return HDF_FAILURE;
435     }
436 
437     audioCard = GetCardInstance(ctlEleList->cardServiceName);
438     if (audioCard == NULL) {
439         return HDF_FAILURE;
440     }
441 
442     DLIST_FOR_EACH_ENTRY(kctrl, &audioCard->controls, struct AudioKcontrol, list) {
443         if (kctrl->name == NULL) {
444             continue;
445         }
446         if (ctlEleList->count >= ctlEleList->space) {
447             ADM_LOG_ERR("The memory requested by user is too small. user space: %d list count: %d",
448                 ctlEleList->space, ctlEleList->count);
449             return HDF_FAILURE;
450         }
451         if (strncpy_s(dst->name, AUDIO_ELEMENT_NAME_LEN, kctrl->name, AUDIO_ELEMENT_NAME_LEN - 1)) {
452             ADM_LOG_ERR("strncpy_s fail!");
453             return HDF_FAILURE;
454         }
455         dst->iface = kctrl->iface;
456         dst++;
457         ctlEleList->count++;
458     }
459 
460     return HDF_SUCCESS;
461 }
462 
ControlElemListRspDataSerialize(struct HdfSBuf * rspData,struct AudioCtlElemList * ctlEleList)463 static int32_t ControlElemListRspDataSerialize(struct HdfSBuf *rspData, struct AudioCtlElemList *ctlEleList)
464 {
465     if (rspData == NULL || ctlEleList == NULL) {
466         ADM_LOG_ERR("Input params is NULL.");
467         return HDF_FAILURE;
468     }
469 
470     if (!HdfSbufWriteString(rspData, ctlEleList->cardServiceName)) {
471         ADM_LOG_ERR("Write response data cardServiceName=%s failed!", ctlEleList->cardServiceName);
472         return HDF_FAILURE;
473     }
474 
475     if (!HdfSbufWriteInt32(rspData, ctlEleList->count)) {
476         ADM_LOG_ERR("Write response data list.count=%d failed!", ctlEleList->count);
477         return HDF_FAILURE;
478     }
479 
480     if (!HdfSbufWriteInt32(rspData, ctlEleList->space)) {
481         ADM_LOG_ERR("Write response data list.space=%d failed!", ctlEleList->space);
482         return HDF_FAILURE;
483     }
484 
485     return HDF_SUCCESS;
486 }
487 
ControlHostElemList(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)488 static int32_t ControlHostElemList(const struct HdfDeviceIoClient *client,
489     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
490 {
491     int32_t ret;
492     struct AudioCtlElemList ctlEleList;
493     uint64_t listAddress = 0;
494     struct AudioCtlElemListReport *dst = NULL;
495 
496     if (client == NULL || reqData == NULL || rspData == NULL) {
497         ADM_LOG_ERR("Input params check error");
498         return HDF_FAILURE;
499     }
500 
501     if (CodecElemListReqDataDeserialization(reqData, &ctlEleList, &listAddress) != HDF_SUCCESS) {
502         return HDF_FAILURE;
503     }
504 
505     dst = (struct AudioCtlElemListReport *)OsalMemCalloc(ctlEleList.space * sizeof(struct AudioCtlElemListReport));
506     if (dst == NULL) {
507         ADM_LOG_ERR("Malloc dst fail!");
508         return HDF_ERR_MALLOC_FAIL;
509     }
510 
511     ctlEleList.count = 0;
512     ret = CodecSetCtlElemListReportInfo(&ctlEleList, dst);
513     if (ret != HDF_SUCCESS) {
514         ADM_LOG_ERR("CodecSetCtlElemListReportInfo fail!");
515         OsalMemFree(dst);
516         return HDF_FAILURE;
517     }
518 
519     ret = ControlElemListRspDataSerialize(rspData, &ctlEleList);
520     if (ret != HDF_SUCCESS) {
521         ADM_LOG_ERR("ControlElemListRspDataSerialize fail!");
522         OsalMemFree(dst);
523         return HDF_FAILURE;
524     }
525 
526     if (CopyToUser((char *)listAddress, (char *)(dst), ctlEleList.count * sizeof(struct AudioCtlElemListReport)) != 0) {
527         AUDIO_DRIVER_LOG_ERR("CopyToUser failed.");
528         OsalMemFree(dst);
529         return HDF_FAILURE;
530     }
531     OsalMemFree(dst);
532 
533     return HDF_SUCCESS;
534 }
535 
536 static struct ControlDispCmdHandleList g_controlDispCmdHandle[] = {
537     {AUDIODRV_CTRL_IOCTRL_ELEM_INFO, ControlHostElemInfo},
538     {AUDIODRV_CTRL_IOCTRL_ELEM_READ, ControlHostElemRead},
539     {AUDIODRV_CTRL_IOCTRL_ELEM_WRITE, ControlHostElemWrite},
540     {AUDIODRV_CTRL_IOCTRL_ELEM_LIST, ControlHostElemList},
541     {AUDIODRV_CTRL_IOCTRL_ELEM_HDMI, ControlHostElemUnloadCard},
542     {AUDIODRV_CTRL_IOCTRL_ELEM_CARD, ControlHostElemGetCard},
543 };
544 
ControlDispatch(struct HdfDeviceIoClient * client,int32_t cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)545 static int32_t ControlDispatch(struct HdfDeviceIoClient *client, int32_t cmdId,
546     struct HdfSBuf *data, struct HdfSBuf *reply)
547 {
548     uint32_t i;
549 
550     if (client == NULL) {
551         ADM_LOG_ERR("Input params check error: client is NULL.");
552         return HDF_FAILURE;
553     }
554     if (data == NULL) {
555         ADM_LOG_ERR("Input params check error: data is NULL.");
556         return HDF_FAILURE;
557     }
558 
559     if (cmdId >= AUDIODRV_CTRL_IOCTRL_ELEM_BUTT || cmdId < 0) {
560         ADM_LOG_ERR("Invalid [cmdId=%d].", cmdId);
561         return HDF_FAILURE;
562     }
563 
564     for (i = 0; i < HDF_ARRAY_SIZE(g_controlDispCmdHandle); ++i) {
565         if ((cmdId == (int32_t)(g_controlDispCmdHandle[i].cmd)) && (g_controlDispCmdHandle[i].func != NULL)) {
566             return g_controlDispCmdHandle[i].func(client, data, reply);
567         }
568     }
569     return HDF_FAILURE;
570 }
571 
ControlHostCreateAndBind(struct HdfDeviceObject * device)572 static struct ControlHost *ControlHostCreateAndBind(struct HdfDeviceObject *device)
573 {
574     struct ControlHost *controlHost = NULL;
575 
576     if (device == NULL) {
577         ADM_LOG_ERR("Input params check error: device is NULL.");
578         return NULL;
579     }
580 
581     controlHost = (struct ControlHost *)OsalMemCalloc(sizeof(*controlHost));
582     if (controlHost == NULL) {
583         ADM_LOG_ERR("Malloc controlHost fail!");
584         return NULL;
585     }
586     controlHost->device = device;
587     device->service = &controlHost->service;
588     return controlHost;
589 }
590 
AudioControlBind(struct HdfDeviceObject * device)591 static int32_t AudioControlBind(struct HdfDeviceObject *device)
592 {
593     struct ControlHost *controlHost = NULL;
594     ADM_LOG_DEBUG("entry.");
595 
596     if (device == NULL) {
597         ADM_LOG_ERR("Input params check error: device is NULL.");
598         return HDF_FAILURE;
599     }
600 
601     controlHost = ControlHostCreateAndBind(device);
602     if (controlHost == NULL) {
603         ADM_LOG_ERR("controlHost is NULL.");
604         return HDF_FAILURE;
605     }
606 
607     controlHost->service.Dispatch = ControlDispatch;
608 
609     ADM_LOG_INFO("success.");
610     return HDF_SUCCESS;
611 }
612 
AudioControlInit(struct HdfDeviceObject * device)613 static int32_t AudioControlInit(struct HdfDeviceObject *device)
614 {
615     (void)device;
616     ADM_LOG_INFO("success.");
617     return HDF_SUCCESS;
618 }
619 
AudioControlRelease(struct HdfDeviceObject * device)620 static void AudioControlRelease(struct HdfDeviceObject *device)
621 {
622     struct ControlHost *controlHost = NULL;
623 
624     if (device == NULL) {
625         ADM_LOG_ERR("Input params check error: device is NULL.");
626         return;
627     }
628 
629     controlHost = (struct ControlHost *)device->service;
630     if (controlHost == NULL) {
631         ADM_LOG_ERR("controlHost is NULL.");
632         return;
633     }
634     OsalMemFree(controlHost);
635 }
636 
637 /* HdfDriverEntry definitions */
638 struct HdfDriverEntry g_audioControlEntry = {
639     .moduleVersion = 1,
640     .moduleName = "HDF_AUDIO_CONTROL",
641     .Bind = AudioControlBind,
642     .Init = AudioControlInit,
643     .Release = AudioControlRelease,
644 };
645 HDF_INIT(g_audioControlEntry);
646