159 lines
3.4 KiB
C
Executable file
159 lines
3.4 KiB
C
Executable file
/**
|
|
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
|
* 2019-01-29 File created.
|
|
*/
|
|
|
|
#include "fsm_public.h"
|
|
#if defined(CONFIG_FSM_FS1599)
|
|
|
|
#define FS1599_STATUS 0xF000
|
|
|
|
#define FS1599_DEVID 0xF001
|
|
#define FS1599_REVID 0xF002
|
|
|
|
#define FS1599_ANASTAT 0xF003
|
|
#define FS1599_DIGSTAT 0xF004
|
|
|
|
#define FS1599_CHIPINI 0xF00E
|
|
|
|
#define FS1599_PWRCTRL 0xF010
|
|
#define FS1599_PWDN 0x0010
|
|
#define FS1599_I2CR 0x0110
|
|
|
|
#define FS1599_SYSCTRL 0xF011
|
|
#define FS1599_CPEN 0x0611
|
|
#define FS1599_AMPEN 0x0711
|
|
|
|
|
|
#define FS1599_GAINCTRL 0xF018
|
|
|
|
#define FS1599_ACCKEY 0xF01F
|
|
|
|
#define FS1599_LNMCTRL 0xF03F
|
|
#define FS1599_LNMMODE 0x0F3F
|
|
|
|
#define FS1599_ANACTRL 0xF0C0
|
|
#define FS1599_BSGCTRL 0xF0BC
|
|
|
|
#define FS1599_FW_NAME "fs1599.fsm"
|
|
|
|
|
|
static int fs1599_i2c_reset(fsm_dev_t *fsm_dev)
|
|
{
|
|
uint16_t val;
|
|
int ret;
|
|
int i;
|
|
|
|
if (!fsm_dev) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < FSM_I2C_RETRY; i++) {
|
|
fsm_reg_write(fsm_dev, REG(FS1599_PWRCTRL), 0x0002); // reset nack
|
|
fsm_reg_read(fsm_dev, REG(FS1599_PWRCTRL), NULL); // dummy read
|
|
fsm_delay_ms(15); // 15ms
|
|
ret = fsm_reg_write(fsm_dev, REG(FS1599_PWRCTRL), 0x0001);
|
|
ret |= fsm_reg_read(fsm_dev, REG(FS1599_CHIPINI), &val);
|
|
if ((val == 0x0003) || (val == 0x0300)) { // init finished
|
|
break;
|
|
}
|
|
}
|
|
if (i == FSM_I2C_RETRY) {
|
|
pr_addr(err, "retry timeout");
|
|
ret = -ETIMEDOUT;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int fs1599_reg_init(fsm_dev_t *fsm_dev)
|
|
{
|
|
fsm_config_t *cfg = fsm_get_config();
|
|
int ret;
|
|
|
|
if (fsm_dev == NULL || cfg == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = fs1599_i2c_reset(fsm_dev);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_ACCKEY), 0x0091);
|
|
ret |= fsm_write_reg_tbl(fsm_dev, FSM_SCENE_COMMON);
|
|
ret |= fsm_write_reg_tbl(fsm_dev, cfg->next_scene);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_ACCKEY), 0x0000);
|
|
if (ret) {
|
|
pr_addr(err, "init fail:%d", ret);
|
|
fsm_dev->state.dev_inited = false;
|
|
} else {
|
|
fsm_dev->cur_scene = cfg->next_scene;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int fs1599_start_up(fsm_dev_t *fsm_dev)
|
|
{
|
|
int ret;
|
|
|
|
if (!fsm_dev) {
|
|
return -EINVAL;
|
|
}
|
|
ret = fsm_reg_write(fsm_dev, REG(FS1599_ACCKEY), 0xCA91);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_ANACTRL), 0x0010);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_PWRCTRL), 0x0000);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_SYSCTRL), 0x00C0);
|
|
fsm_delay_ms(10);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_ANACTRL), 0x0000);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_ACCKEY), 0x0000);
|
|
fsm_dev->amp_on = true;
|
|
fsm_dev->errcode = ret;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int fs1599_set_mute(fsm_dev_t *fsm_dev, int mute)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (!fsm_dev) {
|
|
return -EINVAL;
|
|
}
|
|
if (mute) {
|
|
ret = fsm_set_bf(fsm_dev, FS1599_LNMMODE, 0x0000);
|
|
fsm_dev->cur_scene = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int fs1599_shut_down(fsm_dev_t *fsm_dev)
|
|
{
|
|
int ret;
|
|
|
|
if (fsm_dev == NULL) {
|
|
return -EINVAL;
|
|
}
|
|
ret = fsm_reg_write(fsm_dev, REG(FS1599_SYSCTRL), 0x0000);
|
|
fsm_delay_ms(20);
|
|
ret |= fsm_reg_write(fsm_dev, REG(FS1599_PWRCTRL), 0x0001);
|
|
fsm_dev->amp_on = false;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void fs1599_ops(fsm_dev_t *fsm_dev)
|
|
{
|
|
fsm_config_t *cfg = fsm_get_config();
|
|
|
|
if (!fsm_dev || !cfg) {
|
|
return;
|
|
}
|
|
|
|
fsm_set_fw_name(FS1599_FW_NAME);
|
|
fsm_dev->dev_ops.reg_init = fs1599_reg_init;
|
|
fsm_dev->dev_ops.start_up = fs1599_start_up;
|
|
fsm_dev->dev_ops.set_mute = fs1599_set_mute;
|
|
fsm_dev->dev_ops.shut_down = fs1599_shut_down;
|
|
cfg->nondsp_mode = true;
|
|
cfg->store_otp = false;
|
|
}
|
|
#endif
|