/* * Copyright (c) Hisilicon Technologies Co., Ltd.. 2019-2019. All rights reserved. * Description: amp device and driver ad82010 * 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 #define AD82010_MAX_VOL 0x10 /* un_mute */ #define AD82010_MIN_VOL 0x1e /* mute */ #define AD82010_MUTE_REGISTER 0x02 /* master mute channel mute */ #define AD82010_RESET_REGISTER 0x02 /* master reset channel mute */ #define AD82010_NORMAL_REG_SIZE 1 /* Register size for Mute is 1 Byte */ #define AD82010_DRC_REGISTER 0x07 #define AD82010_DRC_MASK 0x12 static drv_amp_reg_map g_ad82010_init_reg[] = { { 0x00, 0x01, { 0x01 } }, /* noise gate enable (NGE) */ { 0x01, 0x01, { 0x81 } }, /* BCLK system enable (BCLK_SEL) */ { 0x02, 0x01, { 0x10 } }, /* software reset (SW_RSTB) */ { 0x03, 0x01, { 0x00 } }, /* master volume control , 12d_b */ { 0x04, 0x01, { 0x00 } }, /* channel 1 volume , 12d_b */ { 0x05, 0x01, { 0x00 } }, /* channel 2 volume , 12d_b */ { 0x06, 0x01, { 0x22 } }, /* enable HV under voltage circuit */ { 0x07, 0x01, { 0x36 } }, /* enable CH1/CH2 power limit and power clipping (DRC) */ { 0x08, 0x01, { 0x6a } }, /* DRC attack rate = 0.4528 db/ms &DRC release rate = 0.0147 db/ms */ { 0x09, 0x01, { 0xe0 } }, /* quaternary_and_ternary_switching_level */ { 0x0A, 0x01, { 0x00 } }, /* reserved */ { 0x0B, 0x01, { 0x00 } }, /* setting_of_oc */ { 0x0C, 0x01, { 0x36 } }, /* error_message_delay_time_selection */ { 0x0D, 0x01, { 0x00 } }, /* protection_circuit_disable_&_power-down */ { 0x0E, 0x01, { 0x00 } }, /* test-mode_enabled */ { 0x0F, 0x01, { 0x00 } }, /* pwm_control */ { 0x10, 0x03, { 0x20, 0x00, 0x00 } }, /* attack threshold */ { 0x13, 0x03, { 0x20, 0x00, 0x00 } }, /* power clipping level */ { 0x16, 0x01, { 0x00 } }, /* disable noise gate fade */ { 0x17, 0x01, { 0x00 } }, /* volume fine tune = 0d_b */ { 0x18, 0x01, { 0x40 } }, /* disable dynamic temperature control (DTC) */ { 0x19, 0x01, { 0x00 } }, /* reserved */ { 0x1A, 0x03, { 0x00, 0x00, 0x1a } }, /* noise gate attack level */ { 0x1D, 0x03, { 0x00, 0x00, 0x53 } }, /* noise gate release level */ { 0x20, 0x02, { 0x00, 0x10 } }, /* DRC energy coefficient */ { 0x22, 0x03, { 0x08, 0x00, 0x00 } }, /* DRC release threshold */ { 0x25, 0x01, { 0x34 } }, /* device number */ { ENDTBL_FLAG, 0x01, { 0x00 } }, /* end flag */ }; static td_void ad82010_soft_reset(const amp_platform_device *dev, td_bool reset) { td_s32 ret; td_u8 value; value = 0x00; ret = amp_osal_i2c_write(&dev->i2c, AD82010_RESET_REGISTER, &value, AD82010_NORMAL_REG_SIZE); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(amp_osal_i2c_write, ret); return; } osal_msleep(DELAY_20_MS); value = 0x10; ret = amp_osal_i2c_write(&dev->i2c, AD82010_RESET_REGISTER, &value, AD82010_NORMAL_REG_SIZE); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(amp_osal_i2c_write, ret); return; } osal_msleep(DELAY_20_MS); } static td_s32 ad82010_init(const amp_platform_device *dev) { drv_amp_dev_hw_mute(dev, TD_FALSE); osal_msleep(DELAY_20_MS); ad82010_soft_reset(dev, TD_TRUE); osal_msleep(DELAY_20_MS); drv_amp_dev_write_reg_map(dev, g_ad82010_init_reg); return TD_SUCCESS; } static td_void ad82010_deinit(const amp_platform_device *dev) { ad82010_soft_reset(dev, TD_TRUE); } static td_s32 ad82010_set_mute(const amp_platform_device *dev, amp_channel_type channel_type, td_bool mute) { td_s32 ret; const td_u8 vol = (mute == TD_TRUE) ? AD82010_MIN_VOL : AD82010_MAX_VOL; if (channel_type != AMP_CHANNEL_TYPE_ALL) { /* need add by custom for gain */ } ret = amp_osal_i2c_write(&dev->i2c, AD82010_MUTE_REGISTER, &vol, AD82010_NORMAL_REG_SIZE); if (ret != TD_SUCCESS) { soc_err_print_call_fun_err(amp_osal_i2c_write, ret); return ret; } return TD_SUCCESS; } static td_s32 ad82010_get_mute(const amp_platform_device *dev, amp_channel_type channel_type, td_bool *mute) { td_s32 ret; td_u8 vol = 0; if (mute == TD_NULL) { return SOC_ERR_AMP_NULL_PTR; } ret = amp_osal_i2c_read(&dev->i2c, AD82010_MUTE_REGISTER, &vol, AD82010_NORMAL_REG_SIZE); 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 = (vol == AD82010_MIN_VOL); } else { /* need add by custom */ } return TD_SUCCESS; } static amp_platform_driver g_ad82010_driver = { .name = "AD82010", .dev_type = AMP_DEV_AD82010, .deinit = ad82010_deinit, .init = ad82010_init, .get_mute = ad82010_get_mute, .set_mute = ad82010_set_mute, .hw_mute = drv_amp_dev_hw_mute, .reset = ad82010_soft_reset, .get_active = TD_NULL, .dump_reg = TD_NULL, }; td_s32 ad82010_register_driver(td_void) { return amp_platform_driver_register(&g_ad82010_driver); } #ifdef __cplusplus } #endif /* __cplusplus */