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 "tfa9879_accessory_impl.h"
10 #include "audio_accessory_base.h"
11 #include "audio_core.h"
12 #include "audio_device_log.h"
13 #include "audio_sapm.h"
14 #include "gpio_if.h"
15 #include "hdf_log.h"
16 #include "i2c_if.h"
17
18 #define HDF_LOG_TAG "tfa9879_codec"
19
20 #define CTRL_REG_NUM 21
21
22 #define CHANNEL_MAX_NUM 2
23 #define CHANNEL_MIN_NUM 1
24
25 #define I2C_BUS_NUM 6
26 #define I2C_8BIT 8
27 #define I2C_REG_LEN 1
28 #define I2C_MSG_NUM 2
29 #define I2C_MSG_BUF_SIZE 2
30 #define I2C_WAIT_TIMES 10 // ms
31
32 #define VOLUME_MIN 0
33 #define VOLUME_MAX 100
34 #define MUTE__MAX 255
35 #define MUTE_MIN 189
36
37 #define TFA9879_MSG_SIZE 2
38 #define TFA9879_REG_MSGLEN 3
39 #define TFA9879_RIGHT_SHIFT 8
40 #define TFA9879_MUST_SLEEP 10
41 #define TFA9879_REG_MASK 0xFF
42 #define TFA9879_REG_MASK_4 0xF
43 #define TFA9879_REG_MASK_16 0xFFFF
44
45 const int MUTE_SHIFT = 9;
46 const int CHANNEL_SHIFT = 10;
47
48 static uint16_t g_i2cDevAddr;
49
50
51 /* Tfa9879 Special Region Begin */
SysWritel(unsigned long addr,unsigned int value)52 static void SysWritel(unsigned long addr, unsigned int value)
53 {
54 *(volatile unsigned int *)(addr) = value;
55 }
56
57 /* tfa9879 21 control register default value */
58 struct Tfa9879RegAttr g_tfa9879RegDefaultAttr[] = {
59 {
60 .regAddr = DEVICE_CONTROL_REG_ADDR,
61 .regValue = 0x0001 // 0x0009
62 }, {
63 .regAddr = SERIAL_INTERFACE_INPUT1_REG_ADDR,
64 .regValue = 0x0a18 // 48khz, up to 24 bits
65 }, {
66 .regAddr = PCM_IOM2_FMT_INPUT1_REG_ADDR,
67 .regValue = 0x0007
68 }, {
69 .regAddr = SERIAL_INTERFACE_INPUT2_REG_ADDR,
70 .regValue = 0x0a18
71 }, {
72 .regAddr = PCM_IOM2_FMT_INPUT2_REG_ADDR,
73 .regValue = 0x0007
74 }, {
75 .regAddr = EQUALIZER_A_WORD1_REG_ADDR,
76 .regValue = 0x59DD
77 }, {
78 .regAddr = EQUALIZER_A_WORD2_REG_ADDR,
79 .regValue = 0xC63E
80 }, {
81 .regAddr = EQUALIZER_B_WORD1_REG_ADDR,
82 .regValue = 0x651A
83 }, {
84 .regAddr = EQUALIZER_B_WORD2_REG_ADDR,
85 .regValue = 0xE53E
86 }, {
87 .regAddr = EQUALIZER_C_WORD1_REG_ADDR,
88 .regValue = 0x4616
89 }, {
90 .regAddr = EQUALIZER_C_WORD2_REG_ADDR,
91 .regValue = 0xD33E
92 }, {
93 .regAddr = EQUALIZER_D_WORD1_REG_ADDR,
94 .regValue = 0x4DF3
95 }, {
96 .regAddr = EQUALIZER_D_WORD2_REG_ADDR,
97 .regValue = 0xEA3E
98 }, {
99 .regAddr = EQUALIZER_E_WORD1_REG_ADDR,
100 .regValue = 0x5EE0
101 }, {
102 .regAddr = EQUALIZER_E_WORD2_REG_ADDR,
103 .regValue = 0xF93E
104 }, {
105 .regAddr = BYPASS_CONTROL_REG_ADDR,
106 .regValue = 0x0008 // 0x00ff // 0x0093
107 }, {
108 .regAddr = DYNAMIC_RANGE_COMP_REG_ADDR,
109 .regValue = 0x92BA
110 }, {
111 .regAddr = BASS_TREBLE_REG_ADDR,
112 .regValue = 0x12A5
113 }, {
114 .regAddr = HIGH_PASS_FILTER_REG_ADDR,
115 .regValue = 0x0004
116 }, {
117 .regAddr = VOLUME_CONTROL_REG_ADDR,
118 .regValue = 0x1031 // 0x101A
119 }, {
120 .regAddr = DE_EMPHASIS_REG_ADDR,
121 .regValue = 0x0000
122 }
123 };
124
125 /*
126 * release object public function
127 */
ReleaseObject(struct I2cMsg * msgs,int16_t msgSize,DevHandle i2cHandle)128 static void ReleaseObject(struct I2cMsg *msgs, int16_t msgSize, DevHandle i2cHandle)
129 {
130 if (msgs != NULL) {
131 if (msgSize == 0 && msgs->buf != NULL) {
132 OsalMemFree(msgs->buf);
133 msgs->buf = NULL;
134 } else if (msgSize == 1 && msgs[0].buf != NULL) {
135 OsalMemFree(msgs[0].buf);
136 msgs[0].buf = NULL;
137 } else if (msgSize >= TFA9879_MSG_SIZE) {
138 if (msgs[0].buf != NULL) {
139 msgs[0].buf = NULL;
140 }
141 if (msgs[1].buf != NULL) {
142 OsalMemFree(msgs[1].buf);
143 msgs[1].buf = NULL;
144 }
145 }
146 msgs = NULL;
147 AUDIO_DEVICE_LOG_DEBUG("OsalMemFree msgBuf success.\n");
148 }
149 // close i2c device
150 if (i2cHandle != NULL) {
151 I2cClose(i2cHandle);
152 i2cHandle = NULL;
153 AUDIO_DEVICE_LOG_DEBUG("I2cClose success.\n");
154 }
155 }
156
Tfa9879FillMsg(const struct Tfa9879RegAttr * regAttr,uint16_t rwFlag,uint8_t * regs,struct I2cMsg * msgs)157 static int Tfa9879FillMsg(const struct Tfa9879RegAttr *regAttr, uint16_t rwFlag,
158 uint8_t *regs, struct I2cMsg *msgs)
159 {
160 uint8_t *msgBuf = NULL;
161 if (rwFlag != 0 && rwFlag != I2C_FLAG_READ) {
162 AUDIO_DEVICE_LOG_ERR("invalid rwFlag value: %d.", rwFlag);
163 return HDF_ERR_INVALID_PARAM;
164 }
165 regs[0] = regAttr->regAddr;
166 msgs[0].addr = g_i2cDevAddr;
167 msgs[0].flags = 0;
168 msgs[0].len = TFA9879_REG_MSGLEN;
169 AUDIO_DEVICE_LOG_DEBUG("msgs[0].addr=0x%02x, regs[0]=0x%02x.", msgs[0].addr, regs[0]);
170 if (rwFlag == 0) { // write
171 // S 11011A2A1 0 A ADDR A MS1 A LS1 A <....> P
172 msgBuf = OsalMemCalloc(TFA9879_REG_MSGLEN);
173 if (msgBuf == NULL) {
174 AUDIO_DEVICE_LOG_ERR("[write]: malloc buf fail!");
175 return HDF_ERR_MALLOC_FAIL;
176 }
177 msgBuf[0] = regs[0];
178 msgBuf[1] = (uint8_t)(regAttr->regValue >> I2C_8BIT); // High 8 bit
179 msgBuf[I2C_MSG_BUF_SIZE] = (uint8_t)(regAttr->regValue & TFA9879_REG_MASK); // Low 8 bit
180 msgs[0].buf = msgBuf;
181 AUDIO_DEVICE_LOG_DEBUG("msgBuf[1]=0x%02x.", msgBuf[1]);
182 AUDIO_DEVICE_LOG_DEBUG("msgBuf[2]=0x%02x.", msgBuf[I2C_MSG_BUF_SIZE]);
183 } else {
184 // S 11011A2A1 0 A ADDR A Sr 11011A2A1 1 A MS1 A LS1 A <....> NA P
185 msgBuf = OsalMemCalloc(I2C_MSG_NUM);
186 if (msgBuf == NULL) {
187 AUDIO_DEVICE_LOG_ERR("[read]: malloc buf fail!");
188 return HDF_ERR_MALLOC_FAIL;
189 }
190 msgs[0].len = 1;
191 msgs[0].buf = regs;
192 msgs[1].addr = g_i2cDevAddr;
193 msgs[1].flags = I2C_FLAG_READ;
194 msgs[1].len = I2C_MSG_NUM;
195 msgs[1].buf = msgBuf;
196 }
197 AUDIO_DEVICE_LOG_DEBUG("fill msg success.\n");
198 return HDF_SUCCESS;
199 }
200
Tfa9879RegRw(struct Tfa9879RegAttr * regAttr,uint16_t rwFlag)201 int Tfa9879RegRw(struct Tfa9879RegAttr *regAttr, uint16_t rwFlag)
202 {
203 int ret;
204 DevHandle i2cHandle;
205 int16_t transferMsgCount = 1;
206 uint8_t regs[I2C_REG_LEN];
207 struct I2cMsg msgs[I2C_MSG_NUM];
208 AUDIO_DEVICE_LOG_DEBUG("entry.\n");
209 if (regAttr == NULL || rwFlag < 0 || rwFlag > 1) {
210 AUDIO_DEVICE_LOG_ERR("invalid parameter.");
211 return HDF_ERR_INVALID_PARAM;
212 }
213 i2cHandle = I2cOpen(I2C_BUS_NUM);
214 if (i2cHandle == NULL) {
215 AUDIO_DEVICE_LOG_ERR("open i2cBus:%u fail! i2cHandle:%p", I2C_BUS_NUM, i2cHandle);
216 return HDF_FAILURE;
217 }
218 if (rwFlag == I2C_FLAG_READ) {
219 transferMsgCount = I2C_MSG_NUM;
220 }
221 ret = Tfa9879FillMsg(regAttr, rwFlag, regs, msgs);
222 if (ret != HDF_SUCCESS) {
223 AUDIO_DEVICE_LOG_ERR("Tfa9879FillMsg failed!");
224 I2cClose(i2cHandle);
225 return HDF_FAILURE;
226 }
227 ret = I2cTransfer(i2cHandle, msgs, transferMsgCount);
228 if (ret != transferMsgCount) {
229 AUDIO_DEVICE_LOG_ERR("I2cTransfer err:%d", ret);
230 ReleaseObject(msgs, transferMsgCount, i2cHandle);
231 return HDF_FAILURE;
232 }
233 if (rwFlag == I2C_FLAG_READ) {
234 regAttr->regValue = (msgs[1].buf[0] << TFA9879_RIGHT_SHIFT) | msgs[1].buf[1]; // result value 16 bit
235 AUDIO_DEVICE_LOG_DEBUG("[read]: regAttr->regValue=0x%04x.\n", regAttr->regValue);
236 }
237 ReleaseObject(msgs, transferMsgCount, i2cHandle);
238 return HDF_SUCCESS;
239 }
240
Tfa9879GetStatus(void)241 static void Tfa9879GetStatus(void)
242 {
243 int ret;
244 int high;
245 int low;
246 struct Tfa9879RegAttr regAttr = {
247 .regAddr = MISCELLANEOUS_STATUS_REG_ADDR,
248 .regValue = 0,
249 };
250 ret = Tfa9879RegRw(®Attr, I2C_FLAG_READ);
251 if (ret != HDF_SUCCESS) {
252 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw fail.");
253 return;
254 }
255 high = regAttr.regValue >> I2C_8BIT; // High 8 bit
256 low = regAttr.regValue & 0xFF; // Low 8 bit
257 AUDIO_DEVICE_LOG_DEBUG("regAttr.regValue=0x%02x%02x. \n", high, low);
258 }
259
260 // get external codec I2S frequency
GetCodecI2sFrequency(struct I2cMsg * msg,uint16_t * fqVal)261 static int GetCodecI2sFrequency(struct I2cMsg *msg, uint16_t *fqVal)
262 {
263 int ret;
264 struct Tfa9879RegAttr regAttr = {
265 .regAddr = SERIAL_INTERFACE_INPUT1_REG_ADDR, // 0x01
266 .regValue = 0,
267 };
268 if (msg == NULL || msg->len < TFA9879_MSG_SIZE || fqVal == NULL) {
269 AUDIO_DEVICE_LOG_ERR("input invalid parameter.");
270 return HDF_ERR_INVALID_PARAM;
271 }
272 if (g_i2cDevAddr == TFA9879_I2C_DEV_ADDR_ADSEL2) {
273 regAttr.regAddr = SERIAL_INTERFACE_INPUT2_REG_ADDR; // 0x03
274 }
275 ret = Tfa9879RegRw(®Attr, I2C_FLAG_READ);
276 if (ret != HDF_SUCCESS) {
277 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw fail.");
278 return HDF_FAILURE;
279 }
280 msg->buf[0] = regAttr.regValue >> I2C_8BIT; // High 8 bit
281 msg->buf[1] = regAttr.regValue & TFA9879_REG_MASK; // Low 8 bit
282 *fqVal = (regAttr.regValue >> 6) & TFA9879_REG_MASK_4; // 01h/03h[9-6]
283 return HDF_SUCCESS;
284 }
285
286 // set external codec I2S frequency
SetCodecI2sFrequency(uint16_t frequencyVal)287 static int SetCodecI2sFrequency(uint16_t frequencyVal)
288 {
289 int ret;
290 uint16_t oldVal;
291 uint16_t mask = 0x3C0;
292 struct I2cMsg oldMsg;
293 struct Tfa9879RegAttr regAttr;
294 // get current value
295 oldMsg.len = I2C_MSG_BUF_SIZE;
296 oldMsg.buf = OsalMemAlloc(I2C_MSG_BUF_SIZE);
297 if (oldMsg.buf == NULL) {
298 AUDIO_DEVICE_LOG_ERR("oldMsg.buf is null.");
299 return HDF_ERR_MALLOC_FAIL;
300 }
301 ret = GetCodecI2sFrequency(&oldMsg, &oldVal);
302 if (ret != HDF_SUCCESS) {
303 AUDIO_DEVICE_LOG_ERR("GetCodecI2sFrequency fail.");
304 ReleaseObject(&oldMsg, 0, NULL);
305 return HDF_FAILURE;
306 }
307 // update current value
308 oldVal = (oldMsg.buf[0] << TFA9879_RIGHT_SHIFT) | oldMsg.buf[1]; // 16 bit
309 regAttr.regAddr = SERIAL_INTERFACE_INPUT1_REG_ADDR;
310 if (g_i2cDevAddr == TFA9879_I2C_DEV_ADDR_ADSEL2) {
311 regAttr.regAddr = SERIAL_INTERFACE_INPUT2_REG_ADDR; // 0x03
312 }
313 regAttr.regValue = ((frequencyVal << 6) & mask) | (oldVal & ~mask); // 00h[6-9]
314 ret = Tfa9879RegRw(®Attr, 0);
315 if (ret != HDF_SUCCESS) {
316 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw failed.");
317 ReleaseObject(&oldMsg, 0, NULL);
318 return HDF_FAILURE;
319 }
320 ReleaseObject(&oldMsg, 0, NULL);
321 AUDIO_DEVICE_LOG_DEBUG("success.\n");
322 return HDF_SUCCESS;
323 }
324
325 // get external codec I2S format
GetCodecI2sFormat(struct I2cMsg * msg,uint16_t * fsVal)326 static int GetCodecI2sFormat(struct I2cMsg *msg, uint16_t *fsVal)
327 {
328 int ret;
329 struct Tfa9879RegAttr regAttr = {
330 .regAddr = SERIAL_INTERFACE_INPUT1_REG_ADDR, // 0x01
331 .regValue = 0,
332 };
333 if (msg == NULL || msg->len < TFA9879_MSG_SIZE || fsVal == NULL) {
334 AUDIO_DEVICE_LOG_ERR("invalid parameter.");
335 return HDF_ERR_INVALID_PARAM;
336 }
337 if (g_i2cDevAddr == TFA9879_I2C_DEV_ADDR_ADSEL2) {
338 regAttr.regAddr = SERIAL_INTERFACE_INPUT2_REG_ADDR; // 0x03
339 }
340 ret = Tfa9879RegRw(®Attr, I2C_FLAG_READ);
341 if (ret != HDF_SUCCESS) {
342 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw is failure.");
343 return HDF_FAILURE;
344 }
345 msg->buf[0] = regAttr.regValue >> I2C_8BIT; // High 8 bit
346 msg->buf[1] = regAttr.regValue & TFA9879_REG_MASK; // Low 8 bit
347 *fsVal = (regAttr.regValue >> 3) & TFA9879_REG_MASK_4; // 01h/03h[3-5]
348 return HDF_SUCCESS;
349 }
350
351 // set external codec I2S format
SetCodecI2sFormat(uint16_t formatVal)352 static int SetCodecI2sFormat(uint16_t formatVal)
353 {
354 int ret;
355 uint16_t oldVal;
356 uint16_t mask = 0x38;
357 struct I2cMsg oldMsg;
358 struct Tfa9879RegAttr regAttr;
359 // get current value
360 oldMsg.len = I2C_MSG_BUF_SIZE;
361 oldMsg.buf = OsalMemAlloc(I2C_MSG_BUF_SIZE);
362 if (oldMsg.buf == NULL) {
363 AUDIO_DEVICE_LOG_ERR("oldMsg.buf is null.");
364 return HDF_ERR_MALLOC_FAIL;
365 }
366 ret = GetCodecI2sFormat(&oldMsg, &oldVal);
367 if (ret != HDF_SUCCESS) {
368 AUDIO_DEVICE_LOG_ERR("GetCodecI2sFormat fail.");
369 ReleaseObject(&oldMsg, 0, NULL);
370 return HDF_FAILURE;
371 }
372 // update current value
373 oldVal = (oldMsg.buf[0] << TFA9879_RIGHT_SHIFT) | oldMsg.buf[1]; // 16 bit
374 regAttr.regAddr = SERIAL_INTERFACE_INPUT1_REG_ADDR;
375 if (g_i2cDevAddr == TFA9879_I2C_DEV_ADDR_ADSEL2) {
376 regAttr.regAddr = SERIAL_INTERFACE_INPUT2_REG_ADDR; // 0x03
377 }
378 regAttr.regValue = ((formatVal << 3) & mask) | (oldVal & ~mask); // 00h[3-5]
379 ret = Tfa9879RegRw(®Attr, 0);
380 if (ret != HDF_SUCCESS) {
381 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw fail.");
382 ReleaseObject(&oldMsg, 0, NULL);
383 return HDF_FAILURE;
384 }
385 ReleaseObject(&oldMsg, 0, NULL);
386 AUDIO_DEVICE_LOG_DEBUG("success.\n");
387 return HDF_SUCCESS;
388 }
389
390 // Init Function
391 /*
392 * gpio0_6 pin init
393 */
Gpio06PinInit(void)394 static int Gpio06PinInit(void)
395 {
396 int ret;
397 const uint16_t gpio = 6;
398 char *regGpioBase = 0;
399 regGpioBase = (void *)OsalIoRemap(HI35XX_I2S_REG_BASE_ADDR, 0x10000);
400 if (regGpioBase == NULL) {
401 AUDIO_DEVICE_LOG_ERR("regGpioBase is null.");
402 return HDF_FAILURE;
403 }
404 SysWritel((uintptr_t)regGpioBase + 0x0034, 0x0400); // GPIO0_6
405 if (regGpioBase != NULL) {
406 OsalIoUnmap(regGpioBase);
407 }
408 AUDIO_DEVICE_LOG_DEBUG("SYS_WRITEL success.");
409 ret = GpioSetDir(gpio, GPIO_DIR_OUT);
410 if (ret != HDF_SUCCESS) {
411 AUDIO_DEVICE_LOG_ERR("%s: set gpio dir fail! ret:%d", __func__, ret);
412 return ret;
413 }
414 ret = GpioWrite(gpio, GPIO_VAL_HIGH);
415 if (ret != HDF_SUCCESS) {
416 AUDIO_DEVICE_LOG_ERR("%s: write gpio val fail! ret:%d", __func__, ret);
417 return ret;
418 }
419 return HDF_SUCCESS;
420 }
421
422 /*
423 * i2c6 init
424 */
I2c6PinInit(void)425 static int I2c6PinInit(void)
426 {
427 char *regI2cBase = 0;
428 regI2cBase = (void *)OsalIoRemap(HI35XX_I2C_REG_BASE_ADDR, 0x10000);
429 if (regI2cBase == NULL) {
430 AUDIO_DEVICE_LOG_ERR("regI2cBase is null.");
431 return HDF_FAILURE;
432 }
433 SysWritel((uintptr_t)regI2cBase + 0x0048, 0x0473); // I2C6_SCL
434 SysWritel((uintptr_t)regI2cBase + 0x004C, 0x0473); // I2C6_SDA
435 if (regI2cBase != NULL) {
436 OsalIoUnmap(regI2cBase);
437 }
438 return HDF_SUCCESS;
439 }
440
441 /*
442 * i2s0 pin init
443 */
I2s0PinMux(const char * regI2sBase)444 static void I2s0PinMux(const char *regI2sBase)
445 {
446 SysWritel((uintptr_t)regI2sBase + 0x0020, 0x673); // I2S_MCLK
447 SysWritel((uintptr_t)regI2sBase + 0x0024, 0x633); // I2S_BCLK_TX
448 SysWritel((uintptr_t)regI2sBase + 0x0028, 0x533); // I2S_WS_TX
449 SysWritel((uintptr_t)regI2sBase + 0x002C, 0x433); // I2S_SD_TX
450 SysWritel((uintptr_t)regI2sBase + 0x0030, 0x533); // I2S_SD_RX
451 }
452
453 /*
454 * i2s init
455 */
I2sPinInit(void)456 static int I2sPinInit(void)
457 {
458 char *regI2sBase = 0;
459 regI2sBase = (void *)OsalIoRemap(HI35XX_I2S_REG_BASE_ADDR, 0x10000);
460 if (regI2sBase == NULL) {
461 AUDIO_DEVICE_LOG_ERR("regI2sBase is null.");
462 return HDF_FAILURE;
463 }
464 I2s0PinMux(regI2sBase);
465 if (regI2sBase != NULL) {
466 OsalIoUnmap(regI2sBase);
467 }
468 return HDF_SUCCESS;
469 }
470
471 /*
472 * init default value
473 */
Tfa9879RegDefaultInit()474 static int Tfa9879RegDefaultInit()
475 {
476 int ret, i;
477 struct Tfa9879RegAttr regAttr;
478 // Set current i2c dev addr
479 g_i2cDevAddr = TFA9879_I2C_DEV_ADDR_ADSEL1;
480 // Set codec control register(00h-14h) default value
481 for (i = 0; i < CTRL_REG_NUM; i++) {
482 regAttr = g_tfa9879RegDefaultAttr[i];
483 AUDIO_DEVICE_LOG_DEBUG("REG = [%02d], Addr = [0x%2x]", i, regAttr.regAddr);
484 ret = Tfa9879RegRw(®Attr, 0);
485 if (ret != HDF_SUCCESS) {
486 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw(write) err, regAttr.regAddr: 0x%02x.\n",
487 regAttr.regAddr);
488 return HDF_FAILURE;
489 }
490 if (i == 0) {
491 OsalMSleep(TFA9879_MUST_SLEEP); // MUST > 5.6 ms
492 }
493 AUDIO_DEVICE_LOG_DEBUG("Tfa9879RegRw success.i=%d", i);
494 OsalMSleep(I2C_WAIT_TIMES);
495 }
496 // WORK
497 regAttr.regAddr = DEVICE_CONTROL_REG_ADDR;
498 regAttr.regValue = 0x09;
499 ret = Tfa9879RegRw(®Attr, 0);
500 if (ret != HDF_SUCCESS) {
501 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw(write) err, regAttr.regAddr: 0x%02x.\n",
502 regAttr.regAddr);
503 return HDF_FAILURE;
504 }
505 Tfa9879GetStatus();
506 AUDIO_DEVICE_LOG_DEBUG("success.\n");
507 return HDF_SUCCESS;
508 }
509
510 /*
511 * codec init
512 */
CodecTfa9879DeviceInit(void)513 static int CodecTfa9879DeviceInit(void)
514 {
515 int ret;
516 AUDIO_DEVICE_LOG_DEBUG("entry.");
517 ret = Gpio06PinInit();
518 if (ret != HDF_SUCCESS) {
519 AUDIO_DEVICE_LOG_ERR("Gpio06PinInit fail.");
520 return HDF_FAILURE;
521 }
522 AUDIO_DEVICE_LOG_DEBUG("Gpio06PinInit success.");
523 ret = I2c6PinInit();
524 if (ret != HDF_SUCCESS) {
525 AUDIO_DEVICE_LOG_ERR("I2c6PinInit fail.");
526 return HDF_FAILURE;
527 }
528 AUDIO_DEVICE_LOG_DEBUG("I2c6PinInit success.");
529 // Initial tfa9879 register
530 ret = Tfa9879RegDefaultInit();
531 if (ret != HDF_SUCCESS) {
532 AUDIO_DEVICE_LOG_ERR("Tfa9879RegDefaultInit fail.");
533 return HDF_FAILURE;
534 }
535 AUDIO_DEVICE_LOG_DEBUG("success.");
536 return HDF_SUCCESS;
537 }
538
539 /* Tfa9879 Special Region End */
540
541 /* ADM Framework Region Begin */
542 static const struct AudioMixerControl g_tfa9879AudioRegParams[] = {
543 {
544 .reg = VOLUME_CONTROL_REG_ADDR, /* output volume */
545 .rreg = VOLUME_CONTROL_REG_ADDR,
546 .shift = 0,
547 .rshift = 0,
548 .min = 0x0,
549 .max = 0xBC,
550 .mask = 0xFF,
551 .invert = 1,
552 }, {
553 .reg = DE_EMPHASIS_REG_ADDR, /* output mute */
554 .rreg = DE_EMPHASIS_REG_ADDR, // hard mute;
555 .shift = MUTE_SHIFT,
556 .rshift = MUTE_SHIFT,
557 .min = 0x0,
558 .max = 0x1,
559 .mask = 0x1,
560 .invert = 0,
561 }, {
562 .reg = SERIAL_INTERFACE_INPUT1_REG_ADDR, /* left or right channel (output) */
563 .rreg = SERIAL_INTERFACE_INPUT1_REG_ADDR,
564 .shift = CHANNEL_SHIFT,
565 .rshift = CHANNEL_SHIFT,
566 .min = 0x0,
567 .max = 0x3,
568 .mask = 0x3,
569 .invert = 0,
570 },
571 };
572
573 static const struct AudioKcontrol g_tfa9879AudioControls[] = {
574 {
575 .iface = AUDIODRV_CTL_ELEM_IFACE_DAC,
576 .name = "Main Playback Volume",
577 .Info = AudioInfoCtrlOps,
578 .Get = AudioAccessoryGetCtrlOps,
579 .Set = AudioAccessorySetCtrlOps,
580 .privateValue = (unsigned long) &g_tfa9879AudioRegParams[0],
581 }, {
582 .iface = AUDIODRV_CTL_ELEM_IFACE_DAC,
583 .name = "Playback Mute",
584 .Info = AudioInfoCtrlOps,
585 .Get = AudioAccessoryGetCtrlOps,
586 .Set = AudioAccessorySetCtrlOps,
587 .privateValue = (unsigned long) &g_tfa9879AudioRegParams[1],
588 }, {
589 .iface = AUDIODRV_CTL_ELEM_IFACE_AIAO,
590 .name = "Render Channel Mode",
591 .Info = AudioInfoCtrlOps,
592 .Get = AudioAccessoryAiaoGetCtrlOps,
593 .Set = AudioAccessoryAiaoSetCtrlOps,
594 .privateValue = (unsigned long) &g_tfa9879AudioRegParams[2],
595 },
596 };
597
AccessoryDeviceInit(struct AudioCard * audioCard,const struct AccessoryDevice * device)598 int32_t AccessoryDeviceInit(struct AudioCard *audioCard, const struct AccessoryDevice *device)
599 {
600 int32_t ret;
601 AUDIO_DEVICE_LOG_DEBUG(" entry.");
602 if ((audioCard == NULL) || (device == NULL)) {
603 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
604 return HDF_ERR_INVALID_OBJECT;
605 }
606 ret = (int32_t)CodecTfa9879DeviceInit();
607 if (ret != HDF_SUCCESS) {
608 AUDIO_DEVICE_LOG_ERR("init tfa9979 device fail.");
609 return HDF_FAILURE;
610 }
611 ret = AudioAddControls(audioCard, g_tfa9879AudioControls, HDF_ARRAY_SIZE(g_tfa9879AudioControls));
612 if (ret != HDF_SUCCESS) {
613 AUDIO_DEVICE_LOG_ERR("add controls fail.");
614 return HDF_FAILURE;
615 }
616 AUDIO_DEVICE_LOG_DEBUG("success.");
617 return HDF_SUCCESS;
618 }
619
TransformGetCtrlResult(uint32_t reg,const uint16_t * resVal)620 static int32_t TransformGetCtrlResult(uint32_t reg, const uint16_t *resVal)
621 {
622 int32_t ret = HDF_SUCCESS;
623 uint8_t hightByte;
624 uint8_t lowByte;
625 if (reg < 0 || resVal == NULL) {
626 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
627 return HDF_ERR_INVALID_OBJECT;
628 }
629 if (reg == VOLUME_CONTROL_REG_ADDR) {
630 hightByte = (*resVal) >> I2C_8BIT; // High 8 bit
631 lowByte = (*resVal) & 0xFF; // Low 8 bit
632 AUDIO_DEVICE_LOG_DEBUG("hightByte=0x%x, lowByte=0x%x.\n", hightByte, lowByte);
633 if (lowByte < VOLUME_MIN && lowByte > MUTE__MAX) {
634 AUDIO_DEVICE_LOG_ERR("fail\n");
635 return HDF_FAILURE;
636 }
637 AUDIO_DEVICE_LOG_DEBUG("resVal=%d.\n", *resVal);
638 }
639 return ret;
640 }
641
AccessoryDeviceReadReg(const struct AccessoryDevice * codec,uint32_t reg,uint32_t * val)642 int32_t AccessoryDeviceReadReg(const struct AccessoryDevice *codec, uint32_t reg, uint32_t *val)
643 {
644 int32_t ret;
645 struct Tfa9879RegAttr regAttr;
646 uint16_t tmpVal;
647 AUDIO_DEVICE_LOG_DEBUG("entry");
648 if (val == NULL) {
649 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
650 return HDF_ERR_INVALID_OBJECT;
651 }
652 (void)codec;
653 regAttr.regAddr = (uint8_t)reg;
654 regAttr.regValue = 0;
655 ret = Tfa9879RegRw(®Attr, I2C_FLAG_READ);
656 if (ret != HDF_SUCCESS) {
657 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw fail.");
658 return HDF_FAILURE;
659 }
660 tmpVal = regAttr.regValue;
661 ret = TransformGetCtrlResult(reg, &tmpVal);
662 if (ret != HDF_SUCCESS) {
663 AUDIO_DEVICE_LOG_ERR("TransformGetCtrlResult fail, reg=0x%x.", reg);
664 return HDF_FAILURE;
665 }
666 *val = tmpVal;
667 AUDIO_DEVICE_LOG_DEBUG("success");
668 return HDF_SUCCESS;
669 }
670
TransformSetCtrlVal(uint32_t reg,uint16_t * val)671 static int32_t TransformSetCtrlVal(uint32_t reg, uint16_t *val)
672 {
673 int32_t ret = HDF_SUCCESS;
674 uint8_t hightByte;
675 uint8_t lowByte;
676 if (reg < 0 || val == NULL) {
677 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
678 return HDF_ERR_INVALID_OBJECT;
679 }
680 if (reg == VOLUME_CONTROL_REG_ADDR) {
681 hightByte = (*val) >> I2C_8BIT; // High 8 bit
682 lowByte = (*val) & 0xFF; // Low 8 bit
683 AUDIO_DEVICE_LOG_DEBUG("hightByte=0x%x, lowByte=0x%x.\n", hightByte, lowByte);
684 *val = (hightByte << TFA9879_RIGHT_SHIFT) | lowByte;
685 AUDIO_DEVICE_LOG_DEBUG("val=%d.\n", *val);
686 }
687 return ret;
688 }
689
AccessoryDeviceWriteReg(const struct AccessoryDevice * codec,uint32_t reg,uint32_t value)690 int32_t AccessoryDeviceWriteReg(const struct AccessoryDevice *codec, uint32_t reg, uint32_t value)
691 {
692 int32_t ret;
693 struct Tfa9879RegAttr regAttr;
694 uint16_t tmpVal;
695 AUDIO_DEVICE_LOG_DEBUG("entry");
696 (void)codec;
697 tmpVal = (uint16_t)value;
698 ret = TransformSetCtrlVal(reg, &tmpVal);
699 if (ret != HDF_SUCCESS) {
700 AUDIO_DEVICE_LOG_ERR("TransformSetCtrlVal fail, reg=0x%x.", reg);
701 return HDF_FAILURE;
702 }
703 regAttr.regAddr = (uint8_t)reg;
704 regAttr.regValue = tmpVal;
705 ret = Tfa9879RegRw(®Attr, 0);
706 if (ret != HDF_SUCCESS) {
707 AUDIO_DEVICE_LOG_ERR("Tfa9879RegRw fail.");
708 return HDF_FAILURE;
709 }
710 AUDIO_DEVICE_LOG_DEBUG("success");
711 return HDF_SUCCESS;
712 }
713
AccessoryAiaoDeviceReadReg(const struct AccessoryDevice * codec,uint32_t reg,uint32_t * val)714 int32_t AccessoryAiaoDeviceReadReg(const struct AccessoryDevice *codec, uint32_t reg, uint32_t *val)
715 {
716 int32_t ret;
717 ret = AccessoryDeviceReadReg(codec, reg, val);
718 if (ret != HDF_SUCCESS) {
719 AUDIO_DEVICE_LOG_ERR("AccessoryDeviceReadReg fail, reg=0x%x.", reg);
720 return HDF_FAILURE;
721 }
722 AUDIO_DEVICE_LOG_DEBUG("success");
723 return HDF_SUCCESS;
724 }
725
AccessoryAiaoDeviceWriteReg(const struct AccessoryDevice * codec,uint32_t reg,uint32_t value)726 int32_t AccessoryAiaoDeviceWriteReg(const struct AccessoryDevice *codec, uint32_t reg, uint32_t value)
727 {
728 int32_t ret;
729 AUDIO_DEVICE_LOG_DEBUG("entry");
730 ret = AccessoryDeviceWriteReg(codec, reg, value);
731 if (ret != HDF_SUCCESS) {
732 AUDIO_DEVICE_LOG_ERR("AccessoryDeviceWriteReg fail.");
733 return HDF_FAILURE;
734 }
735 AUDIO_DEVICE_LOG_DEBUG("success");
736 return HDF_SUCCESS;
737 }
738
AccessoryDaiStartup(const struct AudioCard * card,const struct DaiDevice * device)739 int32_t AccessoryDaiStartup(const struct AudioCard *card, const struct DaiDevice *device)
740 {
741 (void)card;
742 (void)device;
743 return HDF_SUCCESS;
744 }
745
AccessoryDaiHwParams(const struct AudioCard * card,const struct AudioPcmHwParams * param,const struct DaiDevice * device)746 int32_t AccessoryDaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param,
747 const struct DaiDevice *device)
748 {
749 int ret;
750 uint16_t frequency, bitWidth;
751 (void)card;
752 (void)device;
753 AUDIO_DEVICE_LOG_DEBUG("entry.");
754 if (param == NULL || param->cardServiceName == NULL) {
755 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
756 return HDF_ERR_INVALID_PARAM;
757 }
758 ret = I2sPinInit();
759 if (ret != HDF_SUCCESS) {
760 AUDIO_DEVICE_LOG_ERR("I2sPinInit fail.");
761 }
762 ret = RateToFrequency(param->rate, &frequency);
763 if (ret != HDF_SUCCESS) {
764 AUDIO_DEVICE_LOG_ERR("RateToFrequency fail.");
765 return HDF_ERR_NOT_SUPPORT;
766 }
767 ret = FormatToBitWidth(param->format, &bitWidth);
768 if (ret != HDF_SUCCESS) {
769 AUDIO_DEVICE_LOG_ERR("FormatToBitWidth fail.");
770 return HDF_ERR_NOT_SUPPORT;
771 }
772 ret = SetCodecI2sFrequency(frequency);
773 if (ret != HDF_SUCCESS) {
774 AUDIO_DEVICE_LOG_ERR("SetCodecI2sFs fail.");
775 return HDF_FAILURE;
776 }
777 ret = SetCodecI2sFormat(bitWidth);
778 if (ret != HDF_SUCCESS) {
779 AUDIO_DEVICE_LOG_ERR("SetCodecI2sFormat fail.");
780 return HDF_FAILURE;
781 }
782 AUDIO_DEVICE_LOG_DEBUG("channels = %d, rate = %d, periodSize = %d, \
783 periodCount = %d, format = %d, cardServiceName = %s \n",
784 param->channels, param->rate, param->periodSize,
785 param->periodCount, (uint32_t)param->format, param->cardServiceName);
786 AUDIO_DEVICE_LOG_DEBUG("success.");
787 return HDF_SUCCESS;
788 }
789
AccessoryDaiDeviceInit(const struct AudioCard * card,const struct DaiDevice * device)790 int32_t AccessoryDaiDeviceInit(const struct AudioCard *card, const struct DaiDevice *device)
791 {
792 if (device == NULL || device->devDaiName == NULL) {
793 AUDIO_DEVICE_LOG_ERR("input para is NULL.");
794 return HDF_FAILURE;
795 }
796 AUDIO_DEVICE_LOG_DEBUG("codec dai device name: %s\n", device->devDaiName);
797 (void)card;
798 return HDF_SUCCESS;
799 }
800
801