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.

341 lines
11 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2019-2019. All rights reserved.
* Description: amp device and driver rt5512
* Author: audio
* Create: 2021-3-19
* Notes: smart pa of rt5512
*/
#include <linux/slab.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 ENDTBL_FLAG 0xff
#define MAX_AMP_REG_LEN 20
#define AMP_FIVEMS_DELAY 5
#define AMP_TENMS_DELAY 10
#define AMP_TWENTYMS_DELAY 20
#define AMP_MAX_REG_NUM 0xB7
#define AMP_BYTES_PER_REG 2
#define AMP_MUTE_REG 0x03
#define AMP_MAX_INIT_REG_NUM 60 /* Max registers need to configue for init */
typedef enum {
PA_NUM_1 = 1,
PA_NUM_2 = 2,
PA_NUM_4 = 4,
PA_NUM_MAX
} rt5512_pa_num;
static drv_amp_reg_map g_rt5512_init_reg[PA_NUM_2][AMP_MAX_INIT_REG_NUM] = {
{ { 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x03, 2, { 0x00, 0x80 }, 20},
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x04, 2, { 0x00, 0xff } },
{ 0x10, 2, { 0x00, 0x13 } },
{ 0x12, 2, { 0x00, 0x0a } },
{ 0x68, 2, { 0x00, 0x0d } },
{ 0x69, 2, { 0x00, 0x02 } },
{ 0x6c, 2, { 0x00, 0x10 } },
{ 0x6d, 2, { 0x00, 0x08 } },
{ 0x30, 2, { 0x00, 0x0d } },
{ 0xa7, 2, { 0x0a, 0x84 } },
{ 0x20, 2, { 0x00, 0xa2 } },
{ 0x8b, 2, { 0x00, 0x40 } },
{ 0x74, 2, { 0x00, 0x1a } },
{ 0x38, 2, { 0x9b, 0xeb } },
{ 0x39, 2, { 0x8b, 0xac } },
{ 0x3a, 2, { 0x7e, 0x7d } },
{ 0x3b, 2, { 0x73, 0x95 } },
{ 0x3c, 2, { 0x6a, 0x68 } },
{ 0x3d, 2, { 0x62, 0x95 } },
{ 0x3e, 2, { 0x5b, 0xd4 } },
{ 0xad, 2, { 0x40, 0xf7 } },
{ 0x41, 2, { 0x00, 0x2f } },
{ 0x49, 2, { 0x04, 0x95 } },
{ 0x46, 2, { 0x00, 0x1d } },
{ 0x45, 2, { 0x52, 0x52 } },
{ 0x98, 2, { 0x8b, 0x9c } },
{ 0xa2, 2, { 0x20, 0x0c } },
{ 0xae, 2, { 0x20, 0x56 } },
{ 0xa5, 2, { 0x66, 0x12 } },
{ 0x70, 2, { 0x00, 0x21 } },
{ 0xa6, 2, { 0x31, 0x35 } },
{ 0xb3, 2, { 0x91, 0x03 } },
{ 0xb1, 2, { 0xa5, 0xaa } },
{ 0xb0, 2, { 0xd5, 0xa5 } },
{ 0x78, 2, { 0x00, 0xf2 } },
{ 0x9d, 2, { 0x00, 0xfc } },
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x04, 2, { 0x00, 0xff } },
{ 0xb5, 2, { 0xff, 0xfc } },
{ 0x40, 2, { 0x0f, 0x5c } },
{ 0xb5, 2, { 0x00, 0x00 } },
{ 0x60, 2, { 0x00, 0xa5 } },
{ 0x03, 2, { 0x00, 0x01 } },
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x12, 2, { 0x00, 0x0a } },
{ 0xb5, 2, { 0xf9, 0xfc } },
{ 0x60, 2, { 0x00, 0xa4 }, 2},
{ 0xb6, 2, { 0xf8, 0xef } },
{ 0x51, 2, { 0x00, 0x5a } },
{ 0x40, 2, { 0x0f, 0x5f }, 1},
{ 0x98, 2, { 0x89, 0x9c } },
{ 0xb5, 2, { 0xf9, 0xfd } },
{ 0x03, 2, { 0x00, 0x04 }, 21},
{ 0x98, 2, { 0x8b, 0x9c } },
{ 0xb5, 2, { 0xff, 0xfd } },
{ 0x04, 2, { 0x00, 0x30 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } }, /* End of PA1 */
{ { 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x03, 2, { 0x00, 0x80 }, 20},
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x04, 2, { 0x00, 0xff } },
{ 0x10, 2, { 0x00, 0x13 } },
{ 0x12, 2, { 0x00, 0x92 } },
{ 0x68, 2, { 0x00, 0x0d } },
{ 0x69, 2, { 0x00, 0x02 } },
{ 0x6c, 2, { 0x00, 0x10 } },
{ 0x6d, 2, { 0x00, 0x08 } },
{ 0x30, 2, { 0x00, 0x0d } },
{ 0xa7, 2, { 0x0a, 0x84 } },
{ 0x20, 2, { 0x00, 0xa2 } },
{ 0x8b, 2, { 0x00, 0x40 } },
{ 0x74, 2, { 0x00, 0x1a } },
{ 0x38, 2, { 0x9b, 0xeb } },
{ 0x39, 2, { 0x8b, 0xac } },
{ 0x3a, 2, { 0x7e, 0x7d } },
{ 0x3b, 2, { 0x73, 0x95 } },
{ 0x3c, 2, { 0x6a, 0x68 } },
{ 0x3d, 2, { 0x62, 0x95 } },
{ 0x3e, 2, { 0x5b, 0xd4 } },
{ 0xad, 2, { 0x40, 0xf7 } },
{ 0x41, 2, { 0x00, 0x2f } },
{ 0x49, 2, { 0x04, 0x95 } },
{ 0x46, 2, { 0x00, 0x1d } },
{ 0x45, 2, { 0x52, 0x52 } },
{ 0x98, 2, { 0x8b, 0x9c } },
{ 0xa2, 2, { 0x20, 0x0c } },
{ 0xae, 2, { 0x20, 0x56 } },
{ 0xa5, 2, { 0x66, 0x12 } },
{ 0x70, 2, { 0x00, 0x21 } },
{ 0xa6, 2, { 0x31, 0x35 } },
{ 0xb3, 2, { 0x91, 0x03 } },
{ 0xb1, 2, { 0xa5, 0xaa } },
{ 0xb0, 2, { 0xd5, 0xa5 } },
{ 0x78, 2, { 0x00, 0xf2 } },
{ 0x9d, 2, { 0x00, 0xfc } },
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x04, 2, { 0x00, 0xff } },
{ 0xb5, 2, { 0xff, 0xfc } },
{ 0x40, 2, { 0x0f, 0x5c } },
{ 0xb5, 2, { 0x00, 0x00 } },
{ 0x60, 2, { 0x00, 0xa5 } },
{ 0x03, 2, { 0x00, 0x01 } },
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x12, 2, { 0x00, 0x8a } },
{ 0xb5, 2, { 0xf9, 0xfc } },
{ 0x60, 2, { 0x00, 0xa4 }, 2},
{ 0xb6, 2, { 0xf8, 0xef } },
{ 0x51, 2, { 0x00, 0x5a } },
{ 0x40, 2, { 0x0f, 0x5f }, 1},
{ 0x98, 2, { 0x89, 0x9c } },
{ 0xb5, 2, { 0xf9, 0xfd } },
{ 0x03, 2, { 0x00, 0x04 }, 21},
{ 0x98, 2, { 0x8b, 0x9c } },
{ 0xb5, 2, { 0xff, 0xfd } },
{ 0x04, 2, { 0x00, 0x30 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } } /* End of PA2 */
};
static drv_amp_reg_map g_rt5512_power_on_reg[PA_NUM_2][AMP_MAX_INIT_REG_NUM] = {
{ { 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x12, 2, { 0x00, 0x0a } },
{ 0xb5, 2, { 0xf9, 0xfc } },
{ 0x60, 2, { 0x00, 0xa4 }, 2},
{ 0xb6, 2, { 0xf8, 0xef } },
{ 0x51, 2, { 0x00, 0x5a } },
{ 0x40, 2, { 0x0f, 0x5f }, 1},
{ 0x98, 2, { 0x89, 0x9c } },
{ 0xb5, 2, { 0xf9, 0xfd } },
{ 0x03, 2, { 0x00, 0x04 }, 21},
{ 0x98, 2, { 0x8b, 0x9c } },
{ 0xb5, 2, { 0xff, 0xfd } },
{ 0x04, 2, { 0x00, 0x30 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } }, /* End of PA1 */
{ { 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x12, 2, { 0x00, 0x8a } },
{ 0xb5, 2, { 0xf9, 0xfc } },
{ 0x60, 2, { 0x00, 0xa4 }, 2},
{ 0xb6, 2, { 0xf8, 0xef } },
{ 0x51, 2, { 0x00, 0x5a } },
{ 0x40, 2, { 0x0f, 0x5f }, 1},
{ 0x98, 2, { 0x89, 0x9c } },
{ 0xb5, 2, { 0xf9, 0xfd } },
{ 0x03, 2, { 0x00, 0x04 }, 21},
{ 0x98, 2, { 0x8b, 0x9c } },
{ 0xb5, 2, { 0xff, 0xfd } },
{ 0x04, 2, { 0x00, 0x30 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } } /* End of PA2 */
};
static drv_amp_reg_map g_rt5512_power_off_reg[PA_NUM_2][AMP_MAX_INIT_REG_NUM] = {
{ { 0x04, 2, { 0x00, 0xff } },
{ 0x03, 2, { 0x00, 0x06 }, 1},
{ 0xb5, 2, { 0xc0, 0x00 }, 2},
{ 0x40, 2, { 0x0f, 0x5f } },
{ 0x41, 2, { 0x00, 0x2f }, 32},
{ 0x03, 2, { 0x00, 0x02 }, 1},
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x12, 2, { 0x00, 0x13 } },
{ 0xb5, 2, { 0x00, 0x00 }, 1},
{ 0x40, 2, { 0x0f, 0x5c }, 1},
{ 0xb5, 2, { 0x00, 0x00 } },
{ 0x60, 2, { 0x00, 0xa5 } },
{ 0x03, 2, { 0x00, 0x01 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } }, /* End of PA1 */
{ { 0x04, 2, { 0x00, 0xff } },
{ 0x03, 2, { 0x00, 0x06 }, 1},
{ 0xb5, 2, { 0xc0, 0x00 }, 2},
{ 0x40, 2, { 0x0f, 0x5f } },
{ 0x41, 2, { 0x00, 0x2f }, 32},
{ 0x03, 2, { 0x00, 0x02 }, 1},
{ 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x12, 2, { 0x00, 0x93 } },
{ 0xb5, 2, { 0x00, 0x00 }, 1},
{ 0x40, 2, { 0x0f, 0x5c }, 1},
{ 0xb5, 2, { 0x00, 0x00 } },
{ 0x60, 2, { 0x00, 0xa5 } },
{ 0x03, 2, { 0x00, 0x01 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } } /* End of PA2 */
};
static drv_amp_reg_map g_rt5512_deinit_reg[PA_NUM_2][AMP_MAX_INIT_REG_NUM] = {
{ { 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x04, 2, { 0x00, 0xff } },
{ 0xb5, 2, { 0xff, 0xfc } },
{ 0x40, 2, { 0x0f, 0x5c } },
{ 0xb5, 2, { 0x00, 0x00 } },
{ 0x60, 2, { 0x00, 0xa5 } },
{ 0x03, 2, { 0x00, 0x01 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } }, /* End of PA1 */
{ { 0x03, 2, { 0x00, 0x00 }, 2},
{ 0x04, 2, { 0x00, 0xff } },
{ 0xb5, 2, { 0xff, 0xfc } },
{ 0x40, 2, { 0x0f, 0x5c } },
{ 0xb5, 2, { 0x00, 0x00 } },
{ 0x60, 2, { 0x00, 0xa5 } },
{ 0x03, 2, { 0x00, 0x01 } },
{ ENDTBL_FLAG, 0x01, { 0x00 } } } /* End of PA2 */
};
static td_s32 rt5512_init(const amp_platform_device *dev)
{
osal_msleep(AMP_TWENTYMS_DELAY);
if ((dev->mute_gpio_config == TD_FALSE) || (dev->reset_gpio_config == TD_FALSE)) {
drv_amp_dev_hw_reset(dev, TD_TRUE);
/* release reset AMP */
drv_amp_dev_hw_reset(dev, TD_FALSE);
osal_msleep(AMP_TENMS_DELAY);
}
drv_amp_dev_write_reg_map(dev, g_rt5512_init_reg[dev->dev_id]);
return TD_SUCCESS;
}
static td_void rt5512_deinit(const amp_platform_device *dev)
{
drv_amp_dev_write_reg_map(dev, g_rt5512_power_off_reg[dev->dev_id]);
drv_amp_dev_write_reg_map(dev, g_rt5512_deinit_reg[dev->dev_id]);
}
static td_s32 rt5512_set_mute(const amp_platform_device *dev, amp_channel_type channel_type, td_bool mute)
{
if (mute == TD_TRUE) {
drv_amp_dev_write_reg_map(dev, g_rt5512_power_off_reg[dev->dev_id]);
} else {
drv_amp_dev_write_reg_map(dev, g_rt5512_power_on_reg[dev->dev_id]);
}
return TD_SUCCESS;
}
static td_s32 rt5512_get_mute(const amp_platform_device *dev, amp_channel_type channel_type, td_bool *mute)
{
td_s32 ret;
td_u8 gain[AMP_BYTES_PER_REG] = {0};
if (mute == TD_NULL) {
return SOC_ERR_AMP_NULL_PTR;
}
ret = amp_osal_i2c_read(&dev->i2c, AMP_MUTE_REG, gain, AMP_BYTES_PER_REG);
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[0] & 0x02;
} else {
/* need add by custom */
}
return TD_SUCCESS;
}
static td_void rt5512_dump_reg(const amp_platform_device *dev, td_void *file)
{
int i;
drv_amp_reg_map *reg_table = (drv_amp_reg_map *)osal_vmalloc(sizeof(drv_amp_reg_map) * AMP_MAX_REG_NUM);
if (reg_table == TD_NULL) {
return;
}
for (i = 0; i < AMP_MAX_REG_NUM; i++) {
(reg_table + i)->addr = i;
(reg_table + i)->size = AMP_BYTES_PER_REG;
}
drv_amp_dev_dump_reg_map(dev, file, reg_table);
osal_vfree(reg_table);
}
static amp_platform_driver g_rt5512_driver = {
.name = "RT5512",
.dev_type = EXT_DRV_AMP_RT5512,
.deinit = rt5512_deinit,
.init = rt5512_init,
.get_mute = rt5512_get_mute,
.set_mute = rt5512_set_mute,
.hw_mute = TD_NULL,
.reset = TD_NULL,
.get_active = TD_NULL,
.dump_reg = rt5512_dump_reg,
};
td_s32 rt5512_register_driver(td_void)
{
return amp_platform_driver_register(&g_rt5512_driver);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */