asoc: wcd939x: Update register sequences for wcd9395 v2.0

Check and update register sequences for wcd9395 version
2.0.

Change-Id: I85fc739744ee2ba2c5dbdc853eb639b84cac6478
Signed-off-by: Prasad Kumpatla <quic_pkumpatl@quicinc.com>
此提交包含在:
Prasad Kumpatla
2023-03-29 19:48:32 +05:30
提交者 Gerrit - the friendly Code Review server
父節點 9ef29aa716
當前提交 1ea2687052
共有 4 個檔案被更改,包括 130 行新增27 行删除

查看文件

@@ -17,6 +17,11 @@ enum {
RD_WR_REG
};
enum {
WCD939X_VERSION_1_0,
WCD939X_VERSION_1_1,
WCD939X_VERSION_2_0,
};
#define WCD939X_ANA_BASE (WCD939X_BASE+0x01)
#define WCD939X_ANA_PAGE (WCD939X_ANA_BASE+0x00)
@@ -228,6 +233,11 @@ enum {
#define WCD939X_STATUS_REG_1 (WCD939X_EAR_BASE+0x06)
#define WCD939X_STATUS_REG_2 (WCD939X_EAR_BASE+0x07)
#define WCD939X_FLYBACK_NEW_BASE (WCD939X_BASE+0xf7)
#define WCD939X_FLYBACK_NEW_CTRL_2 (WCD939X_FLYBACK_NEW_BASE+0x00)
#define WCD939X_FLYBACK_NEW_CTRL_3 (WCD939X_FLYBACK_NEW_BASE+0x01)
#define WCD939X_FLYBACK_NEW_CTRL_4 (WCD939X_FLYBACK_NEW_BASE+0x02)
#define WCD939X_ANA_NEW_BASE (WCD939X_BASE+0x101)
#define WCD939X_ANA_NEW_PAGE (WCD939X_ANA_NEW_BASE+0x00)

查看文件

@@ -185,6 +185,9 @@ static struct reg_default wcd939x_defaults[] = {
{WCD939X_EAR_TEST_CTL, 0x00},
{WCD939X_STATUS_REG_1, 0x00},
{WCD939X_STATUS_REG_2, 0x08},
{WCD939X_FLYBACK_NEW_CTRL_2, 0x00},
{WCD939X_FLYBACK_NEW_CTRL_3, 0x00},
{WCD939X_FLYBACK_NEW_CTRL_4, 0x44},
{WCD939X_ANA_NEW_PAGE, 0x00},
{WCD939X_ANA_HPH2, 0x00},
{WCD939X_ANA_HPH3, 0x00},
@@ -569,14 +572,6 @@ static struct reg_default wcd939x_defaults[] = {
{WCD939X_DSD_HPHR_CFG5, 0x00},
};
static bool wcd939x_readable_register(struct device *dev, unsigned int reg)
{
if (reg <= WCD939X_BASE + 1)
return 0;
return wcd939x_reg_access[WCD939X_REG(reg)] & RD_REG;
}
static bool wcd939x_writeable_register(struct device *dev, unsigned int reg)
{
if (reg <= WCD939X_BASE + 1)
@@ -602,7 +597,6 @@ struct regmap_config wcd939x_regmap_config = {
.num_reg_defaults = ARRAY_SIZE(wcd939x_defaults),
.max_register = WCD939X_MAX_REGISTER,
.volatile_reg = wcd939x_volatile_register,
.readable_reg = wcd939x_readable_register,
.writeable_reg = wcd939x_writeable_register,
.reg_format_endian = REGMAP_ENDIAN_NATIVE,
.val_format_endian = REGMAP_ENDIAN_NATIVE,

查看文件

@@ -183,6 +183,9 @@ const u8 wcd939x_reg_access[WCD939X_NUM_REGISTERS] = {
[WCD939X_REG(WCD939X_EAR_TEST_CTL)] = RD_WR_REG,
[WCD939X_REG(WCD939X_STATUS_REG_1)] = RD_REG,
[WCD939X_REG(WCD939X_STATUS_REG_2)] = RD_REG,
[WCD939X_REG(WCD939X_FLYBACK_NEW_CTRL_2)] = RD_WR_REG,
[WCD939X_REG(WCD939X_FLYBACK_NEW_CTRL_3)] = RD_WR_REG,
[WCD939X_REG(WCD939X_FLYBACK_NEW_CTRL_4)] = RD_WR_REG,
[WCD939X_REG(WCD939X_ANA_NEW_PAGE)] = RD_WR_REG,
[WCD939X_REG(WCD939X_ANA_HPH2)] = RD_WR_REG,
[WCD939X_REG(WCD939X_ANA_HPH3)] = RD_WR_REG,
@@ -566,3 +569,4 @@ const u8 wcd939x_reg_access[WCD939X_NUM_REGISTERS] = {
[WCD939X_REG(WCD939X_DSD_HPHR_CFG4)] = RD_WR_REG,
[WCD939X_REG(WCD939X_DSD_HPHR_CFG5)] = RD_WR_REG,
};

查看文件

@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/component.h>
#include <linux/stringify.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <soc/soundwire.h>
@@ -37,7 +38,6 @@
#define NUM_SWRS_DT_PARAMS 5
#define WCD939X_VARIANT_ENTRY_SIZE 32
#define WCD939X_VERSION_1_0 1
#define WCD939X_VERSION_ENTRY_SIZE 32
#define ADC_MODE_VAL_HIFI 0x01
@@ -130,6 +130,7 @@ static u8 tx_mode_bit[] = {
[ADC_MODE_ULP2] = 0x20,
};
extern const u8 wcd939x_reg_access[WCD939X_NUM_REGISTERS];
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
@@ -173,6 +174,20 @@ static struct regmap_irq_chip wcd939x_regmap_irq_chip = {
.irq_drv_data = NULL,
};
static bool wcd939x_readable_register(struct device *dev, unsigned int reg)
{
struct wcd939x_priv *wcd939x = dev_get_drvdata(dev);
if (reg <= WCD939X_BASE + 1)
return 0;
if (reg >= WCD939X_FLYBACK_NEW_CTRL_2 && reg <= WCD939X_FLYBACK_NEW_CTRL_4) {
if (wcd939x && wcd939x->version == WCD939X_VERSION_1_0)
return 0;
}
return wcd939x_reg_access[WCD939X_REG(reg)] & RD_REG;
}
static int wcd939x_handle_post_irq(void *data)
{
struct wcd939x_priv *wcd939x = data;
@@ -366,11 +381,6 @@ static int wcd939x_set_swr_clk_rate(struct snd_soc_component *component,
static int wcd939x_init_reg(struct snd_soc_component *component)
{
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
if (!wcd939x->hph_pcm_enabled)
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VBG_FINE_ADJ, VBG_FINE_ADJ, 0x04));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(BIAS, ANALOG_BIAS_EN, 0x01));
snd_soc_component_update_bits(component,
@@ -385,8 +395,6 @@ static int wcd939x_init_reg(struct snd_soc_component *component)
REG_FIELD_VALUE(RDAC_HD2_CTL_L, HD2_RES_DIV_CTL_L, 0x15));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(RDAC_HD2_CTL_R, HD2_RES_DIV_CTL_R, 0x15));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_UHQA_CTL, SPARE_BITS, 0x02));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(CDC_DMIC_CTL, CLK_SCALE_EN, 0x01));
@@ -699,6 +707,8 @@ static int wcd939x_rx_clk_enable(struct snd_soc_component *component, int rx_num
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
dev_dbg(component->dev, "%s rx_clk_cnt: %d\n", __func__, wcd939x->rx_clk_cnt);
if (wcd939x->rx_clk_cnt == 0) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(RX_SUPPLIES, RX_BIAS_ENABLE, 0x01));
@@ -722,12 +732,6 @@ static int wcd939x_rx_clk_enable(struct snd_soc_component *component, int rx_num
}
wcd939x->rx_clk_cnt++;
if (wcd939x->hph_pcm_enabled && (rx_num != WCD_RX3)) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(PA_GAIN_CTL_L, RX_SUPPLY_LEVEL, 0x01));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VNEG_CTRL_4, ILIM_SEL, 0x02));
}
return 0;
}
@@ -735,6 +739,11 @@ static int wcd939x_rx_clk_disable(struct snd_soc_component *component)
{
struct wcd939x_priv *wcd939x = snd_soc_component_get_drvdata(component);
dev_dbg(component->dev, "%s rx_clk_cnt: %d\n", __func__, wcd939x->rx_clk_cnt);
if (wcd939x->rx_clk_cnt == 0)
return 0;
wcd939x->rx_clk_cnt--;
if (wcd939x->rx_clk_cnt == 0) {
@@ -791,8 +800,12 @@ static int wcd939x_config_power_mode(struct snd_soc_component *component,
{
switch (event) {
case SND_SOC_DAPM_POST_PMU:
case SND_SOC_DAPM_PRE_PMU:
if (mode == CLS_H_ULP) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_UHQA_CTL, REFBUFP_IOUT_CTL, 0x2));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_UHQA_CTL, REFBUFN_IOUT_CTL, 0x2));
if (index == WCD939X_HPHL) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(CTL12, ZONE3_RMS, 0x21));
@@ -841,6 +854,15 @@ static int wcd939x_config_power_mode(struct snd_soc_component *component,
REG_FIELD_VALUE(R_CTL17, PATH_GAIN, 0x00));
}
}
break;
case SND_SOC_DAPM_POST_PMD:
if (mode == CLS_H_ULP) {
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_UHQA_CTL, REFBUFN_IOUT_CTL, 0x0));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_UHQA_CTL, REFBUFP_IOUT_CTL, 0x0));
}
break;
}
return 0;
}
@@ -1256,6 +1278,8 @@ static int wcd939x_rx_mux(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMD:
wcd939x_config_xtalk(component, event, w->shift);
wcd939x_config_compander(component, event, w->shift);
if (wcd939x->hph_pcm_enabled)
wcd939x_config_power_mode(component, event, w->shift, hph_mode);
wcd939x_rx_clk_disable(component);
break;
@@ -1420,6 +1444,8 @@ static int wcd939x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
WCD_CLSH_EVENT_PRE_DAC,
WCD_CLSH_STATE_EAR,
CLS_AB_HIFI);
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VNEG_CTRL_4, ILIM_SEL, 0xD));
break;
case SND_SOC_DAPM_POST_PMD:
snd_soc_component_update_bits(component,
@@ -1465,6 +1491,8 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x01));
}
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VNEG_CTRL_4, ILIM_SEL, 0xD));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(HPH, HPHR_REF_ENABLE, 0x01));
wcd_clsh_set_hph_mode(component, hph_mode);
@@ -1473,9 +1501,12 @@ static int wcd939x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
wcd_usbss_audio_config(NULL, WCD_USBSS_CONFIG_TYPE_POWER_MODE,
wcd939x_get_usbss_hph_power_mode(hph_mode));
/* update Mode for LOHIFI */
if (hph_mode == CLS_H_LOHIFI)
if (hph_mode == CLS_H_LOHIFI) {
snd_soc_component_write(component,
WCD939X_HPH_RDAC_BIAS_LOHIFI, 0x52);
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(HPH, PWR_LEVEL, 0x00));
}
/* 100 usec delay as per HW requirement */
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd939x->status_mask);
@@ -1615,6 +1646,8 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(REFBUFF_LP_CTL, PREREF_FILT_BYPASS, 0x01));
}
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(VNEG_CTRL_4, ILIM_SEL, 0xD));
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(HPH, HPHL_REF_ENABLE, 0x01));
wcd_clsh_set_hph_mode(component, hph_mode);
@@ -1623,9 +1656,12 @@ static int wcd939x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
wcd_usbss_audio_config(NULL, WCD_USBSS_CONFIG_TYPE_POWER_MODE,
wcd939x_get_usbss_hph_power_mode(hph_mode));
/* update Mode for LOHIFI */
if (hph_mode == CLS_H_LOHIFI)
if (hph_mode == CLS_H_LOHIFI) {
snd_soc_component_write(component,
WCD939X_HPH_RDAC_BIAS_LOHIFI, 0x52);
snd_soc_component_update_bits(component,
REG_FIELD_VALUE(HPH, PWR_LEVEL, 0x00));
}
/* 100 usec delay as per HW requirement */
usleep_range(100, 110);
set_bit(HPH_PA_DELAY, &wcd939x->status_mask);
@@ -4316,8 +4352,12 @@ static ssize_t wcd939x_version_read(struct snd_info_entry *entry,
switch (priv->version) {
case WCD939X_VERSION_1_0:
case WCD939X_VERSION_1_1:
len = snprintf(buffer, sizeof(buffer), "WCD939X_1_0\n");
break;
case WCD939X_VERSION_2_0:
len = snprintf(buffer, sizeof(buffer), "WCD939X_2_0\n");
break;
default:
len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
}
@@ -4607,7 +4647,6 @@ static int wcd939x_soc_codec_probe(struct snd_soc_component *component)
goto err_hwdep;
}
}
wcd939x->version = WCD939X_VERSION_1_0;
/* Register event notifier */
wcd939x->nblock.notifier_call = wcd939x_event_notify;
if (wcd939x->register_notifier) {
@@ -5016,11 +5055,54 @@ static struct snd_soc_dai_driver wcd939x_dai[] = {
},
};
static const struct reg_default reg_def_1_1[] = {
{WCD939X_VBG_FINE_ADJ, 0xA5},
{WCD939X_FLYBACK_NEW_CTRL_2, 0x0},
{WCD939X_FLYBACK_NEW_CTRL_3, 0x0},
{WCD939X_FLYBACK_NEW_CTRL_4, 0x44},
{WCD939X_PA_GAIN_CTL_R, 0x80},
};
static const struct reg_default reg_def_2_0[] = {
{WCD939X_INTR_MASK_2, 0x3E},
};
static const char *version_to_str(u32 version)
{
switch (version) {
case WCD939X_VERSION_1_0:
return __stringify(WCD939X_1_0);
case WCD939X_VERSION_1_1:
return __stringify(WCD939X_1_1);
case WCD939X_VERSION_2_0:
return __stringify(WCD939X_2_0);
}
return NULL;
}
static void wcd939x_update_regmap_cache(struct wcd939x_priv *wcd939x)
{
if (wcd939x->version == WCD939X_VERSION_1_0)
return;
if (wcd939x->version >= WCD939X_VERSION_1_1) {
for (int i = 0; i < ARRAY_SIZE(reg_def_1_1); ++i)
regmap_write(wcd939x->regmap, reg_def_1_1[i].reg, reg_def_1_1[i].def);
}
if (wcd939x->version == WCD939X_VERSION_2_0) {
for (int i = 0; i < ARRAY_SIZE(reg_def_2_0); ++i)
regmap_write(wcd939x->regmap, reg_def_2_0[i].reg, reg_def_2_0[i].def);
}
}
static int wcd939x_bind(struct device *dev)
{
int ret = 0, i = 0;
struct wcd939x_pdata *pdata = dev_get_platdata(dev);
struct wcd939x_priv *wcd939x = dev_get_drvdata(dev);
u8 id1 = 0, status1 = 0;
/*
* Add 5msec delay to provide sufficient time for
@@ -5054,6 +5136,18 @@ static int wcd939x_bind(struct device *dev)
swr_init_port_params(wcd939x->tx_swr_dev, SWR_NUM_PORTS,
wcd939x->swr_tx_port_params);
/* Check WCD9395 version */
swr_read(wcd939x->tx_swr_dev, wcd939x->tx_swr_dev->dev_num,
WCD939X_CHIP_ID1, &id1, 1);
swr_read(wcd939x->tx_swr_dev, wcd939x->tx_swr_dev->dev_num,
WCD939X_STATUS_REG_1, &status1, 1);
if (id1 == 0)
wcd939x->version = ((status1 & 0x3) ? WCD939X_VERSION_1_1 : WCD939X_VERSION_1_0);
else if (id1 == 1)
wcd939x->version = WCD939X_VERSION_2_0;
dev_info(dev, "%s: wcd9395 version: %s\n", __func__,
version_to_str(wcd939x->version));
wcd939x_regmap_config.readable_reg = wcd939x_readable_register;
wcd939x->regmap = devm_regmap_init_swr(wcd939x->tx_swr_dev,
&wcd939x_regmap_config);
if (!wcd939x->regmap) {
@@ -5061,6 +5155,7 @@ static int wcd939x_bind(struct device *dev)
__func__);
goto err;
}
wcd939x_update_regmap_cache(wcd939x);
/* Set all interupts as edge triggered */
for (i = 0; i < wcd939x_regmap_irq_chip.num_regs; i++)