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 1
26 #define I2C_MSG_BUF_SIZE_2 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 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_INFO("g_codecData regConfig has been parsed!");
171 return HDF_SUCCESS;
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 (AudioGetRegConfig(device, codecData->regConfig) != HDF_SUCCESS) {
181 ADM_LOG_ERR("AudioGetRegConfig fail!");
182 OsalMemFree(codecData->regConfig);
183 codecData->regConfig = NULL;
184 return HDF_FAILURE;
185 }
186
187 return HDF_SUCCESS;
188 }
189
CodecDaiGetPortConfigInfo(const struct HdfDeviceObject * device,struct DaiData * codecData)190 int32_t CodecDaiGetPortConfigInfo(const struct HdfDeviceObject *device, struct DaiData *codecData)
191 {
192 if (device == NULL || codecData == NULL) {
193 ADM_LOG_ERR("<device> or <codecData> is a null pointer!");
194 return HDF_ERR_INVALID_PARAM;
195 }
196
197 return AudioGetPortConfig(device, &codecData->portInfo);
198 }
199
SapmCtrlToSapmComp(struct AudioSapmComponent * sapmComponents,const struct AudioSapmCtrlConfig * sapmCompItem,uint16_t index)200 static int32_t SapmCtrlToSapmComp(struct AudioSapmComponent *sapmComponents,
201 const struct AudioSapmCtrlConfig *sapmCompItem, uint16_t index)
202 {
203 if (sapmComponents == NULL || sapmCompItem == NULL) {
204 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
205 return HDF_FAILURE;
206 }
207
208 sapmComponents[index].componentName =
209 g_audioSapmCompNameList[sapmCompItem[index].compNameIndex];
210 sapmComponents[index].reg = sapmCompItem[index].reg;
211 sapmComponents[index].sapmType = sapmCompItem[index].sapmType;
212 sapmComponents[index].mask = sapmCompItem[index].mask;
213 sapmComponents[index].shift = sapmCompItem[index].shift;
214 sapmComponents[index].invert = sapmCompItem[index].invert;
215 sapmComponents[index].kcontrolsNum = sapmCompItem[index].kcontrolsNum;
216
217 return HDF_SUCCESS;
218 }
219
CodecSetSapmKcontrolInfo(struct AudioKcontrol * audioSapmControls,struct AudioRegCfgGroupNode ** regCfgGroup)220 static int32_t CodecSetSapmKcontrolInfo(struct AudioKcontrol *audioSapmControls,
221 struct AudioRegCfgGroupNode **regCfgGroup)
222 {
223 uint16_t index;
224 struct AudioControlConfig *sapmCtrlItem = NULL;
225 struct AudioMixerControl *ctlSapmRegCfgItem = NULL;
226 struct AudioEnumCtrlConfig *ctlRegEnumCfgItem = NULL;
227
228 if (audioSapmControls == NULL || regCfgGroup == NULL) {
229 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
230 return HDF_FAILURE;
231 }
232 if (regCfgGroup[AUDIO_CTRL_SAPM_PATAM_GROUP] == NULL || regCfgGroup[AUDIO_SAPM_CFG_GROUP] == NULL) {
233 AUDIO_DRIVER_LOG_ERR("codec config hcs configuration file is no configuration information for sapm");
234 return HDF_SUCCESS;
235 }
236
237 sapmCtrlItem = regCfgGroup[AUDIO_SAPM_CFG_GROUP]->ctrlCfgItem;
238 ctlSapmRegCfgItem = regCfgGroup[AUDIO_CTRL_SAPM_PATAM_GROUP]->regCfgItem;
239 if (sapmCtrlItem == NULL || ctlSapmRegCfgItem == NULL) {
240 AUDIO_DRIVER_LOG_ERR("sapmCtrlItem, ctlSapmRegCfgItem is NULL.");
241 return HDF_FAILURE;
242 }
243
244 if (regCfgGroup[AUDIO_CTRL_SAPM_PATAM_MUX_GROUP] != NULL) {
245 ctlRegEnumCfgItem = regCfgGroup[AUDIO_CTRL_SAPM_PATAM_MUX_GROUP]->regEnumCfgItem;
246 if (ctlRegEnumCfgItem == NULL) {
247 AUDIO_DRIVER_LOG_ERR("ctlRegEnumCfgItem is NULL.");
248 return HDF_FAILURE;
249 }
250 }
251
252 for (index = 0; index < regCfgGroup[AUDIO_SAPM_CFG_GROUP]->itemNum; index++) {
253 if (sapmCtrlItem[index].type == AUDIO_CONTROL_MIXER) {
254 audioSapmControls[index].iface = sapmCtrlItem[index].iface;
255 audioSapmControls[index].name = g_audioSapmCfgNameList[sapmCtrlItem[index].arrayIndex];
256 audioSapmControls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlSapmRegCfgItem[index]);
257 audioSapmControls[index].Info = AudioInfoCtrlOps;
258 audioSapmControls[index].Get = AudioCodecSapmGetCtrlOps;
259 audioSapmControls[index].Set = AudioCodecSapmSetCtrlOps;
260 } else if (sapmCtrlItem[index].type == AUDIO_CONTROL_MUX) {
261 audioSapmControls[index].iface = sapmCtrlItem[index].iface;
262 audioSapmControls[index].name = g_audioSapmCfgNameList[sapmCtrlItem[index].arrayIndex];
263 audioSapmControls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlRegEnumCfgItem[index]);
264 audioSapmControls[index].Info = AudioInfoEnumCtrlOps;
265 audioSapmControls[index].Get = AudioCodecSapmGetEnumCtrlOps;
266 audioSapmControls[index].Set = AudioCodecSapmSetEnumCtrlOps;
267 }
268 }
269
270 return HDF_SUCCESS;
271 }
272
CodecSetSapmConfigInfo(struct CodecData * codeData,struct AudioRegCfgGroupNode ** regCfgGroup)273 static int32_t CodecSetSapmConfigInfo(struct CodecData *codeData, struct AudioRegCfgGroupNode **regCfgGroup)
274 {
275 uint16_t index;
276 struct AudioSapmCtrlConfig *sapmCompItem = NULL;
277 struct AudioKcontrol *audioSapmControls = NULL;
278 if (codeData == NULL || regCfgGroup == NULL) {
279 return HDF_FAILURE;
280 }
281 if (regCfgGroup[AUDIO_SAPM_COMP_GROUP] == NULL || regCfgGroup[AUDIO_SAPM_CFG_GROUP] == NULL) {
282 AUDIO_DRIVER_LOG_ERR("codec config hcs configuration file is no configuration information for sapm");
283 return HDF_SUCCESS;
284 }
285 sapmCompItem = regCfgGroup[AUDIO_SAPM_COMP_GROUP]->sapmCompItem;
286 if (sapmCompItem == NULL) {
287 AUDIO_DRIVER_LOG_ERR("sapmCompItem is NULL.");
288 return HDF_FAILURE;
289 }
290 audioSapmControls = (struct AudioKcontrol *)OsalMemCalloc(
291 regCfgGroup[AUDIO_SAPM_CFG_GROUP]->itemNum * sizeof(struct AudioKcontrol));
292 if (audioSapmControls == NULL) {
293 AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
294 return HDF_FAILURE;
295 }
296 if (CodecSetSapmKcontrolInfo(audioSapmControls, regCfgGroup) != HDF_SUCCESS) {
297 OsalMemFree(audioSapmControls);
298 return HDF_FAILURE;
299 }
300 codeData->numSapmComponent = regCfgGroup[AUDIO_SAPM_COMP_GROUP]->itemNum;
301 codeData->sapmComponents = (struct AudioSapmComponent *)
302 OsalMemCalloc(codeData->numSapmComponent * sizeof(struct AudioSapmComponent));
303 if (codeData->sapmComponents == NULL) {
304 OsalMemFree(audioSapmControls);
305 AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
306 return HDF_FAILURE;
307 }
308 for (index = 0; index < codeData->numSapmComponent; index++) {
309 if (SapmCtrlToSapmComp(codeData->sapmComponents, sapmCompItem, index)) {
310 OsalMemFree(audioSapmControls);
311 OsalMemFree(codeData->sapmComponents);
312 codeData->sapmComponents = NULL;
313 return HDF_FAILURE;
314 }
315
316 if (sapmCompItem[index].kcontrolsNum) {
317 codeData->sapmComponents[index].kcontrolNews =
318 &audioSapmControls[sapmCompItem[index].kcontrolNews - 1];
319 }
320 }
321 return HDF_SUCCESS;
322 }
323
CodecSetKcontrolInfo(struct CodecData * codeData,struct AudioRegCfgGroupNode ** regCfgGroup)324 static int32_t CodecSetKcontrolInfo(struct CodecData *codeData, struct AudioRegCfgGroupNode **regCfgGroup)
325 {
326 uint16_t index = 0;
327 uint16_t enumIndex = 0;
328 struct AudioControlConfig *compItem = NULL;
329 struct AudioMixerControl *ctlRegCfgItem = NULL;
330 struct AudioEnumCtrlConfig *enumCtlRegCfgItem = NULL;
331
332 if (codeData == NULL || regCfgGroup == NULL || regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL ||
333 regCfgGroup[AUDIO_CTRL_PATAM_GROUP] == NULL) {
334 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
335 return HDF_FAILURE;
336 }
337
338 compItem = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
339 ctlRegCfgItem = regCfgGroup[AUDIO_CTRL_PATAM_GROUP]->regCfgItem;
340 if (compItem == NULL || ctlRegCfgItem == NULL) {
341 AUDIO_DRIVER_LOG_ERR("compItem or ctlRegCfgItem is NULL.");
342 return HDF_FAILURE;
343 }
344
345 if (regCfgGroup[AUDIO_CTRL_PATAM_MUX_GROUP] != NULL) {
346 enumCtlRegCfgItem = regCfgGroup[AUDIO_CTRL_PATAM_MUX_GROUP]->regEnumCfgItem;
347 if (enumCtlRegCfgItem == NULL) {
348 AUDIO_DRIVER_LOG_ERR("enumCtlRegCfgItem is NULL.");
349 return HDF_FAILURE;
350 }
351 }
352
353 for (index = 0; index < codeData->numControls; index++) {
354 if (compItem[index].type == AUDIO_CONTROL_MIXER) {
355 codeData->controls[index].iface = compItem[index].iface;
356 codeData->controls[index].name = g_audioCodecControlsList[compItem[index].arrayIndex];
357 codeData->controls[index].Info = AudioInfoCtrlOps;
358 codeData->controls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&ctlRegCfgItem[index]);
359 if (compItem[index].enable) {
360 codeData->controls[index].Get = AudioCodecGetCtrlOps;
361 codeData->controls[index].Set = AudioCodecSetCtrlOps;
362 }
363 } else if (compItem[index].type == AUDIO_CONTROL_MUX) {
364 codeData->controls[index].iface = compItem[index].iface;
365 codeData->controls[index].name = g_audioCodecControlsList[compItem[index].arrayIndex];
366 codeData->controls[index].Info = AudioInfoEnumCtrlOps;
367 codeData->controls[index].privateValue = (unsigned long)(uintptr_t)(void*)(&enumCtlRegCfgItem[enumIndex++]);
368 if (compItem[index].enable) {
369 codeData->controls[index].Get = AudioCodecGetEnumCtrlOps;
370 codeData->controls[index].Set = AudioCodecSetEnumCtrlOps;
371 }
372 }
373 }
374 return HDF_SUCCESS;
375 }
376
CodecSetConfigInfoOfControls(struct CodecData * codeData,struct DaiData * daiData)377 int32_t CodecSetConfigInfoOfControls(struct CodecData *codeData, struct DaiData *daiData)
378 {
379 struct AudioIdInfo *audioIdInfo = NULL;
380 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
381
382 if (codeData == NULL || daiData == NULL || codeData->regConfig == NULL) {
383 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
384 return HDF_FAILURE;
385 }
386
387 audioIdInfo = &(codeData->regConfig->audioIdInfo);
388 regCfgGroup = codeData->regConfig->audioRegParams;
389 if (audioIdInfo == NULL || regCfgGroup == NULL) {
390 AUDIO_DRIVER_LOG_ERR("audioIdInfo or regCfgGroup is NULL.");
391 return HDF_FAILURE;
392 }
393 daiData->regCfgGroup = regCfgGroup;
394 codeData->regCfgGroup = regCfgGroup;
395
396 if (regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL) {
397 AUDIO_DRIVER_LOG_ERR("compItem is NULL.");
398 return HDF_FAILURE;
399 }
400
401 codeData->numControls = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->itemNum;
402 codeData->controls =
403 (struct AudioKcontrol *)OsalMemCalloc(codeData->numControls * sizeof(struct AudioKcontrol));
404 if (codeData->controls == NULL) {
405 AUDIO_DRIVER_LOG_ERR("OsalMemCalloc failed.");
406 return HDF_FAILURE;
407 }
408
409 if (CodecSetKcontrolInfo(codeData, regCfgGroup) != HDF_SUCCESS) {
410 OsalMemFree(codeData->controls);
411 codeData->controls = NULL;
412 return HDF_FAILURE;
413 }
414 codeData->virtualAddress = (uintptr_t)OsalIoRemap(audioIdInfo->chipIdRegister, audioIdInfo->chipIdSize);
415
416 if (CodecSetSapmConfigInfo(codeData, regCfgGroup) != HDF_SUCCESS) {
417 OsalMemFree(codeData->controls);
418 codeData->controls = NULL;
419 return HDF_FAILURE;
420 }
421
422 return HDF_SUCCESS;
423 }
424
CodecSetCtlFunc(struct CodecData * codeData,enum AudioControlType controlType,const void * getCtrl,const void * setCtrl)425 int32_t CodecSetCtlFunc(struct CodecData *codeData, enum AudioControlType controlType, const void *getCtrl,
426 const void *setCtrl)
427 {
428 uint32_t index;
429 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
430 struct AudioControlConfig *compItem = NULL;
431 if (codeData == NULL || codeData->regConfig == NULL ||
432 getCtrl == NULL || setCtrl == NULL) {
433 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
434 return HDF_FAILURE;
435 }
436 regCfgGroup = codeData->regConfig->audioRegParams;
437 if (regCfgGroup == NULL || regCfgGroup[AUDIO_CTRL_CFG_GROUP] == NULL) {
438 AUDIO_DRIVER_LOG_ERR("regCfgGroup or regCfgGroup[AUDIO_CTRL_CFG_GROUP] is NULL.");
439 return HDF_FAILURE;
440 }
441
442 compItem = regCfgGroup[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
443 if (compItem == NULL) {
444 AUDIO_DRIVER_LOG_ERR("compItem is NULL.");
445 return HDF_FAILURE;
446 }
447
448 for (index = 0; index < codeData->numControls; index++) {
449 if (compItem[index].type == controlType) {
450 if (!compItem[index].enable) {
451 codeData->controls[index].Get = getCtrl;
452 codeData->controls[index].Set = setCtrl;
453 }
454 }
455 }
456
457 return HDF_SUCCESS;
458 }
459
460 // release I2C object public function
CodecI2cRelease(struct I2cMsg * msgs,int16_t msgSize,DevHandle i2cHandle)461 static void CodecI2cRelease(struct I2cMsg *msgs, int16_t msgSize, DevHandle i2cHandle)
462 {
463 if (msgs != NULL) {
464 if (msgSize == 0 && msgs->buf != NULL) {
465 OsalMemFree(msgs->buf);
466 msgs->buf = NULL;
467 } else if (msgSize == 1 && msgs[0].buf != NULL) {
468 OsalMemFree(msgs[0].buf);
469 msgs[0].buf = NULL;
470 } else if (msgSize >= I2C_MSG_NUM) {
471 if (msgs[0].buf != NULL) {
472 OsalMemFree(msgs[0].buf);
473 msgs[0].buf = NULL;
474 }
475 if (msgs[1].buf != NULL) {
476 OsalMemFree(msgs[1].buf);
477 msgs[1].buf = NULL;
478 }
479 }
480 AUDIO_DRIVER_LOG_DEBUG("OsalMemFree msgBuf success.\n");
481 }
482 // close i2c device
483 if (i2cHandle != NULL) {
484 I2cClose(i2cHandle);
485 i2cHandle = NULL;
486 AUDIO_DRIVER_LOG_DEBUG("I2cClose success.\n");
487 }
488 }
489
CodecI2cMsgFill(struct I2cTransferParam * i2cTransferParam,const struct AudioAddrConfig * regAttr,uint16_t rwFlag,uint8_t * regs,struct I2cMsg * msgs)490 static int32_t CodecI2cMsgFill(struct I2cTransferParam *i2cTransferParam, const struct AudioAddrConfig *regAttr,
491 uint16_t rwFlag, uint8_t *regs, struct I2cMsg *msgs)
492 {
493 uint8_t *msgBuf = NULL;
494
495 if (i2cTransferParam == NULL || regAttr == NULL || regs == NULL || msgs == NULL) {
496 AUDIO_DRIVER_LOG_ERR("input invalid parameter.");
497 return HDF_ERR_INVALID_PARAM;
498 }
499
500 if (rwFlag != 0 && rwFlag != I2C_FLAG_READ) {
501 AUDIO_DRIVER_LOG_ERR("invalid rwFlag value: %d.", rwFlag);
502 return HDF_ERR_INVALID_PARAM;
503 }
504 regs[0] = regAttr->addr;
505 msgs[0].addr = i2cTransferParam->i2cDevAddr;
506 msgs[0].flags = 0;
507 msgs[0].len = i2cTransferParam->i2cRegDataLen + 1;
508 AUDIO_DRIVER_LOG_DEBUG("msgs[0].addr=0x%02x, regs[0]=0x%02x.", msgs[0].addr, regs[0]);
509
510 if (rwFlag == 0) { // write
511 // S 11011A2A1 0 A ADDR A MS1 A LS1 A <....> P
512 msgBuf = OsalMemCalloc(i2cTransferParam->i2cRegDataLen + 1);
513 if (msgBuf == NULL) {
514 AUDIO_DRIVER_LOG_ERR("[write]: malloc buf failed!");
515 return HDF_ERR_MALLOC_FAIL;
516 }
517 msgBuf[0] = regs[0];
518 if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_1) {
519 msgBuf[1] = (uint8_t)regAttr->value;
520 } else if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_2) {
521 msgBuf[1] = (regAttr->value >> COMM_SHIFT_8BIT); // High 8 bit
522 msgBuf[I2C_MSG_BUF_SIZE_2] = (uint8_t)(regAttr->value & COMM_MASK_FF); // Low 8 bit
523 } else {
524 AUDIO_DRIVER_LOG_ERR("i2cRegDataLen is invalid");
525 return HDF_FAILURE;
526 }
527 msgs[0].buf = msgBuf;
528 } else {
529 // S 11011A2A1 0 A ADDR A Sr 11011A2A1 1 A MS1 A LS1 A <....> NA P
530 msgBuf = OsalMemCalloc(i2cTransferParam->i2cRegDataLen);
531 if (msgBuf == NULL) {
532 AUDIO_DRIVER_LOG_ERR("[read]: malloc buf failed!");
533 return HDF_ERR_MALLOC_FAIL;
534 }
535 msgs[0].len = 1;
536 msgs[0].buf = regs;
537 msgs[1].addr = i2cTransferParam->i2cDevAddr;
538 msgs[1].flags = I2C_FLAG_READ;
539 msgs[1].len = i2cTransferParam->i2cRegDataLen;
540 msgs[1].buf = msgBuf;
541 }
542
543 return HDF_SUCCESS;
544 }
545
CodecI2cTransfer(struct I2cTransferParam * i2cTransferParam,struct AudioAddrConfig * regAttr,uint16_t rwFlag)546 static int32_t CodecI2cTransfer(struct I2cTransferParam *i2cTransferParam, struct AudioAddrConfig *regAttr,
547 uint16_t rwFlag)
548 {
549 int32_t ret;
550 DevHandle i2cHandle;
551 int16_t transferMsgCount = 1;
552 uint8_t regs[I2C_REG_LEN];
553 struct I2cMsg msgs[I2C_MSG_NUM];
554 (void)memset_s(msgs, sizeof(struct I2cMsg) * I2C_MSG_NUM, 0, sizeof(struct I2cMsg) * I2C_MSG_NUM);
555
556 AUDIO_DRIVER_LOG_DEBUG("entry.\n");
557 if (i2cTransferParam == NULL || regAttr == NULL || rwFlag > 1) {
558 AUDIO_DRIVER_LOG_ERR("invalid parameter.");
559 return HDF_ERR_INVALID_PARAM;
560 }
561 i2cHandle = I2cOpen(i2cTransferParam->i2cBusNumber);
562 if (i2cHandle == NULL) {
563 AUDIO_DRIVER_LOG_ERR("open i2cBus:%u failed!", i2cTransferParam->i2cBusNumber);
564 return HDF_FAILURE;
565 }
566 if (rwFlag == I2C_FLAG_READ) {
567 transferMsgCount = I2C_MSG_NUM;
568 }
569 ret = CodecI2cMsgFill(i2cTransferParam, regAttr, rwFlag, regs, msgs);
570 if (ret != HDF_SUCCESS) {
571 AUDIO_DRIVER_LOG_ERR("CodecI2cMsgFill failed!");
572 I2cClose(i2cHandle);
573 return HDF_FAILURE;
574 }
575 ret = I2cTransfer(i2cHandle, msgs, transferMsgCount);
576 if (ret != transferMsgCount) {
577 AUDIO_DRIVER_LOG_ERR("I2cTransfer err:%d", ret);
578 CodecI2cRelease(msgs, transferMsgCount, i2cHandle);
579 return HDF_FAILURE;
580 }
581 if (rwFlag == I2C_FLAG_READ) {
582 if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_1) {
583 regAttr->value = msgs[1].buf[0];
584 } else if (i2cTransferParam->i2cRegDataLen == I2C_MSG_BUF_SIZE_2) {
585 regAttr->value = (msgs[1].buf[0] << COMM_SHIFT_8BIT) | msgs[1].buf[1]; // result value 16 bit
586 } else {
587 AUDIO_DRIVER_LOG_ERR("i2cRegDataLen is invalid");
588 return HDF_FAILURE;
589 }
590 AUDIO_DRIVER_LOG_DEBUG("[read]: regAttr->regValue=0x%04x", regAttr->value);
591 }
592
593 CodecI2cRelease(msgs, transferMsgCount, i2cHandle);
594 return HDF_SUCCESS;
595 }
596
CodecDeviceRegI2cRead(const struct CodecDevice * codec,uint32_t reg,uint32_t * val)597 int32_t CodecDeviceRegI2cRead(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
598 {
599 int32_t ret;
600 struct AudioAddrConfig regAttr;
601 struct I2cTransferParam *i2cTransferParam = NULL;
602
603 if (codec == NULL || codec->devData == NULL || val == NULL) {
604 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
605 return HDF_ERR_INVALID_OBJECT;
606 }
607
608 i2cTransferParam = (struct I2cTransferParam *)codec->devData->privateParam;
609 if (i2cTransferParam == NULL) {
610 AUDIO_DRIVER_LOG_ERR("codec i2cTransferParam is NULL.");
611 return HDF_FAILURE;
612 }
613
614 regAttr.addr = (uint8_t)reg;
615 regAttr.value = 0;
616 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, I2C_FLAG_READ);
617 if (ret != HDF_SUCCESS) {
618 AUDIO_DRIVER_LOG_ERR("failed.");
619 return HDF_FAILURE;
620 }
621 *val = regAttr.value;
622 AUDIO_DRIVER_LOG_DEBUG("success");
623 return HDF_SUCCESS;
624 }
625
CodecDeviceRegI2cWrite(const struct CodecDevice * codec,uint32_t reg,uint32_t value)626 int32_t CodecDeviceRegI2cWrite(const struct CodecDevice *codec, uint32_t reg, uint32_t value)
627 {
628 int32_t ret;
629 struct AudioAddrConfig regAttr;
630 struct I2cTransferParam *i2cTransferParam = NULL;
631 if (codec == NULL || codec->devData == NULL) {
632 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
633 return HDF_FAILURE;
634 }
635
636 i2cTransferParam = (struct I2cTransferParam *)codec->devData->privateParam;
637 if (i2cTransferParam == NULL) {
638 AUDIO_DRIVER_LOG_ERR("codec i2cTransferParam is NULL.");
639 return HDF_FAILURE;
640 }
641
642 regAttr.addr = (uint8_t)reg;
643 regAttr.value = (uint16_t)value;
644 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, 0);
645 if (ret != HDF_SUCCESS) {
646 AUDIO_DRIVER_LOG_ERR("I2c Transfer failed.");
647 return HDF_FAILURE;
648 }
649 AUDIO_DRIVER_LOG_DEBUG("success");
650 return HDF_SUCCESS;
651 }
652
CodecDaiRegI2cRead(const struct DaiDevice * dai,uint32_t reg,uint32_t * value)653 int32_t CodecDaiRegI2cRead(const struct DaiDevice *dai, uint32_t reg, uint32_t *value)
654 {
655 int32_t ret;
656 struct AudioAddrConfig regAttr;
657 struct I2cTransferParam *i2cTransferParam = NULL;
658
659 if (dai == NULL || dai->devData == NULL || value == NULL) {
660 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
661 return HDF_ERR_INVALID_OBJECT;
662 }
663
664 i2cTransferParam = (struct I2cTransferParam *)dai->devData->privateParam;
665 if (i2cTransferParam == NULL) {
666 AUDIO_DRIVER_LOG_ERR("codec dai i2cTransferParam is NULL.");
667 return HDF_FAILURE;
668 }
669
670 regAttr.addr = (uint8_t)reg;
671 regAttr.value = 0;
672 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, I2C_FLAG_READ);
673 if (ret != HDF_SUCCESS) {
674 AUDIO_DRIVER_LOG_ERR("CodecI2cTransfer failed.");
675 return HDF_FAILURE;
676 }
677 *value = regAttr.value;
678 AUDIO_DRIVER_LOG_DEBUG("success");
679 return HDF_SUCCESS;
680 }
681
CodecDaiRegI2cWrite(const struct DaiDevice * dai,uint32_t reg,uint32_t value)682 int32_t CodecDaiRegI2cWrite(const struct DaiDevice *dai, uint32_t reg, uint32_t value)
683 {
684 int32_t ret;
685 struct AudioAddrConfig regAttr;
686 struct I2cTransferParam *i2cTransferParam = NULL;
687 if (dai == NULL || dai->devData == NULL) {
688 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
689 return HDF_FAILURE;
690 }
691
692 i2cTransferParam = (struct I2cTransferParam *)dai->devData->privateParam;
693 if (i2cTransferParam == NULL) {
694 AUDIO_DRIVER_LOG_ERR("codec dai i2cTransferParam is NULL.");
695 return HDF_FAILURE;
696 }
697
698 regAttr.addr = (uint8_t)reg;
699 regAttr.value = (uint16_t)value;
700 ret = CodecI2cTransfer(i2cTransferParam, ®Attr, 0);
701 if (ret != HDF_SUCCESS) {
702 AUDIO_DRIVER_LOG_ERR("codec I2c Transfer failed.");
703 return HDF_FAILURE;
704 }
705 AUDIO_DRIVER_LOG_DEBUG("success");
706 return HDF_SUCCESS;
707 }
708
CodecDeviceReadReg(const struct CodecDevice * codec,uint32_t reg,uint32_t * val)709 int32_t CodecDeviceReadReg(const struct CodecDevice *codec, uint32_t reg, uint32_t *val)
710 {
711 unsigned long virtualAddress;
712 if (codec == NULL || codec->devData == NULL || val == NULL) {
713 AUDIO_DRIVER_LOG_ERR("param val is null.");
714 return HDF_FAILURE;
715 }
716 virtualAddress = codec->devData->virtualAddress;
717 *val = OSAL_READL((void *)((uintptr_t)(virtualAddress + reg)));
718 return HDF_SUCCESS;
719 }
720
CodecDeviceWriteReg(const struct CodecDevice * codec,uint32_t reg,uint32_t value)721 int32_t CodecDeviceWriteReg(const struct CodecDevice *codec, uint32_t reg, uint32_t value)
722 {
723 unsigned long virtualAddress;
724 if (codec == NULL || codec->devData == NULL) {
725 AUDIO_DRIVER_LOG_ERR("param val is null.");
726 return HDF_FAILURE;
727 }
728 virtualAddress = codec->devData->virtualAddress;
729 OSAL_WRITEL(value, (void *)((uintptr_t)(virtualAddress + reg)));
730 return HDF_SUCCESS;
731 }
732
CodecDeviceInitRegConfig(const struct CodecDevice * device)733 int32_t CodecDeviceInitRegConfig(const struct CodecDevice *device)
734 {
735 int32_t ret;
736 uint32_t index;
737 struct AudioAddrConfig *initCfg = NULL;
738 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
739
740 if (device == NULL || device->devData == NULL || device->devData->Write == NULL) {
741 AUDIO_DRIVER_LOG_ERR("param val is null.");
742 return HDF_FAILURE;
743 }
744
745 regCfgGroup = device->devData->regCfgGroup;
746 if (regCfgGroup == NULL || regCfgGroup[AUDIO_INIT_GROUP] == NULL) {
747 AUDIO_DRIVER_LOG_ERR("regCfgGroup init group is null.");
748 return HDF_FAILURE;
749 }
750
751 initCfg = regCfgGroup[AUDIO_INIT_GROUP]->addrCfgItem;
752 if (initCfg == NULL) {
753 AUDIO_DRIVER_LOG_ERR("initCfg is NULL.");
754 return HDF_FAILURE;
755 }
756
757 for (index = 0; index < regCfgGroup[AUDIO_INIT_GROUP]->itemNum; index++) {
758 ret = device->devData->Write(device, initCfg[index].addr, initCfg[index].value);
759 if (ret != HDF_SUCCESS) {
760 AUDIO_DRIVER_LOG_ERR("Write err regAddr: 0x%x.\n", initCfg[index].addr);
761 return HDF_FAILURE;
762 }
763 OsalMSleep(COMM_WAIT_TIMES);
764 }
765 AUDIO_DRIVER_LOG_DEBUG("success.");
766 return HDF_SUCCESS;
767 }
768
CodecDaiDeviceStartupRegConfig(const struct DaiDevice * device)769 int32_t CodecDaiDeviceStartupRegConfig(const struct DaiDevice *device)
770 {
771 int32_t ret;
772 uint16_t index;
773 struct AudioMixerControl *startupRegCfgItem = NULL;
774 uint16_t regCfgItemCount;
775 struct AudioRegCfgGroupNode **regCfgGroup = NULL;
776
777 if (device == NULL || device->devData == NULL) {
778 AUDIO_DRIVER_LOG_ERR("param val is null.");
779 return HDF_FAILURE;
780 }
781
782 regCfgGroup = device->devData->regCfgGroup;
783 if (regCfgGroup == NULL || regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP] == NULL ||
784 regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem == NULL) {
785 AUDIO_DEVICE_LOG_ERR("regCfgGroup is NULL.");
786 return HDF_FAILURE;
787 }
788 startupRegCfgItem = regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->regCfgItem;
789 regCfgItemCount = regCfgGroup[AUDIO_DAI_STARTUP_PATAM_GROUP]->itemNum;
790
791 for (index = 0; index < regCfgItemCount; index++) {
792 ret = AudioDaiRegUpdate(device, &startupRegCfgItem[index]);
793 if (ret != HDF_SUCCESS) {
794 AUDIO_DEVICE_LOG_ERR("CodecDaiRegBitsUpdate fail.");
795 return HDF_FAILURE;
796 }
797 }
798 AUDIO_DEVICE_LOG_DEBUG("success.");
799 return HDF_SUCCESS;
800 }
801
802