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