1 /*
2 * Copyright (c) 2021-2023 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 "i2c_if.h"
11 #include "audio_driver_log.h"
12 #include "audio_parse.h"
13 #include "audio_sapm.h"
14 #include "osal_time.h"
15
16 #define HDF_LOG_TAG HDF_AUDIO_KADM
17
18 #define COMM_SHIFT_8BIT (8)
19 #define COMM_MASK_FF (0xFF)
20 #define COMM_WAIT_TIMES (10) // ms
21
22 #define I2C_REG_LEN (1)
23 #define I2C_REG_MSGLEN (3)
24 #define I2C_MSG_NUM (2)
25 #define I2C_MSG_BUF_SIZE_1_BUTE (1)
26 #define I2C_MSG_BUF_SIZE_2_BUTE (2)
27
28 static char *g_audioSapmCompNameList[AUDIO_SAPM_COMP_NAME_LIST_MAX] = {
29 "ADCL", "ADCR", "DACL", "DACR", // [0], [1] [2], [3]
30 "LPGA", "RPGA", "SPKL", "SPKR", // [4], [5] [6], [7]
31 "MIC", "LOUT", "HPL", "HPR", // [8], [9] [10], [11]
32 "Stereo Mixer", "Line Mix", "Input Mixer", "Speaker Mix", // [12], [13] [14], [15]
33 "Input Mux", "AuxOut Mux", "SPKL Mux", "SPKR Mux", // [16], [17] [18], [19]
34 "AUXOUTL", "AUXOUTR", "LINEINL", "LINEINR", // [20], [21] [22], [23]
35 "AUXINL", "AUXINR", "I2S Mix", "AuxI Mix", // [24], [25] [26], [27]
36 "CaptureL Mix", "CaptureR Mix", "Mono1 Mixer", "Mono2 Mixer", // [28], [29] [30], [31]
37 "DAC1", "DAC2", "DAC3", "DAC4", // [32], [33] [34], [35]
38 "ADC1", "ADC2", "ADC3", "ADC4", // [36], [37] [38], [39]
39 "MIC1", "MIC2", "MIC3", "MIC4", // [40], [41],[42], [43],
40 "SPK1", "SPK2", "SPK3", "SPK4", // [44], [45],[46], [47],
41 "DAC Mix", "DAC Mux", "ADC Mix", "ADC Mux", // [48], [49],[50], [51],
42 "SPKL PGA", "SPKR PGA", "HPL PGA", "HPR PGA", // [52], [53],[54], [55],
43 };
44
45 static char *g_audioSapmCfgNameList[AUDIO_SAPM_CFG_NAME_LIST_MAX] = {
46 "LPGA MIC Switch", "RPGA MIC Switch", // [0], [1]
47 "Dacl enable", "Dacr enable", // [2], [3]
48 "Headphone Playback Switch", "PCM Playback Switch", // [4], [5]
49 "PCM Capture Switch", "Mono Playback Switch", // [6], [7]
50 "Phone Capture Switch", "Mic Switch", // [8], [9]
51 "Stereo Mic Switch", "Line HP Swap Switch", // [10], [11]
52 "Surround Playback Switch", "Center/LFE Playback Switch", // [12], [13]
53 "Capture Source", "Mic Boost Switch", // [14], [15]
54 "DAC1 Switch", "DAC2 Switch", // [16], [17]
55 "DAC3 Switch", "DAC4 Switch", // [18], [19]
56 "ADC1 Switch", "ADC2 Switch", // [20], [21]
57 "ADC3 Switch", "ADC4 Switch", // [22], [23]
58 "Speaker1 Switch", "Speaker2 Switch", // [24], [25]
59 "Speaker3 Switch", "Speaker4 Switch", // [26], [27]
60 "Headphone1 Switch", "Headphone2 Switch", // [28], [29]
61 "Lineout1 Switch", "Lineout2 Switch", // [30], [31]
62 "Lineout3 Switch", "Lineout4 Switch", // [32], [33]
63 "Mixer1 Switch", "Mixer2 Switch", // [34], [35]
64 "Mixer3 Switch", "Mixer4 Switch", // [36], [37]
65 };
66
67 static const char *g_audioCodecControlsList[AUDIO_CTRL_LIST_MAX] = {
68 "Main Playback Volume", "Main Capture Volume", // [0], [1]
69 "Playback Mute", "Capture Mute", // [2], [3]
70 "Mic Left Gain", "Mic Right Gain", // [4], [5]
71 "External Codec Enable", "Internally Codec Enable", // [6], [7]
72 "Render Channel Mode", "Captrue Channel Mode", // [8], [9]
73 "Headphone Playback Volume", "PCM Playback Volume", // [10], [11]
74 "PCM Capture Volume", "Mono Playback Volume", // [12], [13]
75 "Phone Capture Volume", "Mic Volume", // [14], [15]
76 "Surround Playback Volume", "Center/LFE Playback Volume", // [16], [17]
77 "DAC1 Volume", "DAC2 Volume", // [18], [19]
78 "DAC3 Volume", "DAC4 Volume", // [20], [21]
79 "ADC1 Volume", "ADC2 Volume", // [22], [23]
80 "ADC3 Volume", "ADC4 Volume", // [24], [25]
81 "Speaker1 Volume", "Speaker2 Volume", // [26], [27]
82 "Speaker3 Volume", "Speaker4 Volume", // [28], [29]
83 "MIC1 Volume", "MIC2 Volume", // [30], [31]
84 "MIC3 Volume", "MIC4 Volume", // [32], [33]
85 "MIC1 Boost Volume", "MIC2 Boost Volume", // [34], [35]
86 "INA1 Volume", "INB1 Volume", // [36], [37]
87 "INA2 Volume", "INB2 Volume", // [38], [39]
88 "Lineout1 Volume", "Lineout2 Volume", // [40], [41]
89 "Lineout3 Volume", "Lineout4 Volume", // [42], [43]
90 "Headphone Volume", "Receiver Volume", // [44], [45]
91 "EQ1 Switch", "EQ2 Switch", // [46], [47]
92 "DAI1 Filter Mode", "DAI2 Filter Mode", // [48], [49]
93 "ADC High Pass Filter Switch", "Playback Deemphasis", // [50], [51]
94 "PGA1 Setting", "PGA2 Setting", // [52], [53]
95 "PGA3 Setting", "PGA3 Setting", // [54], [55]
96 "ADC1 Mute", "ADC2 Mute", // [56], [57]
97 "ADC3 Mute", "ADC4 Mute", // [58], [59]
98 };
99
CodecGetServiceName(const struct HdfDeviceObject * device,const char ** drvCodecName)100 int32_t CodecGetServiceName(const struct HdfDeviceObject *device, const char **drvCodecName)
101 {
102 const struct DeviceResourceNode *node = NULL;
103 struct DeviceResourceIface *drsOps = NULL;
104 int32_t ret;
105
106 if (device == NULL) {
107 AUDIO_DRIVER_LOG_ERR("input device para is nullptr.");
108 return HDF_FAILURE;
109 }
110
111 node = device->property;
112 if (node == NULL) {
113 AUDIO_DRIVER_LOG_ERR("node instance is nullptr.");
114 return HDF_FAILURE;
115 }
116 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
117 if (drsOps == NULL || drsOps->GetString == NULL) {
118 AUDIO_DRIVER_LOG_ERR("from resource get drsOps fail!");
119 return HDF_FAILURE;
120 }
121
122 ret = drsOps->GetString(node, "serviceName", drvCodecName, 0);
123 if (ret != HDF_SUCCESS) {
124 AUDIO_DRIVER_LOG_ERR("read codecServiceName fail!");
125 return ret;
126 }
127
128 return HDF_SUCCESS;
129 }
130
CodecGetDaiName(const struct HdfDeviceObject * device,const char ** drvDaiName)131 int32_t CodecGetDaiName(const struct HdfDeviceObject *device, const char **drvDaiName)
132 {
133 const struct DeviceResourceNode *node = NULL;
134 struct DeviceResourceIface *drsOps = NULL;
135 int32_t ret;
136
137 if (device == NULL) {
138 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
139 return HDF_FAILURE;
140 }
141
142 node = device->property;
143 if (node == NULL) {
144 AUDIO_DRIVER_LOG_ERR("drs node is NULL.");
145 return HDF_FAILURE;
146 }
147 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
148 if (drsOps == NULL || drsOps->GetString == NULL) {
149 AUDIO_DRIVER_LOG_ERR("drs ops failed!");
150 return HDF_FAILURE;
151 }
152
153 ret = drsOps->GetString(node, "codecDaiName", drvDaiName, 0);
154 if (ret != HDF_SUCCESS) {
155 AUDIO_DRIVER_LOG_ERR("read codecDaiName fail!");
156 return ret;
157 }
158
159 return HDF_SUCCESS;
160 }
161
CodecGetConfigInfo(const struct HdfDeviceObject * device,struct CodecData * codecData)162 int32_t CodecGetConfigInfo(const struct HdfDeviceObject *device, struct CodecData *codecData)
163 {
164 if (device == NULL || codecData == NULL) {
165 AUDIO_DRIVER_LOG_ERR("param is null!");
166 return HDF_FAILURE;
167 }
168
169 if (codecData->regConfig != NULL) {
170 ADM_LOG_ERR("g_codecData regConfig fail!");
171 return HDF_FAILURE;
172 }
173
174 codecData->regConfig = (struct AudioRegCfgData *)OsalMemCalloc(sizeof(*(codecData->regConfig)));
175 if (codecData->regConfig == NULL) {
176 ADM_LOG_ERR("malloc AudioRegCfgData fail!");
177 return HDF_FAILURE;
178 }
179
180 if (CodecGetRegConfig(device, codecData->regConfig) != HDF_SUCCESS) {
181 ADM_LOG_ERR("CodecGetRegConfig fail!");
182 OsalMemFree(codecData->regConfig);
183 codecData->regConfig = NULL;
184 return HDF_FAILURE;
185 }
186
187 return HDF_SUCCESS;
188 }
189
SapmCtrlToSapmComp(struct AudioSapmComponent * sapmComponents,const struct AudioSapmCtrlConfig * sapmCompItem,uint16_t index)190 static int32_t SapmCtrlToSapmComp(struct AudioSapmComponent *sapmComponents,
191 const struct AudioSapmCtrlConfig *sapmCompItem, uint16_t index)
192 {
193 if (sapmComponents == NULL || sapmCompItem == NULL) {
194 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
195 return HDF_FAILURE;
196 }
197
198 sapmComponents[index].componentName =
199 g_audioSapmCompNameList[sapmCompItem[index].compNameIndex];
200 sapmComponents[index].reg = sapmCompItem[index].reg;
201 sapmComponents[index].sapmType = sapmCompItem[index].sapmType;
202 sapmComponents[index].mask = sapmCompItem[index].mask;
203 sapmComponents[index].shift = sapmCompItem[index].shift;
204 sapmComponents[index].invert = sapmCompItem[index].invert;
205 sapmComponents[index].kcontrolsNum = sapmCompItem[index].kcontrolsNum;
206
207 return HDF_SUCCESS;
208 }
209
CodecSetSapmKcontrolInfo(struct AudioKcontrol * audioSapmControls,struct AudioRegCfgGroupNode ** regCfgGroup)210 static int32_t CodecSetSapmKcontrolInfo(struct AudioKcontrol *audioSapmControls,
211 struct AudioRegCfgGroupNode **regCfgGroup)
212 {
213 uint16_t index;
214 struct AudioControlConfig *sapmCtrlItem = NULL;
215 struct AudioMixerControl *ctlSapmRegCfgItem = NULL;
216 struct AudioEnumCtrlConfig *ctlRegEnumCfgItem = NULL;
217
218 if (audioSapmControls == NULL || regCfgGroup == NULL) {
219 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
220 return HDF_FAILURE;
221 }
222 if (regCfgGroup[AUDIO_CTRL_SAPM_PATAM_GROUP] == NULL || regCfgGroup[AUDIO_SAPM_CFG_GROUP] == NULL) {
223 AUDIO_DRIVER_LOG_ERR("codec config hcs configuration file is no configuration information for sapm");
224 return HDF_SUCCESS;
225 }
226
227 sapmCtrlItem = regCfgGroup[AUDIO_SAPM_CFG_GROUP]->ctrlCfgItem;
228 ctlSapmRegCfgItem = regCfgGroup[AUDIO_CTRL_SAPM_PATAM_GROUP]->regCfgItem;
229 if (sapmCtrlItem == NULL || ctlSapmRegCfgItem == NULL) {
230 AUDIO_DRIVER_LOG_ERR("sapmCtrlItem, ctlSapmRegCfgItem is NULL.");
231 return HDF_FAILURE;
232 }
233
234 if (regCfgGroup[AUDIO_CTRL_SAPM_PATAM_MUX_GROUP] != NULL) {
235 ctlRegEnumCfgItem = regCfgGroup[AUDIO_CTRL_SAPM_PATAM_MUX_GROUP]->regEnumCfgItem;
236 if (ctlRegEnumCfgItem == NULL) {
237 AUDIO_DRIVER_LOG_ERR("ctlRegEnumCfgItem is NULL.");
238 return HDF_FAILURE;
239 }
240 }
241
242 for (index = 0; index < regCfgGroup[AUDIO_SAPM_CFG_GROUP]->itemNum; index++) {
243 if (sapmCtrlItem[index].type == AUDIO_CONTROL_MIXER) {
244 audioSapmControls[index].iface = sapmCtrlItem[index].iface;
245 audioSapmControls[index].name = g_audioSapmCfgNameList[sapmCtrlItem[index].arrayIndex];
246 audioSapmControls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlSapmRegCfgItem[index]);
247 audioSapmControls[index].Info = AudioInfoCtrlOps;
248 audioSapmControls[index].Get = AudioCodecSapmGetCtrlOps;
249 audioSapmControls[index].Set = AudioCodecSapmSetCtrlOps;
250 } else if (sapmCtrlItem[index].type == AUDIO_CONTROL_MUX) {
251 audioSapmControls[index].iface = sapmCtrlItem[index].iface;
252 audioSapmControls[index].name = g_audioSapmCfgNameList[sapmCtrlItem[index].arrayIndex];
253 audioSapmControls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlRegEnumCfgItem[index]);
254 audioSapmControls[index].Info = AudioInfoEnumCtrlOps;
255 audioSapmControls[index].Get = AudioCodecSapmGetEnumCtrlOps;
256 audioSapmControls[index].Set = AudioCodecSapmSetEnumCtrlOps;
257 }
258 }
259
260 return HDF_SUCCESS;
261 }
262
CodecSetSapmConfigInfo(struct CodecData * codeData,struct AudioRegCfgGroupNode ** regCfgGroup)263 static int32_t CodecSetSapmConfigInfo(struct CodecData *codeData, struct AudioRegCfgGroupNode **regCfgGroup)
264 {
265 uint16_t index;
266 struct AudioSapmCtrlConfig *sapmCompItem = NULL;
267 struct AudioKcontrol *audioSapmControls = NULL;
268 if (codeData == NULL || regCfgGroup == NULL) {
269 return HDF_FAILURE;
270 }
271 if (regCfgGroup[AUDIO_SAPM_COMP_GROUP] == NULL || regCfgGroup[AUDIO_SAPM_CFG_GROUP] == NULL) {
272 AUDIO_DRIVER_LOG_ERR("codec config hcs configuration file is no configuration information for sapm");
273 return HDF_SUCCESS;
274 }
275 sapmCompItem = regCfgGroup[AUDIO_SAPM_COMP_GROUP]->sapmCompItem;
276 if (sapmCompItem == NULL) {
277 AUDIO_DRIVER_LOG_ERR("sapmCompItem is NULL.");
278 return HDF_FAILURE;
279 }
280 audioSapmControls = (struct AudioKcontrol *)OsalMemCalloc(
281 regCfgGroup[AUDIO_SAPM_CFG_GROUP]->itemNum * sizeof(struct AudioKcontrol));
282 if (audioSapmControls == NULL) {
283 AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
284 return HDF_FAILURE;
285 }
286 if (CodecSetSapmKcontrolInfo(audioSapmControls, regCfgGroup) != HDF_SUCCESS) {
287 OsalMemFree(audioSapmControls);
288 return HDF_FAILURE;
289 }
290 codeData->numSapmComponent = regCfgGroup[AUDIO_SAPM_COMP_GROUP]->itemNum;
291 codeData->sapmComponents = (struct AudioSapmComponent *)
292 OsalMemCalloc(codeData->numSapmComponent * sizeof(struct AudioSapmComponent));
293 if (codeData->sapmComponents == NULL) {
294 OsalMemFree(audioSapmControls);
295 AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
296 return HDF_FAILURE;
297 }
298 for (index = 0; index < codeData->numSapmComponent; index++) {
299 if (SapmCtrlToSapmComp(codeData->sapmComponents, sapmCompItem, index)) {
300 OsalMemFree(audioSapmControls);
301 OsalMemFree(codeData->sapmComponents);
302 codeData->sapmComponents = NULL;
303 return HDF_FAILURE;
304 }
305
306 if (sapmCompItem[index].kcontrolsNum) {
307 codeData->sapmComponents[index].kcontrolNews =
308 &audioSapmControls[sapmCompItem[index].kcontrolNews - 1];
309 }
310 }
311 return HDF_SUCCESS;
312 }
313
CodecSetKcontrolInfo(struct CodecData * codeData,struct AudioRegCfgGroupNode ** regCfgGroup)314 static int32_t CodecSetKcontrolInfo(struct CodecData *codeData, struct AudioRegCfgGroupNode **regCfgGroup)
315 {
316 uint16_t index = 0;
317 uint16_t enumIndex = 0;
318 struct AudioControlConfig *compItem = NULL;
319 struct AudioMixerControl *ctlRegCfgItem = NULL;
320 struct AudioEnumCtrlConfig *enumCtlRegCfgItem = NULL;
321
322 if (codeData == NULL || regCfgGroup == NULL || regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL ||
323 regCfgGroup[AUDIO_CTRL_PATAM_GROUP] == NULL) {
324 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
325 return HDF_FAILURE;
326 }
327
328 compItem = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
329 ctlRegCfgItem = regCfgGroup[AUDIO_CTRL_PATAM_GROUP]->regCfgItem;
330 if (compItem == NULL || ctlRegCfgItem == NULL) {
331 AUDIO_DRIVER_LOG_ERR("compItem or ctlRegCfgItem is NULL.");
332 return HDF_FAILURE;
333 }
334
335 if (regCfgGroup[AUDIO_CTRL_PATAM_MUX_GROUP] != NULL) {
336 enumCtlRegCfgItem = regCfgGroup[AUDIO_CTRL_PATAM_MUX_GROUP]->regEnumCfgItem;
337 if (enumCtlRegCfgItem == NULL) {
338 AUDIO_DRIVER_LOG_ERR("enumCtlRegCfgItem is NULL.");
339 return HDF_FAILURE;
340 }
341 }
342
343 for (index = 0; index < codeData->numControls; index++) {
344 if (compItem[index].type == AUDIO_CONTROL_MIXER) {
345 codeData->controls[index].iface = compItem[index].iface;
346 codeData->controls[index].name = g_audioCodecControlsList[compItem[index].arrayIndex];
347 codeData->controls[index].Info = AudioInfoCtrlOps;
348 codeData->controls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlRegCfgItem[index]);
349 if (compItem[index].enable) {
350 codeData->controls[index].Get = AudioCodecGetCtrlOps;
351 codeData->controls[index].Set = AudioCodecSetCtrlOps;
352 }
353 } else if (compItem[index].type == AUDIO_CONTROL_MUX) {
354 codeData->controls[index].iface = compItem[index].iface;
355 codeData->controls[index].name = g_audioCodecControlsList[compItem[index].arrayIndex];
356 codeData->controls[index].Info = AudioInfoEnumCtrlOps;
357 codeData->controls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&enumCtlRegCfgItem[enumIndex++]);
358 if (compItem[index].enable) {
359 codeData->controls[index].Get = AudioCodecGetEnumCtrlOps;
360 codeData->controls[index].Set = AudioCodecSetEnumCtrlOps;
361 }
362 }
363 }
364 return HDF_SUCCESS;
365 }
366
CodecSetConfigInfoOfControls(struct CodecData * codeData,struct DaiData * daiData)367 int32_t CodecSetConfigInfoOfControls(struct CodecData *codeData, struct DaiData *daiData)
368 {
369 struct AudioIdInfo *audioIdInfo = NULL;
370 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
371
372 if (codeData == NULL || daiData == NULL || codeData->regConfig == NULL) {
373 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
374 return HDF_FAILURE;
375 }
376
377 audioIdInfo = &(codeData->regConfig->audioIdInfo);
378 regCfgGroup = codeData->regConfig->audioRegParams;
379 if (audioIdInfo == NULL || regCfgGroup == NULL) {
380 AUDIO_DRIVER_LOG_ERR("audioIdInfo or regCfgGroup is NULL.");
381 return HDF_FAILURE;
382 }
383 daiData->regCfgGroup = regCfgGroup;
384 codeData->regCfgGroup = regCfgGroup;
385
386 if (regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL) {
387 AUDIO_DRIVER_LOG_ERR("compItem is NULL.");
388 return HDF_FAILURE;
389 }
390
391 codeData->numControls = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->itemNum;
392 codeData->controls =
393 (struct AudioKcontrol *)OsalMemCalloc(codeData->numControls * sizeof(struct AudioKcontrol));
394 if (codeData->controls == NULL) {
395 AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
396 return HDF_FAILURE;
397 }
398
399 if (CodecSetKcontrolInfo(codeData, regCfgGroup) != HDF_SUCCESS) {
400 OsalMemFree(codeData->controls);
401 codeData->controls = NULL;
402 return HDF_FAILURE;
403 }
404 codeData->virtualAddress = (uintptr_t)OsalIoRemap(audioIdInfo->chipIdRegister, audioIdInfo->chipIdSize);
405
406 if (CodecSetSapmConfigInfo(codeData, regCfgGroup) != HDF_SUCCESS) {
407 OsalMemFree(codeData->controls);
408 codeData->controls = NULL;
409 return HDF_FAILURE;
410 }
411
412 return HDF_SUCCESS;
413 }
414
CodecSetCtlFunc(struct CodecData * codeData,enum AudioControlType controlType,const void * getCtrl,const void * setCtrl)415 int32_t CodecSetCtlFunc(struct CodecData *codeData, enum AudioControlType controlType, const void *getCtrl,
416 const void *setCtrl)
417 {
418 uint32_t index;
419 struct AudioRegCfgGroupNode **regCfgGroup;
420 struct AudioControlConfig *compItem;
421 if (codeData == NULL || codeData->regConfig == NULL ||
422 getCtrl == NULL || setCtrl == NULL) {
423 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
424 return HDF_FAILURE;
425 }
426 regCfgGroup = codeData->regConfig->audioRegParams;
427 if (regCfgGroup == NULL || regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL) {
428 AUDIO_DRIVER_LOG_ERR("regCfgGroup or regCfgGroup[AUDIO_CTRL_CFG_GROUP] is NULL.");
429 return HDF_FAILURE;
430 }
431
432 compItem = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
433 if (compItem == NULL) {
434 AUDIO_DRIVER_LOG_ERR("compItem is NULL.");
435 return HDF_FAILURE;
436 }
437
438 for (index = 0; index < codeData->numControls; index++) {
439 if (compItem[index].type == controlType) {
440 if (!compItem[index].enable) {
441 codeData->controls[index].Get = getCtrl;
442 codeData->controls[index].Set = setCtrl;
443 }
444 }
445 }
446
447 return HDF_SUCCESS;
448 }
449
450 // release I2C object public function
CodecI2cRelease(struct I2cMsg * msgs,int16_t msgSize,DevHandle i2cHandle)451 static void CodecI2cRelease(struct I2cMsg *msgs, int16_t msgSize, DevHandle i2cHandle)
452 {
453 if (msgs != NULL) {
454 if (msgSize == 0 && msgs->buf != NULL) {
455 OsalMemFree(msgs->buf);
456 msgs->buf = NULL;
457 } else if (msgSize == 1 && msgs[0].buf != NULL) {
458 OsalMemFree(msgs[0].buf);
459 msgs[0].buf = NULL;
460 } else if (msgSize >= I2C_MSG_NUM) {
461 if (msgs[0].buf != NULL) {
462 OsalMemFree(msgs[0].buf);
463 msgs[0].buf = NULL;
464 }
465 if (msgs[1].buf != NULL) {
466 OsalMemFree(msgs[1].buf);
467 msgs[1].buf = NULL;
468 }
469 }
470 AUDIO_DRIVER_LOG_DEBUG("OsalMemFree msgBuf success.\n");
471 }
472 // close i2c device
473 if (i2cHandle != NULL) {
474 I2cClose(i2cHandle);
475 i2cHandle = NULL;
476 AUDIO_DRIVER_LOG_DEBUG("I2cClose success.\n");
477 }
478 }
479
CodecI2cMsgFill(struct I2cTransferParam * i2cTransferParam,const struct AudioAddrConfig * regAttr,uint16_t rwFlag,uint8_t * regs,struct I2cMsg * msgs)480 static int32_t CodecI2cMsgFill(struct I2cTransferParam *i2cTransferParam, const struct AudioAddrConfig *regAttr,
481 uint16_t rwFlag, uint8_t *regs, struct I2cMsg *msgs)
482 {
483 uint8_t *msgBuf = NULL;
484
485 if (i2cTransferParam == NULL || regAttr == NULL || regs == NULL || msgs == NULL) {
486 AUDIO_DRIVER_LOG_ERR("input invalid parameter.");
487 return HDF_ERR_INVALID_PARAM;
488 }
489
490 if (rwFlag != 0 && rwFlag != I2C_FLAG_READ) {
491 AUDIO_DRIVER_LOG_ERR("invalid rwFlag value: %d.", rwFlag);
492 return HDF_ERR_INVALID_PARAM;
493 }
494 regs[0] = regAttr->addr;
495 msgs[0].addr = i2cTransferParam->i2cDevAddr;
496 msgs[0].flags = 0;
497 msgs[0].len = i2cTransferParam->i2cRegDataLen + 1;
498 AUDIO_DRIVER_LOG_DEBUG("msgs[0].addr=0x%02x, regs[0]=0x%02x.", msgs[0].addr, regs[0]);
499
500 if (rwFlag == 0) { // write
501 // S 11011A2A1 0 A ADDR A MS1 A LS1 A <....> P
502 msgBuf = OsalMemCalloc(i2cTransferParam->i2cRegDataLen + 1);
503 if (msgBuf == NULL) {
504 AUDIO_DRIVER_LOG_ERR("[write]: malloc buf failed!");
505 return HDF_ERR_MALLOC_FAIL;
506 }
507 msgBuf[0] = regs[0];
508 if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_1_BUTE) {
509 msgBuf[1] = (uint8_t)regAttr->value;
510 } else if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_2_BUTE) {
511 msgBuf[1] = (regAttr->value >> COMM_SHIFT_8BIT); // High 8 bit
512 msgBuf[I2C_MSG_BUF_SIZE_2_BUTE] = (uint8_t)(regAttr->value & COMM_MASK_FF); // Low 8 bit
513 } else {
514 AUDIO_DRIVER_LOG_ERR("i2cRegDataLen is invalid");
515 return HDF_FAILURE;
516 }
517 msgs[0].buf = msgBuf;
518 } else {
519 // S 11011A2A1 0 A ADDR A Sr 11011A2A1 1 A MS1 A LS1 A <....> NA P
520 msgBuf = OsalMemCalloc(i2cTransferParam->i2cRegDataLen);
521 if (msgBuf == NULL) {
522 AUDIO_DRIVER_LOG_ERR("[read]: malloc buf failed!");
523 return HDF_ERR_MALLOC_FAIL;
524 }
525 msgs[0].len = 1;
526 msgs[0].buf = regs;
527 msgs[1].addr = i2cTransferParam->i2cDevAddr;
528 msgs[1].flags = I2C_FLAG_READ;
529 msgs[1].len = i2cTransferParam->i2cRegDataLen;
530 msgs[1].buf = msgBuf;
531 }
532
533 return HDF_SUCCESS;
534 }
535
CodecI2cTransfer(struct I2cTransferParam * i2cTransferParam,struct AudioAddrConfig * regAttr,uint16_t rwFlag)536 static int32_t CodecI2cTransfer(struct I2cTransferParam *i2cTransferParam, struct AudioAddrConfig *regAttr,
537 uint16_t rwFlag)
538 {
539 int32_t ret;
540 DevHandle i2cHandle;
541 int16_t transferMsgCount = 1;
542 uint8_t regs[I2C_REG_LEN];
543 struct I2cMsg msgs[I2C_MSG_NUM];
544 (void)memset_s(msgs, sizeof(struct I2cMsg) * I2C_MSG_NUM, 0, sizeof(struct I2cMsg) * I2C_MSG_NUM);
545
546 AUDIO_DRIVER_LOG_DEBUG("entry.\n");
547 if (i2cTransferParam == NULL || regAttr == NULL || rwFlag > 1) {
548 AUDIO_DRIVER_LOG_ERR("invalid parameter.");
549 return HDF_ERR_INVALID_PARAM;
550 }
551 i2cHandle = I2cOpen(i2cTransferParam->i2cBusNumber);
552 if (i2cHandle == NULL) {
553 AUDIO_DRIVER_LOG_ERR("open i2cBus:%u failed! i2cHandle:%p", i2cTransferParam->i2cBusNumber, i2cHandle);
554 return HDF_FAILURE;
555 }
556 if (rwFlag == I2C_FLAG_READ) {
557 transferMsgCount = I2C_MSG_NUM;
558 }
559 ret = CodecI2cMsgFill(i2cTransferParam, regAttr, rwFlag, regs, msgs);
560 if (ret != HDF_SUCCESS) {
561 AUDIO_DRIVER_LOG_ERR("CodecI2cMsgFill failed!");
562 I2cClose(i2cHandle);
563 return HDF_FAILURE;
564 }
565 ret = I2cTransfer(i2cHandle, msgs, transferMsgCount);
566 if (ret != transferMsgCount) {
567 AUDIO_DRIVER_LOG_ERR("I2cTransfer err:%d", ret);
568 CodecI2cRelease(msgs, transferMsgCount, i2cHandle);
569 return HDF_FAILURE;
570 }
571 if (rwFlag == I2C_FLAG_READ) {
572 if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_1_BUTE) {
573 regAttr->value = msgs[1].buf[0];
574 } else if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_2_BUTE) {
575 regAttr->value = (msgs[1].buf[0] << COMM_SHIFT_8BIT) | msgs[1].buf[1]; // result value 16 bit
576 } else {
577 AUDIO_DRIVER_LOG_ERR("i2cRegDataLen is invalid");
578 return HDF_FAILURE;
579 }
580 AUDIO_DRIVER_LOG_DEBUG("[read]: regAttr->regValue=0x%04x", regAttr->value);
581 }
582
583 CodecI2cRelease(msgs, transferMsgCount, i2cHandle);
584 return HDF_SUCCESS;
585 }
586
CodecDeviceRegI2cRead(const struct CodecDevice * codec,uint32_t reg,uint32_t * val)587 int32_t CodecDeviceRegI2cRead(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
588 {
589 int32_t ret;
590 struct AudioAddrConfig regAttr;
591 struct I2cTransferParam *i2cTransferParam = NULL;
592
593 if (codec == NULL || codec->devData == NULL || val == NULL) {
594 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
595 return HDF_ERR_INVALID_OBJECT;
596 }
597
598 i2cTransferParam = (struct I2cTransferParam *)codec->devData->privateParam;
599 if (i2cTransferParam == NULL) {
600 AUDIO_DRIVER_LOG_ERR("codec i2cTransferParam is NULL.");
601 return HDF_FAILURE;
602 }
603
604 regAttr.addr = (uint8_t)reg;
605 regAttr.value = 0;
606 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, I2C_FLAG_READ);
607 if (ret != HDF_SUCCESS) {
608 AUDIO_DRIVER_LOG_ERR("failed.");
609 return HDF_FAILURE;
610 }
611 *val = regAttr.value;
612 AUDIO_DRIVER_LOG_DEBUG("success");
613 return HDF_SUCCESS;
614 }
615
CodecDeviceRegI2cWrite(const struct CodecDevice * codec,uint32_t reg,uint32_t value)616 int32_t CodecDeviceRegI2cWrite(const struct CodecDevice *codec, uint32_t reg, uint32_t value)
617 {
618 int32_t ret;
619 struct AudioAddrConfig regAttr;
620 struct I2cTransferParam *i2cTransferParam = NULL;
621 if (codec == NULL || codec->devData == NULL) {
622 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
623 return HDF_FAILURE;
624 }
625
626 i2cTransferParam = (struct I2cTransferParam *)codec->devData->privateParam;
627 if (i2cTransferParam == NULL) {
628 AUDIO_DRIVER_LOG_ERR("codec i2cTransferParam is NULL.");
629 return HDF_FAILURE;
630 }
631
632 regAttr.addr = (uint8_t)reg;
633 regAttr.value = (uint16_t)value;
634 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, 0);
635 if (ret != HDF_SUCCESS) {
636 AUDIO_DRIVER_LOG_ERR("I2c Transfer failed.");
637 return HDF_FAILURE;
638 }
639 AUDIO_DRIVER_LOG_DEBUG("success");
640 return HDF_SUCCESS;
641 }
642
CodecDaiRegI2cRead(const struct DaiDevice * dai,uint32_t reg,uint32_t * value)643 int32_t CodecDaiRegI2cRead(const struct DaiDevice *dai, uint32_t reg, uint32_t *value)
644 {
645 int32_t ret;
646 struct AudioAddrConfig regAttr;
647 struct I2cTransferParam *i2cTransferParam = NULL;
648
649 if (dai == NULL || dai->devData == NULL || value == NULL) {
650 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
651 return HDF_ERR_INVALID_OBJECT;
652 }
653
654 i2cTransferParam = (struct I2cTransferParam *)dai->devData->privateParam;
655 if (i2cTransferParam == NULL) {
656 AUDIO_DRIVER_LOG_ERR("codec dai i2cTransferParam is NULL.");
657 return HDF_FAILURE;
658 }
659
660 regAttr.addr = (uint8_t)reg;
661 regAttr.value = 0;
662 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, I2C_FLAG_READ);
663 if (ret != HDF_SUCCESS) {
664 AUDIO_DRIVER_LOG_ERR("CodecI2cTransfer failed.");
665 return HDF_FAILURE;
666 }
667 *value = regAttr.value;
668 AUDIO_DRIVER_LOG_DEBUG("success");
669 return HDF_SUCCESS;
670 }
671
CodecDaiRegI2cWrite(const struct DaiDevice * dai,uint32_t reg,uint32_t value)672 int32_t CodecDaiRegI2cWrite(const struct DaiDevice *dai, uint32_t reg, uint32_t value)
673 {
674 int32_t ret;
675 struct AudioAddrConfig regAttr;
676 struct I2cTransferParam *i2cTransferParam = NULL;
677 if (dai == NULL || dai->devData == NULL) {
678 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
679 return HDF_FAILURE;
680 }
681
682 i2cTransferParam = (struct I2cTransferParam *)dai->devData->privateParam;
683 if (i2cTransferParam == NULL) {
684 AUDIO_DRIVER_LOG_ERR("codec dai i2cTransferParam is NULL.");
685 return HDF_FAILURE;
686 }
687
688 regAttr.addr = (uint8_t)reg;
689 regAttr.value = (uint16_t)value;
690 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, 0);
691 if (ret != HDF_SUCCESS) {
692 AUDIO_DRIVER_LOG_ERR("codec I2c Transfer failed.");
693 return HDF_FAILURE;
694 }
695 AUDIO_DRIVER_LOG_DEBUG("success");
696 return HDF_SUCCESS;
697 }
698
CodecDeviceReadReg(const struct CodecDevice * codec,uint32_t reg,uint32_t * val)699 int32_t CodecDeviceReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
700 {
701 unsigned long virtualAddress;
702 if (codec == NULL || codec->devData == NULL || val == NULL) {
703 AUDIO_DRIVER_LOG_ERR("param val is null.");
704 return HDF_FAILURE;
705 }
706 virtualAddress = codec->devData->virtualAddress;
707 *val = OSAL_READL((void *)((uintptr_t)(virtualAddress + reg)));
708 return HDF_SUCCESS;
709 }
710
CodecDeviceWriteReg(const struct CodecDevice * codec,uint32_t reg,uint32_t value)711 int32_t CodecDeviceWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t value)
712 {
713 unsigned long virtualAddress;
714 if (codec == NULL || codec->devData == NULL) {
715 AUDIO_DRIVER_LOG_ERR("param val is null.");
716 return HDF_FAILURE;
717 }
718 virtualAddress = codec->devData->virtualAddress;
719 OSAL_WRITEL(value, (void *)((uintptr_t)(virtualAddress + reg)));
720 return HDF_SUCCESS;
721 }
722
CodecDeviceInitRegConfig(const struct CodecDevice * device)723 int32_t CodecDeviceInitRegConfig(const struct CodecDevice *device)
724 {
725 int32_t ret;
726 uint32_t index;
727 struct AudioAddrConfig *initCfg = NULL;
728 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
729
730 if (device == NULL || device->devData == NULL || device->devData->Write == NULL) {
731 AUDIO_DRIVER_LOG_ERR("param val is null.");
732 return HDF_FAILURE;
733 }
734
735 regCfgGroup = device->devData->regCfgGroup;
736 if (regCfgGroup == NULL || regCfgGroup[AUDIO_INIT_GROUP] == NULL) {
737 AUDIO_DRIVER_LOG_ERR("regCfgGroup init group is null.");
738 return HDF_FAILURE;
739 }
740
741 initCfg = regCfgGroup[AUDIO_INIT_GROUP]->addrCfgItem;
742 if (initCfg == NULL) {
743 AUDIO_DRIVER_LOG_ERR("initCfg is NULL.");
744 return HDF_FAILURE;
745 }
746
747 for (index = 0; index < regCfgGroup[AUDIO_INIT_GROUP]->itemNum; index++) {
748 ret = device->devData->Write(device, initCfg[index].addr, initCfg[index].value);
749 if (ret != HDF_SUCCESS) {
750 AUDIO_DRIVER_LOG_ERR("Write err regAddr: 0x%x.\n", initCfg[index].addr);
751 return HDF_FAILURE;
752 }
753 OsalMSleep(COMM_WAIT_TIMES);
754 }
755 AUDIO_DRIVER_LOG_DEBUG("success.");
756 return HDF_SUCCESS;
757 }
758
CodecDaiDeviceStartupRegConfig(const struct DaiDevice * device)759 int32_t CodecDaiDeviceStartupRegConfig(const struct DaiDevice *device)
760 {
761 int32_t ret;
762 uint16_t index;
763 struct AudioMixerControl *startupRegCfgItem = NULL;
764 uint16_t regCfgItemCount;
765 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
766
767 if (device == NULL || device->devData == NULL) {
768 AUDIO_DRIVER_LOG_ERR("param val is null.");
769 return HDF_FAILURE;
770 }
771
772 regCfgGroup = device->devData->regCfgGroup;
773 if (regCfgGroup == NULL || regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP] == NULL ||
774 regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem == NULL) {
775 AUDIO_DEVICE_LOG_ERR("regCfgGroup is NULL.");
776 return HDF_FAILURE;
777 }
778 startupRegCfgItem = regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem;
779 regCfgItemCount = regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->itemNum;
780
781 for (index = 0; index < regCfgItemCount; index++) {
782 ret = AudioDaiRegUpdate(device, &startupRegCfgItem[index]);
783 if (ret != HDF_SUCCESS) {
784 AUDIO_DEVICE_LOG_ERR("CodecDaiRegBitsUpdate fail.");
785 return HDF_FAILURE;
786 }
787 }
788 AUDIO_DEVICE_LOG_DEBUG("success.");
789 return HDF_SUCCESS;
790 }
791
792