• 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_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