/* * 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 #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 */