You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
8.4 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2019-2019. All rights reserved.
* Description: amp device and driver tas5711
* Author: audio
* Create: 2019-05-30
*/
#include "osal_ext.h"
#include "soc_errno.h"
#include "drv_amp_debug.h"
#include "drv_amp_osal.h"
#include "drv_amp_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define TAS5711_MAX_VOL 0x05
#define TAS5711_MIN_VOL 0xff /* mute */
static drv_amp_reg_map g_tas5711_init_reg[] = {
{ 0x1B, 1, { 0x00 } },
{ 0x06, 1, { 0x00 } },
{ 0x0A, 1, { 0xff } },
{ 0x09, 1, { 0x30 } },
{ 0x08, 1, { 0x30 } }, /* to avoid the abnormal of speaker */
/* IC delay */
{ 0x14, 1, { 0x54 } },
{ 0x13, 1, { 0xAC } },
{ 0x12, 1, { 0x54 } },
{ 0x11, 1, { 0xAC } },
{ 0x0E, 1, { 0xD1 } },
{ 0x1A, 1, { 0x95 } },
{ 0x20, 4, { 0x00, 0x89, 0x77, 0x72 } }, /* CH1/CH2 BD mode */
{ 0x21, 4, { 0x00, 0x00, 0x42, 0x03 } },
{ 0x10, 1, { 0x02 } },
{ 0x10, 1, { 0x02 } },
{ 0x1C, 1, { 0x02 } },
{ 0x19, 1, { 0x30 } },
{ 0x25, 4, { 0x01, 0x02, 0x31, 0x45 } },
{ 0x50, 4, { 0x00, 0x00, 0x00, 0x00 } },
/* BQ */
{ 0x29, 0x14, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ 0x2A, 0x14, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ 0x2B, 0x14, { 0x00, 0x7E, 0xCB, 0x2F, 0x0F, 0x02, 0x69, 0xA1, 0x00,
0x7E, 0xCB, 0x2F, 0x00, 0xFD, 0x90, 0x9B, 0x0F, 0x82, 0x63, 0xDD } },
{ 0x2C, 0x14, { 0x00, 0x7F, 0x9C, 0x79, 0x0F, 0x02, 0x3E, 0x2E, 0x00,
0x7E, 0x48, 0x26, 0x00, 0xFD, 0xC1, 0xD2, 0x0F, 0x82, 0x1B, 0x61 } },
{ 0x2D, 0x14, { 0x00, 0x7F, 0x83, 0xD8, 0x0F, 0x03, 0x2B, 0xB8, 0x00,
0x7D, 0xDB, 0x4F, 0x00, 0xFC, 0xD4, 0x48, 0x0F, 0x82, 0xA0, 0xD8 } },
{ 0x2E, 0x14, { 0x00, 0x8B, 0x96, 0xE3, 0x0F, 0x2C, 0xCE, 0xB5, 0x00,
0x56, 0xA0, 0xE1, 0x00, 0xD3, 0x31, 0x4B, 0x0F, 0x9D, 0xC8, 0x3B } },
{ 0x2F, 0x14, { 0x00, 0x8C, 0x10, 0xAF, 0x0F, 0x64, 0x3A, 0xF0, 0x00,
0x4A, 0xAD, 0xC6, 0x00, 0x9B, 0xC5, 0x10, 0x0F, 0xA9, 0x41, 0x8A } },
{ 0x58, 0x14, { 0x00, 0x8C, 0x6B, 0xCE, 0x0F, 0xAE, 0x49, 0x6D, 0x00,
0x49, 0x1B, 0x11, 0x00, 0x51, 0xB6, 0x93, 0x0F, 0xAA, 0x79, 0x20 } },
{ 0x59, 0x14, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ 0x30, 0x14, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ 0x31, 0x14, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ 0x32, 0x14, { 0x00, 0x7E, 0xCB, 0x2F, 0x0F, 0x02, 0x69, 0xA1, 0x00,
0x7E, 0xCB, 0x2F, 0x00, 0xFD, 0x90, 0x9B, 0x0F, 0x82, 0x63, 0xDD } },
{ 0x33, 0x14, { 0x00, 0x7F, 0x9C, 0x79, 0x0F, 0x02, 0x3E, 0x2E, 0x00,
0x7E, 0x48, 0x26, 0x00, 0xFD, 0xC1, 0xD2, 0x0F, 0x82, 0x1B, 0x61 } },
{ 0x34, 0x14, { 0x00, 0x7F, 0x83, 0xD8, 0x0F, 0x03, 0x2B, 0xB8, 0x00,
0x7D, 0xDB, 0x4F, 0x00, 0xFC, 0xD4, 0x48, 0x0F, 0x82, 0xA0, 0xD8 } },
{ 0x35, 0x14, { 0x00, 0x8B, 0x96, 0xE3, 0x0F, 0x2C, 0xCE, 0xB5, 0x00,
0x56, 0xA0, 0xE1, 0x00, 0xD3, 0x31, 0x4B, 0x0F, 0x9D, 0xC8, 0x3B } },
{ 0x36, 0x14, { 0x00, 0x8C, 0x10, 0xAF, 0x0F, 0x64, 0x3A, 0xF0, 0x00,
0x4A, 0xAD, 0xC6, 0x00, 0x9B, 0xC5, 0x10, 0x0F, 0xA9, 0x41, 0x8A } },
{ 0x5C, 0x14, { 0x00, 0x8C, 0x6B, 0xCE, 0x0F, 0xAE, 0x49, 0x6D, 0x00,
0x49, 0x1B, 0x11, 0x00, 0x51, 0xB6, 0x93, 0x0F, 0xAA, 0x79, 0x20 } },
{ 0x5D, 0x14, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
/* subchanel BQ */
{ 0x5A, 0x14, { 0x00, 0x7F, 0x0E, 0x38, 0x0F, 0x01, 0xE3, 0x90, 0x00,
0x7F, 0x0E, 0x38, 0x00, 0xFE, 0x1A, 0xA7, 0x0F, 0x81, 0xE1, 0xC8 } },
{ 0x5B, 0x14, { 0x00, 0x00, 0x10, 0xA7, 0x00, 0x00, 0x21, 0x4E, 0x00,
0x00, 0x10, 0xA7, 0x00, 0xF7, 0xB5, 0x4D, 0x0F, 0x88, 0x08, 0x17 } },
/* DRC1 */
{ 0x3A, 8, { 0x00, 0x05, 0x39, 0x47, 0x00, 0x7A, 0xC6, 0xB8 } },
{ 0x3B, 8, { 0x00, 0x05, 0x39, 0x47, 0x00, 0x7A, 0xC6, 0xB8 } },
{ 0x3C, 8, { 0x00, 0x00, 0x00, 0xF9, 0x00, 0x7F, 0xFF, 0x06 } },
{ 0x40, 4, { 0xFD, 0xA2, 0x14, 0x90 } },
{ 0x41, 4, { 0x0F, 0x81, 0x47, 0xAF } },
{ 0x42, 4, { 0x00, 0x08, 0x42, 0x10 } },
/* DRC2 */
{ 0x39, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
{ 0x3D, 8, { 0x00, 0x05, 0x39, 0x47, 0x00, 0x7A, 0xC6, 0xB8 } },
{ 0x3E, 8, { 0x00, 0x05, 0x39, 0x47, 0x00, 0x7A, 0xC6, 0xB8 } },
{ 0x3F, 8, { 0x00, 0x00, 0x00, 0xF9, 0x00, 0x7F, 0xFF, 0x06 } },
{ 0x43, 4, { 0xFD, 0x8C, 0xD1, 0xEA } }, /* -5.5d_b */
{ 0x44, 4, { 0x0F, 0x84, 0x44, 0x44 } },
{ 0x45, 4, { 0x00, 0x08, 0x42, 0x10 } },
{ 0x46, 4, { 0x00, 0x00, 0x00, 0x03 } }, /* 0x03 */
{ 0x07, 1, { 0x10 } }, /* 0xFF}}, */
{ 0x05, 1, { 0x80 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } }
};
static td_void tas5711_write_reg_map(const amp_platform_device *dev,
drv_amp_reg_map *reg_map)
{
td_s32 ret;
td_u32 addr;
td_u32 size;
td_u8 *reg = TD_NULL;
while (1) {
if ((reg_map == TD_NULL) || (reg_map->addr == ENDTBL_FLAG)) {
return;
}
addr = reg_map->addr;
reg = reg_map->reg;
size = reg_map->size;
ret = amp_osal_i2c_write(&dev->i2c, addr, reg, size);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(amp_osal_i2c_write, ret);
return;
}
/* 0x1B:oscillator trim, 0x46:DRC control, 0x50:EQ control, 0xF9:I2C device addr */
if ((addr == 0x1B) || (addr == 0x46) || (addr == 0x50) || (addr == 0xF9)) {
osal_msleep(DELAY_50_MS);
}
/* BQ1-BQ4 */
if ((addr >= 0x29) && (addr <= 0x36)) {
osal_msleep(DELAY_05_MS);
}
if ((addr >= 0x58) && (addr <= 0x5D)) {
osal_msleep(DELAY_05_MS);
}
reg_map++;
}
}
static td_s32 tas5711_set_mute(const amp_platform_device *dev, amp_channel_type channel_type, td_bool mute)
{
td_s32 ret;
td_u8 gain;
gain = (mute == TD_TRUE) ? TAS5711_MIN_VOL : TAS5711_MAX_VOL;
if (channel_type == AMP_CHANNEL_TYPE_ALL) {
/* need add by custom */
}
/* 0x07: mute register addr */
ret = amp_osal_i2c_write(&dev->i2c, 0x07, &gain, 1);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(amp_osal_i2c_write, ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 tas5711_get_mute(const amp_platform_device *dev, amp_channel_type channel_type, td_bool *mute)
{
td_s32 ret;
td_u8 gain = 0;
if (mute == TD_NULL) {
return SOC_ERR_AMP_NULL_PTR;
}
/* 0x07: mute register addr */
ret = amp_osal_i2c_read(&dev->i2c, 0x07, &gain, 1);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(amp_osal_i2c_read, ret);
return ret;
}
if (channel_type == AMP_CHANNEL_TYPE_ALL) {
*mute = (gain == TAS5711_MIN_VOL);
} else {
/* need add by custom */
}
return TD_SUCCESS;
}
static td_void tas5711_deinit(const amp_platform_device *dev)
{
drv_amp_dev_hw_reset(dev, TD_TRUE);
}
static td_s32 tas5711_init(const amp_platform_device *dev)
{
td_s32 ret;
ret = tas5711_set_mute(dev, AMP_CHANNEL_TYPE_ALL, TD_TRUE);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(tas5711_set_mute, ret);
return ret;
}
drv_amp_dev_hw_mute(dev, TD_FALSE);
osal_msleep(DELAY_10_MS);
drv_amp_dev_hw_reset(dev, TD_TRUE);
osal_msleep(DELAY_10_MS);
/* release reset AMP */
drv_amp_dev_hw_reset(dev, TD_FALSE);
tas5711_write_reg_map(dev, g_tas5711_init_reg);
return TD_SUCCESS;
}
static amp_platform_driver g_tas5711_driver = {
.name = "TAS5711",
.dev_type = AMP_DEV_TAS5711,
.deinit = tas5711_deinit,
.init = tas5711_init,
.get_mute = tas5711_get_mute,
.set_mute = tas5711_set_mute,
.hw_mute = drv_amp_dev_hw_mute,
.reset = TD_NULL,
.get_active = TD_NULL,
.dump_reg = TD_NULL,
};
td_s32 tas5711_register_driver(td_void)
{
return amp_platform_driver_register(&g_tas5711_driver);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */