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