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_parse.h"
10 #include "audio_driver_log.h"
11
12 #define HDF_LOG_TAG audio_parse
13
14 enum AudioRegCfgIndex {
15 AUDIO_REG_CFG_REG_INDEX = 0,
16 AUDIO_REG_CFG_RREG_INDEX,
17 AUDIO_REG_CFG_SHIFT_INDEX,
18 AUDIO_REG_CFG_RSHIFT_INDEX,
19 AUDIO_REG_CFG_MIN_INDEX,
20 AUDIO_REG_CFG_MAX_INDEX,
21 AUDIO_REG_CFG_MASK_INDEX,
22 AUDIO_REG_CFG_INVERT_INDEX,
23 AUDIO_REG_CFG_VALUE_INDEX,
24 AUDIO_REG_CFG_INDEX_MAX
25 };
26
27 enum AudioAddrCfgIndex {
28 AUDIO_ADDR_CFG_REG_INDEX = 0,
29 AUDIO_ADDR_CFG_VALUE_INDEX,
30 AUDIO_ADDR_CFG_INDEX_MAX
31 };
32
33 enum AudioCrtlCfgIndex {
34 AUDIO_CTRL_CFG_INDEX_INDEX = 0,
35 AUDIO_CTRL_CFG_IFACE_INDEX,
36 AUDIO_CTRL_CFG_ENABLE_INDEX,
37 AUDIO_CTRL_CFG_INDEX_MAX
38 };
39
40 enum AudioSapmComponentIndex {
41 AUDIO_SAPM_COMP_INDEX_TYPE = 0,
42 AUDIO_SAPM_COMP_INDEX_NAME,
43 AUDIO_SAPM_COMP_INDEX_REG,
44 AUDIO_SAPM_COMP_INDEX_MASK,
45 AUDIO_SAPM_COMP_INDEX_SHIFT,
46 AUDIO_SAPM_COMP_INDEX_INVERT,
47 AUDIO_SAPM_COMP_INDEX_KCTL,
48 AUDIO_SAPM_COMP_INDEX_KCTLNUM,
49 AUDIO_SAPM_COMP_INDEX_MAX
50 };
51
52
53 static char *g_audioRegGroupName[AUDIO_GROUP_MAX] = {
54 "resetSeqConfig",
55 "initSeqConfig",
56 "ctrlParamsSeqConfig",
57 "ctrlSapmParamsSeqConfig",
58 "daiStartupSeqConfig",
59 "daiParamsSeqConfig",
60 "daiTriggerSeqConfig",
61 "controlsConfig",
62 "sapmComponent",
63 "sapmConfig"
64 };
65
AudioFillConfigData(const struct HdfDeviceObject * device,struct AudioConfigData * configData)66 int32_t AudioFillConfigData(const struct HdfDeviceObject *device, struct AudioConfigData *configData)
67 {
68 const struct DeviceResourceNode *node = NULL;
69 struct DeviceResourceIface *drsOps = NULL;
70 int32_t serviceRet;
71 int32_t codecRet;
72 int32_t platformRet;
73 int32_t cpuRet;
74 int32_t codeDaiRet;
75 int32_t dspRet;
76 int32_t dspDaiRet;
77 int32_t accessoryRet;
78 int32_t accessoryDaiRet;
79 ADM_LOG_DEBUG("Entry.");
80
81 if (device == NULL || configData == NULL) {
82 ADM_LOG_ERR("Input para check error: device=%p, configData=%p.", device, configData);
83 return HDF_FAILURE;
84 }
85
86 node = device->property;
87 if (node == NULL) {
88 ADM_LOG_ERR("drs node is NULL.");
89 return HDF_FAILURE;
90 }
91 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
92 if (drsOps == NULL || drsOps->GetString == NULL) {
93 ADM_LOG_ERR("AudioFillConfigData: invalid drs ops fail!");
94 return HDF_FAILURE;
95 }
96
97 serviceRet = drsOps->GetString(node, "serviceName", &(configData->cardServiceName), 0);
98 codecRet = drsOps->GetString(node, "codecName", &(configData->codecName), 0);
99 platformRet = drsOps->GetString(node, "platformName", &(configData->platformName), 0);
100 cpuRet = drsOps->GetString(node, "cpuDaiName", &(configData->cpuDaiName), 0);
101 codeDaiRet = drsOps->GetString(node, "codecDaiName", &(configData->codecDaiName), 0);
102 dspRet = drsOps->GetString(node, "dspName", &(configData->dspName), 0);
103 dspDaiRet = drsOps->GetString(node, "dspDaiName", &(configData->dspDaiName), 0);
104 accessoryRet = drsOps->GetString(node, "accessoryName", &(configData->accessoryName), 0);
105 accessoryDaiRet = drsOps->GetString(node, "accessoryDaiName", &(configData->accessoryDaiName), 0);
106 if (serviceRet || codecRet || platformRet || cpuRet || codeDaiRet ||
107 dspRet || dspDaiRet || accessoryRet || accessoryDaiRet) {
108 ADM_LOG_ERR("Read audioDeviceName fail: serviceRet=%d, codecRet=%d, platformRet=%d, cpuRet=%d, codeDaiRet=%d,"
109 "dspRet=%d, dspDaiRet=%d, accessoryRet=%d, accessoryDaiRet=%d",
110 serviceRet, codecRet, platformRet, cpuRet, codeDaiRet, dspRet,
111 dspDaiRet, accessoryRet, accessoryDaiRet);
112 return HDF_FAILURE;
113 }
114
115 ADM_LOG_DEBUG("Success! codecName = %s, platformName = %s, cpuDaiName = %s, codecDaiName = %s, "
116 "dspName = %s, dspDaiName = %s, accessoryName = %s, accessoryDaiName = %s.",
117 configData->codecName, configData->platformName, configData->cpuDaiName,
118 configData->codecDaiName, configData->dspName, configData->dspDaiName,
119 configData->accessoryName, configData->accessoryDaiName);
120
121 return HDF_SUCCESS;
122 }
123
GetAudioRegGroupNameIndex(const char * name)124 static uint32_t GetAudioRegGroupNameIndex(const char *name)
125 {
126 uint32_t index;
127
128 if (name == NULL) {
129 return AUDIO_GROUP_MAX;
130 }
131
132 for (index = 0; index < AUDIO_GROUP_MAX; ++index) {
133 if ((g_audioRegGroupName[index] != NULL) && (strcmp(name, g_audioRegGroupName[index]) == 0)) {
134 break;
135 }
136 }
137
138 return index;
139 }
140
GetRegArray(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * regNode,struct AudioRegCfgGroupNode * group,uint32_t indexMax)141 static uint32_t* GetRegArray(const struct DeviceResourceIface *parser, const struct DeviceResourceNode *regNode,
142 struct AudioRegCfgGroupNode* group, uint32_t indexMax)
143 {
144 int32_t ret;
145 int32_t index;
146 int32_t num;
147 uint32_t *buf;
148 if (group == NULL || parser == NULL || regNode == NULL || indexMax == 0) {
149 ADM_LOG_ERR("Input para check error");
150 return NULL;
151 }
152
153 index = group->groupIndex;
154 if (index >= AUDIO_GROUP_MAX) {
155 ADM_LOG_ERR("Input indexMax=%d error", index);
156 return NULL;
157 }
158
159 num = parser->GetElemNum(regNode, g_audioRegGroupName[index]);
160 if (num <= 0 || num > AUDIO_CONFIG_MAX_ITEM) {
161 ADM_LOG_ERR("parser %s element num failed", g_audioRegGroupName[index]);
162 return NULL;
163 }
164
165 group->itemNum = num / indexMax;
166
167 buf = (uint32_t *)OsalMemCalloc(sizeof(uint32_t) * num);
168 if (buf == NULL) {
169 ADM_LOG_ERR("malloc reg array buf failed!");
170 return NULL;
171 }
172
173 ret = parser->GetUint32Array(regNode, g_audioRegGroupName[index], buf, num, 0);
174 if (ret != HDF_SUCCESS) {
175 ADM_LOG_ERR("parser %s reg array failed", g_audioRegGroupName[index]);
176 OsalMemFree(buf);
177 return NULL;
178 }
179 return buf;
180 }
181
ParseAudioRegItem(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * regNode,struct AudioRegCfgGroupNode * group)182 static int32_t ParseAudioRegItem(const struct DeviceResourceIface *parser, const struct DeviceResourceNode *regNode,
183 struct AudioRegCfgGroupNode* group)
184 {
185 int32_t step;
186 int32_t index;
187 int32_t *buf;
188 if (group == NULL || parser == NULL || regNode == NULL) {
189 ADM_LOG_ERR("Input para check error");
190 return HDF_FAILURE;
191 }
192
193 buf = GetRegArray(parser, regNode, group, AUDIO_REG_CFG_INDEX_MAX);
194 if (buf == NULL) {
195 ADM_LOG_ERR("malloc reg array buf failed!");
196 return HDF_FAILURE;
197 }
198
199 group->regCfgItem =
200 (struct AudioMixerControl*)OsalMemCalloc(group->itemNum * sizeof(*(group->regCfgItem)));
201 if (group->regCfgItem == NULL) {
202 OsalMemFree(buf);
203 ADM_LOG_ERR("malloc audio reg config item failed!");
204 return HDF_ERR_MALLOC_FAIL;
205 }
206
207 for (index = 0; index < group->itemNum; ++index) {
208 step = AUDIO_REG_CFG_INDEX_MAX * index;
209
210 group->regCfgItem[index].reg = buf[step + AUDIO_REG_CFG_REG_INDEX];
211 group->regCfgItem[index].rreg = buf[step + AUDIO_REG_CFG_RREG_INDEX];
212 group->regCfgItem[index].shift = buf[step + AUDIO_REG_CFG_SHIFT_INDEX];
213 group->regCfgItem[index].rshift = buf[step + AUDIO_REG_CFG_RSHIFT_INDEX];
214 group->regCfgItem[index].min = buf[step + AUDIO_REG_CFG_MIN_INDEX];
215 group->regCfgItem[index].max = buf[step + AUDIO_REG_CFG_MAX_INDEX];
216 group->regCfgItem[index].mask = buf[step + AUDIO_REG_CFG_MASK_INDEX];
217 group->regCfgItem[index].invert = buf[step + AUDIO_REG_CFG_INVERT_INDEX];
218 group->regCfgItem[index].value = buf[step + AUDIO_REG_CFG_VALUE_INDEX];
219 }
220 OsalMemFree(buf);
221
222 return HDF_SUCCESS;
223 }
224
ParseAudioSapmItem(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * regNode,struct AudioRegCfgGroupNode * group)225 static int32_t ParseAudioSapmItem(const struct DeviceResourceIface *parser, const struct DeviceResourceNode *regNode,
226 struct AudioRegCfgGroupNode* group)
227 {
228 int32_t step;
229 int32_t index;
230 uint32_t *buf;
231 if (group == NULL || parser == NULL || regNode == NULL) {
232 ADM_LOG_ERR("Input para check error");
233 return HDF_FAILURE;
234 }
235
236 buf = GetRegArray(parser, regNode, group, AUDIO_SAPM_COMP_INDEX_MAX);
237 if (buf == NULL) {
238 ADM_LOG_ERR("malloc reg array buf failed!");
239 return HDF_FAILURE;
240 }
241
242 group->sapmCompItem =
243 (struct AudioSapmCtrlConfig*)OsalMemCalloc(group->itemNum * sizeof(*(group->sapmCompItem)));
244 if (group->sapmCompItem == NULL) {
245 OsalMemFree(buf);
246 ADM_LOG_ERR("malloc audio reg config item failed!");
247 return HDF_ERR_MALLOC_FAIL;
248 }
249
250 for (index = 0; index < group->itemNum; ++index) {
251 step = AUDIO_SAPM_COMP_INDEX_MAX * index;
252 group->sapmCompItem[index].sapmType = buf[step + AUDIO_SAPM_COMP_INDEX_TYPE];
253 group->sapmCompItem[index].compNameIndex = buf[step + AUDIO_SAPM_COMP_INDEX_NAME];
254 group->sapmCompItem[index].reg = buf[step + AUDIO_SAPM_COMP_INDEX_REG];
255 group->sapmCompItem[index].mask = buf[step + AUDIO_SAPM_COMP_INDEX_MASK];
256 group->sapmCompItem[index].shift = buf[step + AUDIO_SAPM_COMP_INDEX_SHIFT];
257 group->sapmCompItem[index].invert = buf[step + AUDIO_SAPM_COMP_INDEX_INVERT];
258 group->sapmCompItem[index].kcontrolNews = buf[step + AUDIO_SAPM_COMP_INDEX_KCTL];
259 group->sapmCompItem[index].kcontrolsNum = buf[step + AUDIO_SAPM_COMP_INDEX_KCTLNUM];
260 }
261
262 OsalMemFree(buf);
263 return HDF_SUCCESS;
264 }
265
266
ParseAudioCtrlItem(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * regNode,struct AudioRegCfgGroupNode * group)267 static int32_t ParseAudioCtrlItem(const struct DeviceResourceIface *parser, const struct DeviceResourceNode *regNode,
268 struct AudioRegCfgGroupNode* group)
269 {
270 int32_t step;
271 int32_t index;
272 uint32_t *buf;
273 if (parser == NULL || regNode == NULL || group == NULL) {
274 ADM_LOG_ERR("Input para check error");
275 return HDF_FAILURE;
276 }
277
278 buf = GetRegArray(parser, regNode, group, AUDIO_CTRL_CFG_INDEX_MAX);
279 if (buf == NULL) {
280 ADM_LOG_ERR("malloc reg array buf failed!");
281 return HDF_FAILURE;
282 }
283
284 group->ctrlCfgItem =
285 (struct AudioControlConfig*)OsalMemCalloc(group->itemNum * sizeof(*(group->ctrlCfgItem)));
286 if (group->ctrlCfgItem == NULL) {
287 OsalMemFree(buf);
288 ADM_LOG_ERR("malloc audio ctrl config item failed!");
289 return HDF_ERR_MALLOC_FAIL;
290 }
291
292 for (index = 0; index < group->itemNum; ++index) {
293 step = AUDIO_CTRL_CFG_INDEX_MAX * index;
294
295 group->ctrlCfgItem[index].arrayIndex = buf[step + AUDIO_CTRL_CFG_INDEX_INDEX];
296 group->ctrlCfgItem[index].iface = buf[step + AUDIO_CTRL_CFG_IFACE_INDEX];
297 group->ctrlCfgItem[index].enable = buf[step + AUDIO_CTRL_CFG_ENABLE_INDEX];
298 }
299 OsalMemFree(buf);
300 return HDF_SUCCESS;
301 }
302
ParseAudioAddrItem(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * regNode,struct AudioRegCfgGroupNode * group)303 static int32_t ParseAudioAddrItem(const struct DeviceResourceIface *parser, const struct DeviceResourceNode *regNode,
304 struct AudioRegCfgGroupNode* group)
305 {
306 int32_t step;
307 int32_t index;
308 uint32_t *buf;
309
310 if (parser == NULL || regNode == NULL || group == NULL) {
311 ADM_LOG_ERR("Input para check error.");
312 return HDF_FAILURE;
313 }
314
315 buf = GetRegArray(parser, regNode, group, AUDIO_ADDR_CFG_INDEX_MAX);
316 if (buf == NULL) {
317 ADM_LOG_ERR("malloc reg array buf failed!");
318 return HDF_FAILURE;
319 }
320
321 group->addrCfgItem = (struct AudioAddrConfig*)OsalMemCalloc(group->itemNum * sizeof(*(group->addrCfgItem)));
322 if (group->addrCfgItem == NULL) {
323 OsalMemFree(buf);
324 ADM_LOG_ERR("malloc audio addr config item failed!");
325 return HDF_ERR_MALLOC_FAIL;
326 }
327
328 for (index = 0; index < group->itemNum; ++index) {
329 step = AUDIO_ADDR_CFG_INDEX_MAX * index;
330 group->addrCfgItem[index].addr = buf[step + AUDIO_ADDR_CFG_REG_INDEX];
331 group->addrCfgItem[index].value = buf[step + AUDIO_ADDR_CFG_VALUE_INDEX];
332 }
333 OsalMemFree(buf);
334 return HDF_SUCCESS;
335 }
336
ParseAudioRegGroup(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * regCfgNode,struct AudioRegCfgGroupNode ** groupNode,uint32_t index)337 static int32_t ParseAudioRegGroup(const struct DeviceResourceIface *parser,
338 const struct DeviceResourceNode *regCfgNode, struct AudioRegCfgGroupNode **groupNode, uint32_t index)
339 {
340 int32_t ret = HDF_FAILURE;
341 struct AudioRegCfgGroupNode *group = NULL;
342
343 if (parser == NULL || regCfgNode == NULL || groupNode == NULL) {
344 ADM_LOG_ERR("Input para check error: parser=%p, regCfgNode=%p, groupNode=%p.",
345 parser, regCfgNode, groupNode);
346 return HDF_FAILURE;
347 }
348
349 group = (struct AudioRegCfgGroupNode*)OsalMemCalloc(sizeof(*group));
350 if (group == NULL) {
351 ADM_LOG_ERR("malloc audio reg config group failed");
352 return HDF_ERR_MALLOC_FAIL;
353 }
354 *groupNode = group;
355 (*groupNode)->groupIndex = index;
356
357 switch (index) {
358 case AUDIO_CTRL_CFG_GROUP:
359 case AUDIO_SAPM_CFG_GROUP:
360 ret = ParseAudioCtrlItem(parser, regCfgNode, group);
361 break;
362 case AUDIO_RSET_GROUP:
363 case AUDIO_INIT_GROUP:
364 ret = ParseAudioAddrItem(parser, regCfgNode, group);
365 break;
366 case AUDIO_DAI_PATAM_GROUP:
367 case AUDIO_DAI_TRIGGER_GROUP:
368 case AUDIO_CTRL_PATAM_GROUP:
369 case AUDIO_CTRL_SAPM_PATAM_GROUP:
370 case AUDIO_DAI_STARTUP_PATAM_GROUP:
371 ret = ParseAudioRegItem(parser, regCfgNode, group);
372 break;
373 case AUDIO_SAPM_COMP_GROUP:
374 ret = ParseAudioSapmItem(parser, regCfgNode, group);
375 break;
376 default:
377 ADM_LOG_ERR("parse audio config index = %d not found!", index);
378 return HDF_FAILURE;
379 }
380
381 if (ret != HDF_SUCCESS) {
382 ADM_LOG_ERR("parse audio config item failed!");
383 return HDF_FAILURE;
384 }
385 return HDF_SUCCESS;
386 }
387
ReleaseAudioAllRegConfig(struct AudioRegCfgData * config)388 static void ReleaseAudioAllRegConfig(struct AudioRegCfgData *config)
389 {
390 int32_t index;
391
392 if (config == NULL) {
393 return;
394 }
395
396 for (index = 0; index < AUDIO_GROUP_MAX; ++index) {
397 if (config->audioRegParams[index] != NULL) {
398 if (config->audioRegParams[index]->regCfgItem != NULL) {
399 OsalMemFree(config->audioRegParams[index]->regCfgItem);
400 config->audioRegParams[index]->regCfgItem = NULL;
401 }
402 OsalMemFree(config->audioRegParams[index]);
403 config->audioRegParams[index] = NULL;
404 }
405 }
406 }
407
ParseAudioAttr(const struct DeviceResourceIface * parser,const struct DeviceResourceNode * attrNode,struct AudioIdInfo * config)408 static int32_t ParseAudioAttr(const struct DeviceResourceIface *parser, const struct DeviceResourceNode *attrNode,
409 struct AudioIdInfo *config)
410 {
411 int32_t ret;
412 ret = parser->GetString(attrNode, "chipName", &config->chipName, NULL);
413 if (ret != HDF_SUCCESS) {
414 ADM_LOG_ERR("parser chipName reg audioIdInfo failed!");
415 return HDF_SUCCESS;
416 }
417
418 ret = parser->GetUint32(attrNode, "chipIdRegister", &config->chipIdRegister, 0);
419 if (ret != HDF_SUCCESS) {
420 ADM_LOG_ERR("parser chipIdRegister reg audioIdInfo failed!");
421 return HDF_SUCCESS;
422 }
423
424 ret = parser->GetUint32(attrNode, "chipIdSize", &config->chipIdSize, 0);
425 if (ret != HDF_SUCCESS) {
426 ADM_LOG_ERR("parser chipIdSize reg audioIdInfo failed!");
427 return HDF_SUCCESS;
428 }
429 return ret;
430 }
431
CodecGetRegConfig(const struct HdfDeviceObject * device,struct AudioRegCfgData * configData)432 int32_t CodecGetRegConfig(const struct HdfDeviceObject *device, struct AudioRegCfgData *configData)
433 {
434 uint16_t index;
435 const struct DeviceResourceNode *root = NULL;
436 const struct DeviceResourceNode *regCfgNode = NULL;
437 const struct DeviceResourceAttr *regAttr = NULL;
438 const struct DeviceResourceNode *idNode = NULL;
439 struct DeviceResourceIface *drsOps = NULL;
440
441 ADM_LOG_DEBUG("Entry.");
442
443 if (device == NULL || configData == NULL) {
444 ADM_LOG_ERR("Input para check error: device=%p, configData=%p.", device, configData);
445 return HDF_FAILURE;
446 }
447
448 root = device->property;
449 if (root == NULL) {
450 ADM_LOG_ERR("drs node is NULL.");
451 return HDF_FAILURE;
452 }
453
454 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
455 if (drsOps == NULL || drsOps->GetString == NULL) {
456 ADM_LOG_ERR("AudioFillConfigData: invalid drs ops fail!");
457 return HDF_FAILURE;
458 }
459
460 idNode = drsOps->GetChildNode(root, "idInfo");
461 if (idNode != NULL) {
462 if (ParseAudioAttr(drsOps, idNode, &configData->audioIdInfo) != HDF_SUCCESS) {
463 ADM_LOG_ERR("audio reg node attr is null");
464 return HDF_FAILURE;
465 }
466 }
467
468 regCfgNode = drsOps->GetChildNode(root, "regConfig");
469 if (regCfgNode == NULL) {
470 ADM_LOG_ERR("CodecGetRegConfig: Read audioRegConfig fail!");
471 return HDF_FAILURE;
472 }
473
474 DEV_RES_NODE_FOR_EACH_ATTR(regCfgNode, regAttr) {
475 if (regAttr == NULL || regAttr->name == NULL) {
476 ADM_LOG_ERR("audio reg node attr is null");
477 return HDF_FAILURE;
478 }
479
480 index = GetAudioRegGroupNameIndex(regAttr->name);
481 if (index >= AUDIO_GROUP_MAX) {
482 continue;
483 }
484
485 if (ParseAudioRegGroup(drsOps, regCfgNode, &configData->audioRegParams[index], index) != HDF_SUCCESS) {
486 ADM_LOG_ERR("parse audio register group failed");
487 ReleaseAudioAllRegConfig(configData);
488 return HDF_FAILURE;
489 }
490 }
491 return HDF_SUCCESS;
492 }
493