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.

173 lines
4.3 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2019-2019. All rights reserved.
* Description: amp device and driver rt9114c
* Author: audio
* Create: 2019-05-30
*/
#include "osal_ext.h"
#include "soc_errno.h"
#include "drv_amp_debug.h"
#include "drv_proc_ext.h"
#include "drv_amp_osal.h"
#include "drv_amp_common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define RT9114C_MAX_VOL 0x05
#define RT9114C_MIN_VOL 0xff /* mute */
static const drv_amp_reg_map g_rt9114c_init_reg[] = {
/* Initial sequence */
{ 0x07, 0x02, { 0x01, 0x80 } }, /* master volume: 0dB */
{ 0x62, 0x04, { 0x00, 0x00, 0x00, 0xA0 } }, /* IDF gain: 2dB */
{ 0x1A, 0x01, { 0x41 } }, /* Class D gain setting: 4.5 x Gain */
{ 0x04, 0x01, { 0x03 } },
{ 0x05, 0x01, { 0x02 } }, /* Amp turn on */
{ ENDTBL_FLAG, 0x01, { 0x00 } },
};
static td_void rt9114c_soft_reset(const amp_platform_device *dev)
{
td_s32 ret;
td_u8 reset_val = 0x80;
ret = amp_osal_i2c_write(&dev->i2c, 0x80, &reset_val, 1);
if (ret != TD_SUCCESS) {
soc_err_print_call_fun_err(amp_osal_i2c_write, ret);
return;
}
}
static td_void rt9114c_write_reg_map(const amp_platform_device *dev,
const drv_amp_reg_map *reg_map)
{
td_s32 ret;
td_u32 addr;
td_u32 size;
const 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 ((*reg == 0x1B) || (*reg == 0x46) || (*reg == 0x50) || (*reg == 0xF9)) {
osal_msleep(1);
}
reg_map++;
}
}
static td_s32 rt9114c_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) ? 0x03 : 0x00); /* 0x03: mute value */
if (channel_type != AMP_CHANNEL_TYPE_ALL) {
/* need add by custom */
}
/* 0x06: mute register addr */
ret = amp_osal_i2c_write(&dev->i2c, 0x06, &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 rt9114c_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;
}
/* 0x06: mute register addr */
ret = amp_osal_i2c_read(&dev->i2c, 0x06, &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 == 0x03); /* 0x03: mute value */
} else {
/* need add by custom */
}
return TD_SUCCESS;
}
static td_s32 rt9114c_init(const amp_platform_device *dev)
{
drv_amp_dev_hw_mute(dev, TD_FALSE);
osal_msleep(DELAY_10_MS);
rt9114c_soft_reset(dev);
osal_msleep(DELAY_10_MS);
rt9114c_write_reg_map(dev, g_rt9114c_init_reg);
return TD_SUCCESS;
}
static td_void rt9114c_deinit(const amp_platform_device *dev)
{
rt9114c_soft_reset(dev);
}
static td_void rt9114c_dump_reg(const amp_platform_device *dev, td_void *file)
{
drv_amp_dev_dump_reg_map(dev, file, g_rt9114c_init_reg);
}
static amp_platform_driver g_rt9114c_driver = {
.name = "RT9114C",
.dev_type = AMP_DEV_RT9114C,
.deinit = rt9114c_deinit,
.init = rt9114c_init,
.get_mute = rt9114c_get_mute,
.set_mute = rt9114c_set_mute,
.hw_mute = drv_amp_dev_hw_mute,
.reset = TD_NULL,
.get_active = TD_NULL,
.dump_reg = rt9114c_dump_reg,
};
td_s32 rt9114c_register_driver(td_void)
{
return amp_platform_driver_register(&g_rt9114c_driver);
}
#ifdef __cplusplus
}
#endif /* __cplusplus */