kernel-brax3-ubuntu-touch/sound/soc/codecs/fs1599/fs1599.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

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