• 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_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(&regVal, 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(&regAttr, &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(&regVal, 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(&regAttr, 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(&regAttr, 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