• 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_codec_base.h"
10 #include "audio_driver_log.h"
11 #include "audio_parse.h"
12 #include "audio_sapm.h"
13 
14 #define HDF_LOG_TAG audio_codec_base
15 
16 static char *g_audioSapmCompNameList[AUDIO_SAPM_COMP_NAME_LIST_MAX] = {
17     "ADCL", "ADCR", "DACL", "DACR", "LPGA", "RPGA", "SPKL", "SPKR", "MIC"
18 };
19 
20 static char *g_audioSapmCfgNameList[AUDIO_SAPM_CFG_NAME_LIST_MAX] = {
21     "LPGA MIC Switch", "RPGA MIC Switch", "Dacl enable", "Dacr enable"
22 };
23 
24 static const char *g_audioCodecControlsList[AUDIO_CTRL_LIST_MAX] = {
25     "Main Playback Volume", "Main Capture Volume",
26     "Playback Mute", "Capture Mute", "Mic Left Gain",
27     "Mic Right Gain", "External Codec Enable",
28     "Internally Codec Enable", "Render Channel Mode", "Captrue Channel Mode"
29 };
30 
CodecGetServiceName(const struct HdfDeviceObject * device,const char ** drvCodecName)31 int32_t CodecGetServiceName(const struct HdfDeviceObject *device, const char **drvCodecName)
32 {
33     const struct DeviceResourceNode *node = NULL;
34     struct DeviceResourceIface *drsOps = NULL;
35     int32_t ret;
36 
37     if (device == NULL) {
38         AUDIO_DRIVER_LOG_ERR("input device para is nullptr.");
39         return HDF_FAILURE;
40     }
41 
42     node = device->property;
43     if (node == NULL) {
44         AUDIO_DRIVER_LOG_ERR("node instance is nullptr.");
45         return HDF_FAILURE;
46     }
47     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
48     if (drsOps == NULL || drsOps->GetString == NULL) {
49         AUDIO_DRIVER_LOG_ERR("from resouce get drsOps fail!");
50         return HDF_FAILURE;
51     }
52 
53     ret = drsOps->GetString(node, "serviceName", drvCodecName, 0);
54     if (ret != HDF_SUCCESS) {
55         AUDIO_DRIVER_LOG_ERR("read codecServiceName fail!");
56         return ret;
57     }
58 
59     return HDF_SUCCESS;
60 }
61 
CodecGetDaiName(const struct HdfDeviceObject * device,const char ** drvDaiName)62 int32_t CodecGetDaiName(const struct HdfDeviceObject *device, const char **drvDaiName)
63 {
64     const struct DeviceResourceNode *node = NULL;
65     struct DeviceResourceIface *drsOps = NULL;
66     int32_t ret;
67 
68     if (device == NULL) {
69         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
70         return HDF_FAILURE;
71     }
72 
73     node = device->property;
74     if (node == NULL) {
75         AUDIO_DRIVER_LOG_ERR("drs node is NULL.");
76         return HDF_FAILURE;
77     }
78     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
79     if (drsOps == NULL || drsOps->GetString == NULL) {
80         AUDIO_DRIVER_LOG_ERR("drs ops failed!");
81         return HDF_FAILURE;
82     }
83 
84     ret = drsOps->GetString(node, "codecDaiName", drvDaiName, 0);
85     if (ret != HDF_SUCCESS) {
86         AUDIO_DRIVER_LOG_ERR("read codecDaiName fail!");
87         return ret;
88     }
89 
90     return HDF_SUCCESS;
91 }
92 
CodecGetConfigInfo(const struct HdfDeviceObject * device,struct CodecData * codecData)93 int32_t CodecGetConfigInfo(const struct HdfDeviceObject *device, struct CodecData *codecData)
94 {
95     if (device == NULL || codecData == NULL) {
96         AUDIO_DRIVER_LOG_ERR("param is null!");
97         return HDF_FAILURE;
98     }
99 
100     if (codecData->regConfig != NULL) {
101         ADM_LOG_ERR("g_codecData regConfig  fail!");
102         return HDF_FAILURE;
103     }
104 
105     codecData->regConfig = (struct AudioRegCfgData *)OsalMemCalloc(sizeof(*(codecData->regConfig)));
106     if (codecData->regConfig == NULL) {
107         ADM_LOG_ERR("malloc AudioRegCfgData fail!");
108         return HDF_FAILURE;
109     }
110 
111     if (CodecGetRegConfig(device, codecData->regConfig) != HDF_SUCCESS) {
112         ADM_LOG_ERR("CodecGetRegConfig fail!");
113         return HDF_FAILURE;
114     }
115 
116     return HDF_SUCCESS;
117 }
118 
SapmCtrlToSapmComp(struct AudioSapmComponent * sapmComponents,const struct AudioSapmCtrlConfig * sapmCompItem,uint16_t index)119 static int32_t SapmCtrlToSapmComp(struct AudioSapmComponent *sapmComponents,
120     const struct AudioSapmCtrlConfig *sapmCompItem, uint16_t index)
121 {
122     if (sapmComponents == NULL || sapmCompItem == NULL) {
123         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
124         return HDF_FAILURE;
125     }
126 
127     sapmComponents[index].componentName =
128         g_audioSapmCompNameList[sapmCompItem[index].compNameIndex];
129     sapmComponents[index].reg      = sapmCompItem[index].reg;
130     sapmComponents[index].sapmType = sapmCompItem[index].sapmType;
131     sapmComponents[index].mask     = sapmCompItem[index].mask;
132     sapmComponents[index].shift    = sapmCompItem[index].shift;
133     sapmComponents[index].invert   = sapmCompItem[index].invert;
134     sapmComponents[index].kcontrolsNum = sapmCompItem[index].kcontrolsNum;
135 
136     return HDF_SUCCESS;
137 }
138 
CodecSetSapmConfigInfo(struct CodecData * codeData,struct AudioRegCfgGroupNode ** regCfgGroup)139 static int32_t CodecSetSapmConfigInfo(struct CodecData *codeData, struct AudioRegCfgGroupNode **regCfgGroup)
140 {
141     uint16_t index;
142     struct AudioSapmCtrlConfig *sapmCompItem;
143     struct AudioControlConfig  *sapmCtrlItem;
144     struct AudioMixerControl   *ctlSapmRegCfgItem;
145     struct AudioKcontrol *audioSapmControls;
146     if (codeData == NULL || regCfgGroup == NULL) {
147         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
148         return HDF_FAILURE;
149     }
150 
151     sapmCompItem = regCfgGroup[AUDIO_SAPM_COMP_GROUP]->sapmCompItem;
152     sapmCtrlItem = regCfgGroup[AUDIO_SAPM_CFG_GROUP]->ctrlCfgItem;
153     ctlSapmRegCfgItem = regCfgGroup[AUDIO_CTRL_SAPM_PATAM_GROUP]->regCfgItem;
154 
155     if (sapmCompItem == NULL || sapmCtrlItem == NULL || ctlSapmRegCfgItem == NULL) {
156         AUDIO_DRIVER_LOG_ERR("sapmCompItem, sapmCtrlItem, ctlSapmRegCfgItem is NULL.");
157         return HDF_FAILURE;
158     }
159 
160     audioSapmControls = (struct AudioKcontrol *)OsalMemCalloc(
161         regCfgGroup[AUDIO_SAPM_CFG_GROUP]->itemNum * sizeof(struct AudioKcontrol));
162     if (audioSapmControls == NULL) {
163         AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
164         return HDF_FAILURE;
165     }
166     for (index = 0; index < regCfgGroup[AUDIO_SAPM_CFG_GROUP]->itemNum; index++) {
167         audioSapmControls[index].iface = sapmCtrlItem[index].iface;
168         audioSapmControls[index].name = g_audioSapmCfgNameList[sapmCtrlItem[index].arrayIndex];
169         audioSapmControls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlSapmRegCfgItem[index]);
170         audioSapmControls[index].Info = AudioInfoCtrlOps;
171         audioSapmControls[index].Get  = AudioCodecSapmGetCtrlOps;
172         audioSapmControls[index].Set  = AudioCodecSapmSetCtrlOps;
173     }
174 
175     codeData->numSapmComponent = regCfgGroup[AUDIO_SAPM_COMP_GROUP]->itemNum;
176     codeData->sapmComponents = (struct AudioSapmComponent *)
177         OsalMemCalloc(codeData->numSapmComponent * sizeof(struct AudioSapmComponent));
178     if (codeData->sapmComponents == NULL) {
179         OsalMemFree(audioSapmControls);
180         AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
181         return HDF_FAILURE;
182     }
183 
184     for (index = 0; index < codeData->numSapmComponent; index++) {
185         if (SapmCtrlToSapmComp(codeData->sapmComponents, sapmCompItem, index)) {
186             OsalMemFree(audioSapmControls);
187             return HDF_FAILURE;
188         }
189 
190         if (sapmCompItem[index].kcontrolsNum) {
191             codeData->sapmComponents[index].kcontrolNews =
192                 &audioSapmControls[sapmCompItem[index].kcontrolNews - 1];
193         }
194     }
195 
196     return HDF_SUCCESS;
197 }
198 
CodecSetConfigInfo(struct CodecData * codeData,struct DaiData * daiData)199 int32_t CodecSetConfigInfo(struct CodecData *codeData,  struct DaiData *daiData)
200 {
201     uint16_t index;
202     struct AudioIdInfo   *audioIdInfo;
203     struct AudioRegCfgGroupNode **regCfgGroup;
204     struct AudioControlConfig  *compItem;
205     struct AudioMixerControl   *ctlRegCfgItem;
206     if (codeData == NULL || daiData == NULL || codeData->regConfig == NULL) {
207         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
208         return HDF_FAILURE;
209     }
210 
211     audioIdInfo = &(codeData->regConfig->audioIdInfo);
212     regCfgGroup = codeData->regConfig->audioRegParams;
213     daiData->regCfgGroup = regCfgGroup;
214     codeData->regCfgGroup = regCfgGroup;
215     if (audioIdInfo == NULL || regCfgGroup == NULL) {
216         AUDIO_DRIVER_LOG_ERR("audioIdInfo or regCfgGroup is NULL.");
217         return HDF_FAILURE;
218     }
219 
220     compItem = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
221     ctlRegCfgItem = regCfgGroup[AUDIO_CTRL_PATAM_GROUP]->regCfgItem;
222     if (compItem == NULL || ctlRegCfgItem == NULL) {
223         AUDIO_DRIVER_LOG_ERR("compItem or ctlRegCfgItem is NULL.");
224         return HDF_FAILURE;
225     }
226 
227     codeData->numControls = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->itemNum;
228     codeData->controls =
229         (struct AudioKcontrol *)OsalMemCalloc(codeData->numControls * sizeof(struct AudioKcontrol));
230     if (codeData->controls == NULL) {
231         AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
232         return HDF_FAILURE;
233     }
234 
235     for (index = 0; index < codeData->numControls; index++) {
236         codeData->controls[index].iface   = compItem[index].iface;
237         codeData->controls[index].name    = g_audioCodecControlsList[compItem[index].arrayIndex];
238         codeData->controls[index].Info    = AudioInfoCtrlOps;
239         codeData->controls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlRegCfgItem[index]);
240         if (compItem[index].enable) {
241             codeData->controls[index].Get = AudioCodecGetCtrlOps;
242             codeData->controls[index].Set = AudioCodecSetCtrlOps;
243         }
244     }
245 
246     codeData->virtualAddress = (uintptr_t)OsalIoRemap(audioIdInfo->chipIdRegister, audioIdInfo->chipIdSize);
247 
248     if (CodecSetSapmConfigInfo(codeData, regCfgGroup) != HDF_SUCCESS) {
249         return HDF_FAILURE;
250     }
251 
252     return HDF_SUCCESS;
253 }
254 
CodecSetCtlFunc(struct CodecData * codeData,const void * aiaoGetCtrl,const void * aiaoSetCtrl)255 int32_t CodecSetCtlFunc(struct CodecData *codeData, const void *aiaoGetCtrl, const void *aiaoSetCtrl)
256 {
257     uint32_t index;
258     struct AudioRegCfgGroupNode **regCfgGroup;
259     struct AudioControlConfig *compItem;
260     if (codeData == NULL || codeData->regConfig == NULL ||
261         aiaoGetCtrl == NULL || aiaoSetCtrl == NULL) {
262         AUDIO_DRIVER_LOG_ERR("input para is NULL.");
263         return HDF_FAILURE;
264     }
265     regCfgGroup = codeData->regConfig->audioRegParams;
266     if (regCfgGroup == NULL || regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL) {
267         AUDIO_DRIVER_LOG_ERR("regCfgGroup or regCfgGroup[AUDIO_CTRL_CFG_GROUP] is NULL.");
268         return HDF_FAILURE;
269     }
270 
271     compItem = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
272     if (compItem == NULL) {
273         AUDIO_DRIVER_LOG_ERR("compItem is NULL.");
274         return HDF_FAILURE;
275     }
276 
277     for (index = 0; index < codeData->numControls; index++) {
278         if (!compItem[index].enable) {
279             codeData->controls[index].Get = aiaoGetCtrl;
280             codeData->controls[index].Set = aiaoSetCtrl;
281         }
282     }
283 
284     return HDF_SUCCESS;
285 }
286