• 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_control_dispatch.h"
10 #include "audio_control.h"
11 #include "audio_driver_log.h"
12 
13 #define HDF_LOG_TAG audio_control_dispatch
14 
AudioGetKctrlInstance(const struct AudioCtrlElemId * ctrlElemId)15 static struct AudioKcontrol *AudioGetKctrlInstance(const struct AudioCtrlElemId *ctrlElemId)
16 {
17     struct AudioKcontrol *kctrl = NULL;
18     struct AudioCard *audioCard = NULL;
19 
20     if (ctrlElemId == NULL || ctrlElemId->itemName == NULL || ctrlElemId->cardServiceName == NULL) {
21         ADM_LOG_ERR("input params check error: ctrlElemId is NULL.");
22         return NULL;
23     }
24 
25     audioCard = GetCardInstance(ctrlElemId->cardServiceName);
26     if (audioCard == NULL) {
27         ADM_LOG_ERR("get kcontrol instance fail!");
28         return NULL;
29     }
30 
31     DLIST_FOR_EACH_ENTRY(kctrl, &audioCard->controls, struct AudioKcontrol, list) {
32         if (kctrl->name == NULL) {
33             continue;
34         }
35         if (strcmp(kctrl->name, ctrlElemId->itemName) != 0) {
36             continue;
37         }
38         if (kctrl->iface != ctrlElemId->iface) {
39             continue;
40         }
41         return kctrl;
42     }
43     return NULL;
44 }
45 
ControlHostElemInfoSub(struct HdfSBuf * rspData,const struct AudioCtrlElemId id)46 static int32_t ControlHostElemInfoSub(struct HdfSBuf *rspData, const struct AudioCtrlElemId id)
47 {
48     int32_t result;
49     struct AudioKcontrol *kctrl = NULL;
50     struct AudioCtrlElemInfo elemInfo;
51     if (rspData == NULL) {
52         ADM_LOG_ERR("Input rspData is null.");
53         return HDF_FAILURE;
54     }
55     kctrl = AudioGetKctrlInstance(&id);
56     if (kctrl == NULL || kctrl->Info == NULL) {
57         ADM_LOG_ERR("Find kctrl or Info fail!");
58         return HDF_FAILURE;
59     }
60 
61     (void)memset_s(&elemInfo, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
62     result = kctrl->Info(kctrl, &elemInfo);
63     if (result != HDF_SUCCESS) {
64         ADM_LOG_ERR("Get control info fail result=%d", result);
65         return HDF_FAILURE;
66     }
67 
68     if (!HdfSbufWriteInt32(rspData, elemInfo.type)) {
69         ADM_LOG_ERR("Write response data type failed!");
70         return HDF_FAILURE;
71     }
72     if (!HdfSbufWriteInt32(rspData, elemInfo.max)) {
73         ADM_LOG_ERR("Write response data max failed!");
74         return HDF_FAILURE;
75     }
76     if (!HdfSbufWriteInt32(rspData, elemInfo.min)) {
77         ADM_LOG_ERR("Write response data min failed!");
78         return HDF_FAILURE;
79     }
80     if (!HdfSbufWriteUint32(rspData, elemInfo.count)) {
81         ADM_LOG_ERR("Write response data count failed!");
82         return HDF_FAILURE;
83     }
84     ADM_LOG_DEBUG("success.");
85     return HDF_SUCCESS;
86 }
87 
ControlHostElemInfo(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)88 static int32_t ControlHostElemInfo(const struct HdfDeviceIoClient *client,
89     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
90 {
91     struct AudioCtrlElemId id;
92     ADM_LOG_DEBUG("entry.");
93 
94     if ((client == NULL) || (reqData == NULL)) {
95         ADM_LOG_ERR("Input ElemInfo params check error: client=%p, reqData=%p.", client, reqData);
96         return HDF_FAILURE;
97     }
98 
99     (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId));
100     if (!HdfSbufReadInt32(reqData, &id.iface)) {
101         ADM_LOG_ERR("Read ElemInfo request id failed!");
102         return HDF_FAILURE;
103     }
104 
105     if (!(id.cardServiceName = HdfSbufReadString(reqData))) {
106         ADM_LOG_ERR("Read ElemInfo request cardServiceName failed!");
107         return HDF_FAILURE;
108     }
109 
110     if (!(id.itemName = HdfSbufReadString(reqData))) {
111         ADM_LOG_ERR("Read ElemInfo request itemName failed!");
112         return HDF_FAILURE;
113     }
114 
115     if (ControlHostElemInfoSub(rspData, id)) {
116         ADM_LOG_ERR("ControlHostElemInfoSub failed!");
117         return HDF_FAILURE;
118     }
119 
120     return HDF_SUCCESS;
121 }
122 
ControlHostElemRead(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)123 static int32_t ControlHostElemRead(const struct HdfDeviceIoClient *client, struct HdfSBuf *reqData,
124     struct HdfSBuf *rspData)
125 {
126     struct AudioKcontrol *kctrl = NULL;
127     struct AudioCtrlElemValue elemValue;
128     struct AudioCtrlElemId id;
129     int32_t result;
130 
131     if ((client == NULL) || (reqData == NULL) || (rspData == NULL)) {
132         ADM_LOG_ERR("Input ElemRead params check error: client=%p, reqData=%p, rspData=%p.", client, reqData, rspData);
133         return HDF_FAILURE;
134     }
135 
136     (void)memset_s(&id, sizeof(struct AudioCtrlElemId), 0, sizeof(struct AudioCtrlElemId));
137     if (!HdfSbufReadInt32(reqData, &id.iface)) {
138         ADM_LOG_ERR("ElemRead request id failed!");
139         return HDF_FAILURE;
140     }
141 
142     if (!(id.cardServiceName = HdfSbufReadString(reqData))) {
143         ADM_LOG_ERR("ElemRead request cardServiceName failed!");
144         return HDF_FAILURE;
145     }
146 
147     if (!(id.itemName = HdfSbufReadString(reqData))) {
148         ADM_LOG_ERR("ElemRead request itemName failed!");
149         return HDF_FAILURE;
150     }
151     ADM_LOG_DEBUG("itemName: %s cardServiceName: %s iface: %d ", id.itemName, id.cardServiceName, id.iface);
152 
153     kctrl = AudioGetKctrlInstance(&id);
154     if (kctrl == NULL || kctrl->Get == NULL) {
155         ADM_LOG_ERR("Find kctrl or Get fail.");
156         return HDF_FAILURE;
157     }
158 
159     (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue));
160     result = kctrl->Get(kctrl, &elemValue);
161     if (result != HDF_SUCCESS) {
162         ADM_LOG_ERR("Get elemValue fail result=%d", result);
163         return HDF_FAILURE;
164     }
165 
166     if (!HdfSbufWriteInt32(rspData, elemValue.value[0])) {
167         ADM_LOG_ERR("Write response data value[0]=%d failed!", elemValue.value[0]);
168         return HDF_FAILURE;
169     }
170     if (!HdfSbufWriteInt32(rspData, elemValue.value[1])) {
171         ADM_LOG_ERR("Write response data value[1]=%d failed!", elemValue.value[1]);
172         return HDF_FAILURE;
173     }
174     return HDF_SUCCESS;
175 }
176 
ControlHostElemWrite(const struct HdfDeviceIoClient * client,struct HdfSBuf * reqData,struct HdfSBuf * rspData)177 static int32_t ControlHostElemWrite(const struct HdfDeviceIoClient *client,
178     struct HdfSBuf *reqData, struct HdfSBuf *rspData)
179 {
180     struct AudioKcontrol *kctrl = NULL;
181     struct AudioCtrlElemValue elemValue;
182     int32_t result;
183 
184     if ((client == NULL) || (reqData == NULL)) {
185         ADM_LOG_ERR("Input params check error: client=%p, reqData=%p.", client, reqData);
186         return HDF_FAILURE;
187     }
188     (void)rspData;
189 
190     (void)memset_s(&elemValue, sizeof(struct AudioCtrlElemValue), 0, sizeof(struct AudioCtrlElemValue));
191     if (!HdfSbufReadInt32(reqData, &elemValue.value[0])) {
192         ADM_LOG_ERR("Read request elemValue failed!");
193         return HDF_FAILURE;
194     }
195     elemValue.value[1] = elemValue.value[0];
196 
197     if (!HdfSbufReadInt32(reqData, &elemValue.id.iface)) {
198         ADM_LOG_ERR("Read request id failed!");
199         return HDF_FAILURE;
200     }
201 
202     if (!(elemValue.id.cardServiceName = HdfSbufReadString(reqData))) {
203         ADM_LOG_ERR("Read request cardServiceName failed!");
204         return HDF_FAILURE;
205     }
206 
207     if (!(elemValue.id.itemName = HdfSbufReadString(reqData))) {
208         ADM_LOG_ERR("Read request itemName failed!");
209         return HDF_FAILURE;
210     }
211 
212     ADM_LOG_DEBUG("itemName: %s cardServiceName: %s iface: %d value: %d ", elemValue.id.itemName,
213         elemValue.id.cardServiceName,
214         elemValue.id.iface, elemValue.value[0]);
215 
216     kctrl = AudioGetKctrlInstance(&elemValue.id);
217     if (kctrl == NULL || kctrl->Set == NULL) {
218         ADM_LOG_ERR("Find kctrl or Set fail!");
219         return HDF_FAILURE;
220     }
221 
222     result = kctrl->Set(kctrl, &elemValue);
223     if (result != HDF_SUCCESS) {
224         ADM_LOG_ERR("Get control value fail result=%d", result);
225         return HDF_FAILURE;
226     }
227     return HDF_SUCCESS;
228 }
229 
230 static struct ControlDispCmdHandleList g_controlDispCmdHandle[] = {
231     {AUDIODRV_CTRL_IOCTRL_ELEM_INFO, ControlHostElemInfo},
232     {AUDIODRV_CTRL_IOCTRL_ELEM_READ, ControlHostElemRead},
233     {AUDIODRV_CTRL_IOCTRL_ELEM_WRITE, ControlHostElemWrite},
234 };
235 
ControlDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)236 static int32_t ControlDispatch(struct HdfDeviceIoClient *client, int cmdId,
237     struct HdfSBuf *data, struct HdfSBuf *reply)
238 {
239     unsigned int i;
240 
241     if ((client == NULL) || (data == NULL)) {
242         ADM_LOG_ERR("Input params check error: client=%p, data=%p.", client, data);
243         return HDF_FAILURE;
244     }
245 
246     if (cmdId >= AUDIODRV_CTRL_IOCTRL_ELEM_BUTT || cmdId < 0) {
247         ADM_LOG_ERR("Invalid [cmdId=%d].", cmdId);
248         return HDF_FAILURE;
249     }
250 
251     for (i = 0; i < HDF_ARRAY_SIZE(g_controlDispCmdHandle); ++i) {
252         if ((cmdId == (int)(g_controlDispCmdHandle[i].cmd)) && (g_controlDispCmdHandle[i].func != NULL)) {
253             return g_controlDispCmdHandle[i].func(client, data, reply);
254         }
255     }
256     return HDF_FAILURE;
257 }
258 
ControlHostCreateAndBind(struct HdfDeviceObject * device)259 static struct ControlHost *ControlHostCreateAndBind(struct HdfDeviceObject *device)
260 {
261     struct ControlHost *controlHost = NULL;
262 
263     if (device == NULL) {
264         ADM_LOG_ERR("Input params check error: device is NULL.");
265         return NULL;
266     }
267 
268     controlHost = (struct ControlHost *)OsalMemCalloc(sizeof(*controlHost));
269     if (controlHost == NULL) {
270         ADM_LOG_ERR("Malloc controlHost fail!");
271         return NULL;
272     }
273     controlHost->device = device;
274     device->service = &controlHost->service;
275     return controlHost;
276 }
277 
AudioControlBind(struct HdfDeviceObject * device)278 static int32_t AudioControlBind(struct HdfDeviceObject *device)
279 {
280     struct ControlHost *controlHost = NULL;
281     ADM_LOG_DEBUG("entry.");
282 
283     if (device == NULL) {
284         ADM_LOG_ERR("Input params check error: device is NULL.");
285         return HDF_FAILURE;
286     }
287 
288     controlHost = ControlHostCreateAndBind(device);
289     if (controlHost == NULL) {
290         ADM_LOG_ERR("controlHost is NULL.");
291         return HDF_FAILURE;
292     }
293 
294     controlHost->service.Dispatch = ControlDispatch;
295 
296     ADM_LOG_INFO("success.");
297     return HDF_SUCCESS;
298 }
299 
AudioControlInit(struct HdfDeviceObject * device)300 static int32_t AudioControlInit(struct HdfDeviceObject *device)
301 {
302     (void)device;
303     ADM_LOG_INFO("success.");
304     return HDF_SUCCESS;
305 }
306 
AudioControlRelease(struct HdfDeviceObject * device)307 static void AudioControlRelease(struct HdfDeviceObject *device)
308 {
309     struct ControlHost *controlHost = NULL;
310 
311     if (device == NULL) {
312         ADM_LOG_ERR("Input params check error: device is NULL.");
313         return;
314     }
315 
316     controlHost = (struct ControlHost *)device->service;
317     if (controlHost == NULL) {
318         ADM_LOG_ERR("controlHost is NULL.");
319         return;
320     }
321     OsalMemFree(controlHost);
322 }
323 
324 /* HdfDriverEntry definitions */
325 struct HdfDriverEntry g_audioControlEntry = {
326     .moduleVersion = 1,
327     .moduleName = "HDF_AUDIO_CONTROL",
328     .Bind = AudioControlBind,
329     .Init = AudioControlInit,
330     .Release = AudioControlRelease,
331 };
332 HDF_INIT(g_audioControlEntry);
333