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_accessory_base.h"
10 #include "audio_driver_log.h"
11 #include "i2c_if.h"
12 #include "osal_time.h"
13
14 #define HDF_LOG_TAG "audio_accessory_base"
15
16 #define COMM_SHIFT_8BIT (8)
17 #define COMM_MASK_FF (0xFF)
18 #define COMM_WAIT_TIMES (10) // ms
19
20 #define I2C_REG_LEN (1)
21 #define I2C_REG_MSGLEN (3)
22 #define I2C_MSG_NUM (2)
23 #define I2C_MSG_BUF_SIZE (2)
24
25 uint16_t g_i2cDevAddr, g_i2cBusNumber;
26 struct AudioRegCfgGroupNode **g_audioRegCfgGroupNode = NULL;
27 struct AudioKcontrol *g_audioControls = NULL;
28
29 static const char *g_audioAccessoryControlsList[AUDIO_CTRL_LIST_MAX] = {
30 "Main Playback Volume", "Main Capture Volume",
31 "Playback Mute", "Capture Mute", "Mic Left Gain",
32 "Mic Right Gain", "External Codec Enable",
33 "Internally Codec Enable", "Render Channel Mode", "Captrue Channel Mode"
34 };
35 /*
36 * release I2C object public function
37 */
AccessoryI2cRelease(struct I2cMsg * msgs,int16_t msgSize,DevHandle i2cHandle)38 static void AccessoryI2cRelease(struct I2cMsg *msgs, int16_t msgSize, DevHandle i2cHandle)
39 {
40 if (msgs != NULL) {
41 if (msgSize == 0 && msgs->buf != NULL) {
42 OsalMemFree(msgs->buf);
43 msgs->buf = NULL;
44 } else if (msgSize == 1 && msgs[0].buf != NULL) {
45 OsalMemFree(msgs[0].buf);
46 msgs[0].buf = NULL;
47 } else if (msgSize >= I2C_MSG_NUM) {
48 if (msgs[0].buf != NULL) {
49 msgs[0].buf = NULL;
50 }
51 if (msgs[1].buf != NULL) {
52 OsalMemFree(msgs[1].buf);
53 msgs[1].buf = NULL;
54 }
55 }
56 AUDIO_DRIVER_LOG_DEBUG("OsalMemFree msgBuf success.\n");
57 }
58 // close i2c device
59 if (i2cHandle != NULL) {
60 I2cClose(i2cHandle);
61 i2cHandle = NULL;
62 AUDIO_DRIVER_LOG_DEBUG("I2cClose success.\n");
63 }
64 }
65
AccessoryI2cMsgFill(const struct AudioAddrConfig * regAttr,uint16_t rwFlag,uint8_t * regs,struct I2cMsg * msgs)66 static int32_t AccessoryI2cMsgFill(const struct AudioAddrConfig *regAttr, uint16_t rwFlag,
67 uint8_t *regs, struct I2cMsg *msgs)
68 {
69 uint8_t *msgBuf = NULL;
70 if (rwFlag != 0 && rwFlag != I2C_FLAG_READ) {
71 AUDIO_DRIVER_LOG_ERR("invalid rwFlag value: %d.", rwFlag);
72 return HDF_ERR_INVALID_PARAM;
73 }
74 regs[0] = regAttr->addr;
75 msgs[0].addr = g_i2cDevAddr;
76 msgs[0].flags = 0;
77 msgs[0].len = I2C_REG_MSGLEN;
78 AUDIO_DRIVER_LOG_DEBUG("msgs[0].addr=0x%02x, regs[0]=0x%02x.", msgs[0].addr, regs[0]);
79 if (rwFlag == 0) { // write
80 // S 11011A2A1 0 A ADDR A MS1 A LS1 A <....> P
81 msgBuf = OsalMemCalloc(I2C_REG_MSGLEN);
82 if (msgBuf == NULL) {
83 AUDIO_DRIVER_LOG_ERR("[write]: malloc buf failed!");
84 return HDF_ERR_MALLOC_FAIL;
85 }
86 msgBuf[0] = regs[0];
87 msgBuf[1] = (uint8_t)(regAttr->value >> COMM_SHIFT_8BIT); // High 8 bit
88 msgBuf[I2C_MSG_BUF_SIZE] = (uint8_t)(regAttr->value & COMM_MASK_FF); // Low 8 bit
89 msgs[0].buf = msgBuf;
90 AUDIO_DRIVER_LOG_DEBUG("msgBuf[1]=0x%02x.", msgBuf[1]);
91 AUDIO_DRIVER_LOG_DEBUG("msgBuf[2]=0x%02x.", msgBuf[I2C_MSG_BUF_SIZE]);
92 } else {
93 // S 11011A2A1 0 A ADDR A Sr 11011A2A1 1 A MS1 A LS1 A <....> NA P
94 msgBuf = OsalMemCalloc(I2C_MSG_NUM);
95 if (msgBuf == NULL) {
96 AUDIO_DRIVER_LOG_ERR("[read]: malloc buf failed!");
97 return HDF_ERR_MALLOC_FAIL;
98 }
99 msgs[0].len = 1;
100 msgs[0].buf = regs;
101 msgs[1].addr = g_i2cDevAddr;
102 msgs[1].flags = I2C_FLAG_READ;
103 msgs[1].len = I2C_MSG_NUM;
104 msgs[1].buf = msgBuf;
105 }
106 AUDIO_DRIVER_LOG_DEBUG("success.");
107 return HDF_SUCCESS;
108 }
109
AccessoryI2cReadWrite(struct AudioAddrConfig * regAttr,uint16_t rwFlag)110 int32_t AccessoryI2cReadWrite(struct AudioAddrConfig *regAttr, uint16_t rwFlag)
111 {
112 int32_t ret;
113 DevHandle i2cHandle;
114 int16_t transferMsgCount = 1;
115 uint8_t regs[I2C_REG_LEN];
116 struct I2cMsg msgs[I2C_MSG_NUM];
117 (void)memset_s(msgs, sizeof(struct I2cMsg) * I2C_MSG_NUM, 0, sizeof(struct I2cMsg) * I2C_MSG_NUM);
118
119 AUDIO_DRIVER_LOG_DEBUG("entry.\n");
120 if (regAttr == NULL || rwFlag < 0 || rwFlag > 1) {
121 AUDIO_DRIVER_LOG_ERR("invalid parameter.");
122 return HDF_ERR_INVALID_PARAM;
123 }
124 i2cHandle = I2cOpen(g_i2cBusNumber);
125 if (i2cHandle == NULL) {
126 AUDIO_DRIVER_LOG_ERR("open i2cBus:%u failed! i2cHandle:%p", g_i2cBusNumber, i2cHandle);
127 return HDF_FAILURE;
128 }
129 if (rwFlag == I2C_FLAG_READ) {
130 transferMsgCount = I2C_MSG_NUM;
131 }
132 ret = AccessoryI2cMsgFill(regAttr, rwFlag, regs, msgs);
133 if (ret != HDF_SUCCESS) {
134 AUDIO_DRIVER_LOG_ERR("AccessoryI2cMsgFill failed!");
135 I2cClose(i2cHandle);
136 return HDF_FAILURE;
137 }
138 ret = I2cTransfer(i2cHandle, msgs, transferMsgCount);
139 if (ret != transferMsgCount) {
140 AUDIO_DRIVER_LOG_ERR("I2cTransfer err:%d", ret);
141 AccessoryI2cRelease(msgs, transferMsgCount, i2cHandle);
142 return HDF_FAILURE;
143 }
144 if (rwFlag == I2C_FLAG_READ) {
145 regAttr->value = (msgs[1].buf[0] << COMM_SHIFT_8BIT) | msgs[1].buf[1]; // result value 16 bit
146 AUDIO_DRIVER_LOG_DEBUG("[read]: regAttr->regValue=0x%04x.\n", regAttr->value);
147 }
148 AccessoryI2cRelease(msgs, transferMsgCount, i2cHandle);
149 return HDF_SUCCESS;
150 }
151
152 // Read contrl reg bits value
AccessoryRegBitsRead(struct AudioMixerControl * regAttr,uint32_t * regValue)153 int32_t AccessoryRegBitsRead(struct AudioMixerControl *regAttr, uint32_t *regValue)
154 {
155 int32_t ret;
156 struct AudioAddrConfig regVal;
157 if (regAttr == NULL || regAttr->reg < 0 || regValue == NULL) {
158 AUDIO_DRIVER_LOG_ERR("input invalid parameter.");
159 return HDF_ERR_INVALID_PARAM;
160 }
161 regVal.addr = regAttr->reg;
162 ret = AccessoryI2cReadWrite(®Val, I2C_FLAG_READ);
163 if (ret != HDF_SUCCESS) {
164 AUDIO_DRIVER_LOG_ERR("AccessoryRegBitsRead failed.");
165 return HDF_FAILURE;
166 }
167 *regValue = regVal.value;
168 regAttr->value = (regVal.value >> regAttr->shift) & regAttr->mask;
169 if (regAttr->value > regAttr->max || regAttr->value < regAttr->min) {
170 AUDIO_DRIVER_LOG_ERR("invalid bitsValue=0x%x", regAttr->value);
171 return HDF_FAILURE;
172 }
173 if (regAttr->invert) {
174 regAttr->value = regAttr->max - regAttr->value;
175 }
176 AUDIO_DRIVER_LOG_DEBUG("regAddr=0x%x, regValue=0x%x, currBitsValue=0x%x",
177 regAttr->reg, regVal.value, regAttr->value);
178 AUDIO_DRIVER_LOG_DEBUG("mask=0x%x, shift=%d, max=0x%x,min=0x%x, invert=%d",
179 regAttr->mask, regAttr->shift, regAttr->max, regAttr->min, regAttr->invert);
180 AUDIO_DRIVER_LOG_DEBUG("success.");
181 return HDF_SUCCESS;
182 }
183
184 // Update contrl reg bits value
AccessoryRegBitsUpdate(struct AudioMixerControl regAttr)185 int32_t AccessoryRegBitsUpdate(struct AudioMixerControl regAttr)
186 {
187 int32_t ret;
188 struct AudioAddrConfig regVal;
189 uint32_t newValue, newMask, value;
190 if (regAttr.reg < 0) {
191 AUDIO_DRIVER_LOG_ERR("input invalid parameter.");
192 return HDF_ERR_INVALID_PARAM;
193 }
194 if (regAttr.invert) {
195 regAttr.value = regAttr.max - regAttr.value;
196 }
197 newValue = regAttr.value << regAttr.shift;
198 newMask = regAttr.mask << regAttr.shift;
199 ret = AccessoryRegBitsRead(®Attr, &value);
200 if (ret != HDF_SUCCESS) {
201 ADM_LOG_ERR("AccessoryRegBitsRead faileded, ret=%d.", ret);
202 return HDF_FAILURE;
203 }
204 regVal.value = (value & ~newMask) | (newValue & newMask);
205 regVal.addr = regAttr.reg;
206 ret = AccessoryI2cReadWrite(®Val, 0);
207 if (ret != HDF_SUCCESS) {
208 AUDIO_DRIVER_LOG_ERR("AccessoryI2cReadWrite faileded.");
209 return HDF_FAILURE;
210 }
211 AUDIO_DRIVER_LOG_DEBUG("regAddr=0x%x, regValue=0x%x, oldValue=0x%x, newValue=0x%x,",
212 regAttr.reg, regVal.value, regAttr.value, newValue);
213 AUDIO_DRIVER_LOG_DEBUG(" mask=0x%x, shift=%d, max=0x%x, min=0x%x, invert=%d",
214 newMask, regAttr.shift, regAttr.max, regAttr.min, regAttr.invert);
215 AUDIO_DRIVER_LOG_DEBUG("success.");
216 return HDF_SUCCESS;
217 }
218
219 // update external codec I2S frequency
AccessoryDaiParamsUpdate(struct DaiParamsVal daiParamsVal)220 int32_t AccessoryDaiParamsUpdate(struct DaiParamsVal daiParamsVal)
221 {
222 int32_t ret;
223 const int itemNum = 3; // current only 3 items(frequency, format, channel)
224 struct AudioMixerControl *regAttr = NULL;
225 ret = (g_audioRegCfgGroupNode == NULL || g_audioRegCfgGroupNode[AUDIO_DAI_PATAM_GROUP] == NULL
226 || g_audioRegCfgGroupNode[AUDIO_DAI_PATAM_GROUP]->regCfgItem == NULL
227 || g_audioRegCfgGroupNode[AUDIO_DAI_PATAM_GROUP]->itemNum < itemNum);
228 if (ret) {
229 AUDIO_DRIVER_LOG_ERR("g_audioRegCfgGroupNode[AUDIO_DAI_PATAM_GROUP] is NULL.");
230 return HDF_FAILURE;
231 }
232 regAttr = g_audioRegCfgGroupNode[AUDIO_DAI_PATAM_GROUP]->regCfgItem;
233 regAttr[0].value = daiParamsVal.frequencyVal;
234 ret = AccessoryRegBitsUpdate(regAttr[0]);
235 if (ret != HDF_SUCCESS) {
236 AUDIO_DRIVER_LOG_ERR("set freq failed.");
237 return HDF_FAILURE;
238 }
239 regAttr[1].value = daiParamsVal.formatVal;
240 ret = AccessoryRegBitsUpdate(regAttr[1]);
241 if (ret != HDF_SUCCESS) {
242 AUDIO_DRIVER_LOG_ERR("set format failed.");
243 return HDF_FAILURE;
244 }
245 regAttr[itemNum - 1].value = daiParamsVal.channelVal;
246 ret = AccessoryRegBitsUpdate(regAttr[itemNum - 1]);
247 if (ret != HDF_SUCCESS) {
248 AUDIO_DRIVER_LOG_ERR("set channel failed.");
249 return HDF_FAILURE;
250 }
251 AUDIO_DRIVER_LOG_DEBUG("success.");
252 return HDF_SUCCESS;
253 }
254
AcessoryDeviceFrequencyParse(uint32_t rate,uint16_t * freq)255 int32_t AcessoryDeviceFrequencyParse(uint32_t rate, uint16_t *freq)
256 {
257 if (freq == NULL) {
258 AUDIO_DRIVER_LOG_ERR("input param is NULL");
259 return HDF_FAILURE;
260 }
261 switch (rate) {
262 case I2S_SAMPLE_FREQUENCY_8000:
263 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_8000;
264 break;
265 case I2S_SAMPLE_FREQUENCY_11025:
266 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_11025;
267 break;
268 case I2S_SAMPLE_FREQUENCY_12000:
269 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_12000;
270 break;
271 case I2S_SAMPLE_FREQUENCY_16000:
272 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_16000;
273 break;
274 case I2S_SAMPLE_FREQUENCY_22050:
275 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_22050;
276 break;
277 case I2S_SAMPLE_FREQUENCY_24000:
278 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_24000;
279 break;
280 case I2S_SAMPLE_FREQUENCY_32000:
281 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_32000;
282 break;
283 case I2S_SAMPLE_FREQUENCY_44100:
284 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_44100;
285 break;
286 case I2S_SAMPLE_FREQUENCY_48000:
287 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_48000;
288 break;
289 case I2S_SAMPLE_FREQUENCY_64000:
290 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_64000;
291 break;
292 case I2S_SAMPLE_FREQUENCY_88200:
293 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_88200;
294 break;
295 case I2S_SAMPLE_FREQUENCY_96000:
296 *freq = I2S_SAMPLE_FREQUENCY_REG_VAL_96000;
297 break;
298 default:
299 AUDIO_DRIVER_LOG_ERR("rate: %d is not support.", rate);
300 return HDF_ERR_NOT_SUPPORT;
301 }
302 AUDIO_DRIVER_LOG_DEBUG("success.");
303 return HDF_SUCCESS;
304 }
305
AccessoryDeviceCfgGet(struct AccessoryData * accessoryData,struct AccessoryTransferData * accessoryTransferData)306 int32_t AccessoryDeviceCfgGet(struct AccessoryData *accessoryData,
307 struct AccessoryTransferData *accessoryTransferData)
308 {
309 int32_t ret;
310 int32_t index;
311 int32_t audioCfgCtrlCount;
312 struct AudioControlConfig *ctlcfgItem;
313 ret = (accessoryData == NULL || accessoryData->regConfig == NULL || accessoryTransferData == NULL);
314 if (ret) {
315 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
316 return HDF_FAILURE;
317 }
318 g_i2cDevAddr = accessoryTransferData->i2cDevAddr;
319 g_i2cBusNumber = accessoryTransferData->i2cBusNumber;
320 g_audioRegCfgGroupNode = accessoryData->regConfig->audioRegParams;
321 ret = (g_audioRegCfgGroupNode[AUDIO_CTRL_CFG_GROUP] == NULL ||
322 g_audioRegCfgGroupNode[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem == NULL ||
323 g_audioRegCfgGroupNode[AUDIO_CTRL_PATAM_GROUP] == NULL ||
324 g_audioRegCfgGroupNode[AUDIO_CTRL_PATAM_GROUP]->regCfgItem == NULL);
325 if (ret) {
326 AUDIO_DRIVER_LOG_ERR("parsing params is NULL.");
327 return HDF_FAILURE;
328 }
329 ctlcfgItem = g_audioRegCfgGroupNode[AUDIO_CTRL_CFG_GROUP]->ctrlCfgItem;
330 audioCfgCtrlCount = g_audioRegCfgGroupNode[AUDIO_CTRL_CFG_GROUP]->itemNum;
331 g_audioControls = (struct AudioKcontrol *)OsalMemCalloc(audioCfgCtrlCount * sizeof(struct AudioKcontrol));
332 accessoryTransferData->accessoryRegCfgGroupNode = g_audioRegCfgGroupNode;
333 accessoryTransferData->accessoryCfgCtrlCount = audioCfgCtrlCount;
334 accessoryTransferData->accessoryControls = g_audioControls;
335 for (index = 0; index < audioCfgCtrlCount; index++) {
336 g_audioControls[index].iface = ctlcfgItem[index].iface;
337 g_audioControls[index].name = g_audioAccessoryControlsList[ctlcfgItem[index].arrayIndex];
338 g_audioControls[index].Info = AudioInfoCtrlOps;
339 g_audioControls[index].privateValue =
340 (unsigned long)(uintptr_t)(void*)(&g_audioRegCfgGroupNode[AUDIO_CTRL_PATAM_GROUP]->regCfgItem[index]);
341 g_audioControls[index].Get = AudioAccessoryGetCtrlOps;
342 g_audioControls[index].Set = AudioAccessorySetCtrlOps;
343 }
344 return HDF_SUCCESS;
345 }
346
347 /*
348 * init control reg to default value
349 */
AccessoryDeviceCtrlRegInit(void)350 int32_t AccessoryDeviceCtrlRegInit(void)
351 {
352 int32_t ret, i;
353 struct AudioAddrConfig *initCfg;
354 // Set codec control register(00h-14h) default value
355 ret = (g_audioRegCfgGroupNode == NULL || g_audioRegCfgGroupNode[AUDIO_INIT_GROUP] == NULL
356 || g_audioRegCfgGroupNode[AUDIO_INIT_GROUP]->addrCfgItem == NULL);
357 if (ret) {
358 AUDIO_DRIVER_LOG_ERR("g_audioRegCfgGroupNode[AUDIO_INIT_GROUP] is NULL.");
359 return HDF_FAILURE;
360 }
361 initCfg = g_audioRegCfgGroupNode[AUDIO_INIT_GROUP]->addrCfgItem;
362 for (i = 0; i < g_audioRegCfgGroupNode[AUDIO_INIT_GROUP]->itemNum; i++) {
363 AUDIO_DRIVER_LOG_DEBUG("i=%d, Addr = [0x%2x]", i, initCfg[i].addr);
364 ret = AccessoryI2cReadWrite(&initCfg[i], 0);
365 if (ret != HDF_SUCCESS) {
366 AUDIO_DRIVER_LOG_ERR("AccessoryI2cReadWrite(write) err, regAttr.regAddr: 0x%x.\n",
367 initCfg[i].addr);
368 return HDF_FAILURE;
369 }
370 OsalMSleep(COMM_WAIT_TIMES);
371 }
372 AUDIO_DRIVER_LOG_DEBUG("success.");
373 return HDF_SUCCESS;
374 }
375
AccessoryDeviceRegRead(const struct AccessoryDevice * codec,uint32_t reg,uint32_t * val)376 int32_t AccessoryDeviceRegRead(const struct AccessoryDevice *codec, uint32_t reg, uint32_t *val)
377 {
378 int32_t ret;
379 struct AudioAddrConfig regAttr;
380 if (val == NULL) {
381 AUDIO_DRIVER_LOG_ERR("input para is NULL.");
382 return HDF_ERR_INVALID_OBJECT;
383 }
384 (void)codec;
385 regAttr.addr = (uint8_t)reg;
386 regAttr.value = 0;
387 ret = AccessoryI2cReadWrite(®Attr, I2C_FLAG_READ);
388 if (ret != HDF_SUCCESS) {
389 AUDIO_DRIVER_LOG_ERR("failed.");
390 return HDF_FAILURE;
391 }
392 *val = regAttr.value;
393 AUDIO_DRIVER_LOG_DEBUG("success");
394 return HDF_SUCCESS;
395 }
396
AccessoryDeviceRegWrite(const struct AccessoryDevice * codec,uint32_t reg,uint32_t value)397 int32_t AccessoryDeviceRegWrite(const struct AccessoryDevice *codec, uint32_t reg, uint32_t value)
398 {
399 int32_t ret;
400 struct AudioAddrConfig regAttr;
401 (void)codec;
402 regAttr.addr = (uint8_t)reg;
403 regAttr.value = (uint16_t)value;
404 ret = AccessoryI2cReadWrite(®Attr, 0);
405 if (ret != HDF_SUCCESS) {
406 AUDIO_DRIVER_LOG_ERR("failed.");
407 return HDF_FAILURE;
408 }
409 AUDIO_DRIVER_LOG_DEBUG("success");
410 return HDF_SUCCESS;
411 }
412
AccessoryGetConfigInfo(const struct HdfDeviceObject * device,struct AccessoryData * accessoryData)413 int32_t AccessoryGetConfigInfo(const struct HdfDeviceObject *device, struct AccessoryData *accessoryData)
414 {
415 if (device == NULL || accessoryData == NULL) {
416 AUDIO_DRIVER_LOG_ERR("param is null!");
417 return HDF_FAILURE;
418 }
419
420 if (accessoryData->regConfig != NULL) {
421 ADM_LOG_ERR("g_codecData regConfig fail!");
422 return HDF_FAILURE;
423 }
424
425 accessoryData->regConfig = (struct AudioRegCfgData *)OsalMemCalloc(sizeof(*(accessoryData->regConfig)));
426 if (accessoryData->regConfig == NULL) {
427 ADM_LOG_ERR("malloc AudioRegCfgData fail!");
428 return HDF_FAILURE;
429 }
430
431 if (CodecGetRegConfig(device, accessoryData->regConfig) != HDF_SUCCESS) {
432 ADM_LOG_ERR("CodecGetRegConfig fail!");
433 return HDF_FAILURE;
434 }
435
436 return HDF_SUCCESS;
437 }
438