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