Merge "drivers: mfd: set IIR and ANC registers as volatile"
This commit is contained in:
commit
504c6dd5d1
9 changed files with 770 additions and 71 deletions
|
@ -1848,6 +1848,20 @@ static bool wcd934x_is_volatile_register(struct device *dev, unsigned int reg)
|
|||
if (reg_tbl && reg_tbl[reg_offset] == WCD934X_READ)
|
||||
return true;
|
||||
|
||||
/* IIR Coeff registers are not cacheable */
|
||||
if ((reg >= WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL) &&
|
||||
(reg <= WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL))
|
||||
return true;
|
||||
|
||||
if ((reg >= WCD934X_CDC_ANC0_IIR_COEFF_1_CTL) &&
|
||||
(reg <= WCD934X_CDC_ANC0_FB_GAIN_CTL))
|
||||
return true;
|
||||
|
||||
if ((reg >= WCD934X_CDC_ANC1_IIR_COEFF_1_CTL) &&
|
||||
(reg <= WCD934X_CDC_ANC1_FB_GAIN_CTL))
|
||||
return true;
|
||||
|
||||
|
||||
/*
|
||||
* Need to mark volatile for registers that are writable but
|
||||
* only few bits are read-only
|
||||
|
|
|
@ -53,12 +53,18 @@
|
|||
#define TASHA_VERSION_1_0 0
|
||||
#define TASHA_VERSION_1_1 1
|
||||
#define TASHA_VERSION_2_0 2
|
||||
#define TASHA_IS_1_0(ver) \
|
||||
((ver == TASHA_VERSION_1_0) ? 1 : 0)
|
||||
#define TASHA_IS_1_1(ver) \
|
||||
((ver == TASHA_VERSION_1_1) ? 1 : 0)
|
||||
#define TASHA_IS_2_0(ver) \
|
||||
((ver == TASHA_VERSION_2_0) ? 1 : 0)
|
||||
|
||||
#define TASHA_IS_1_0(wcd) \
|
||||
((wcd->type == WCD9335 || wcd->type == WCD9326) ? \
|
||||
((wcd->version == TASHA_VERSION_1_0) ? 1 : 0) : 0)
|
||||
|
||||
#define TASHA_IS_1_1(wcd) \
|
||||
((wcd->type == WCD9335 || wcd->type == WCD9326) ? \
|
||||
((wcd->version == TASHA_VERSION_1_1) ? 1 : 0) : 0)
|
||||
|
||||
#define TASHA_IS_2_0(wcd) \
|
||||
((wcd->type == WCD9335 || wcd->type == WCD9326) ? \
|
||||
((wcd->version == TASHA_VERSION_2_0) ? 1 : 0) : 0)
|
||||
|
||||
/*
|
||||
* As fine version info cannot be retrieved before tavil probe.
|
||||
|
|
|
@ -352,4 +352,10 @@
|
|||
#define WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL (0xB70)
|
||||
#define WCD9XXX_CDC_RX2_RX_PATH_SEC1 (0xB72)
|
||||
|
||||
/* Class-H registers for codecs from and above WCD934X */
|
||||
#define WCD9XXX_HPH_CNP_WG_CTL (0x06cc)
|
||||
#define WCD9XXX_FLYBACK_VNEG_CTRL_4 (0x06a8)
|
||||
#define WCD9XXX_HPH_NEW_INT_PA_MISC2 (0x0738)
|
||||
#define WCD9XXX_RX_BIAS_HPH_LOWPOWER (0x06bf)
|
||||
#define WCD9XXX_HPH_PA_CTL1 (0x06d1)
|
||||
#endif
|
||||
|
|
|
@ -1114,7 +1114,7 @@ static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
|
|||
if (!codec)
|
||||
return;
|
||||
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx->version)) {
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx)) {
|
||||
dev_dbg(codec->dev, "%s: tasha version < 2p0, return\n",
|
||||
__func__);
|
||||
return;
|
||||
|
@ -1139,7 +1139,7 @@ static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
|
|||
|
||||
static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha)
|
||||
{
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version) &&
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx) &&
|
||||
svs_scaling_enabled)
|
||||
return true;
|
||||
|
||||
|
@ -1269,7 +1269,7 @@ int tasha_enable_efuse_sensing(struct snd_soc_codec *codec)
|
|||
|
||||
tasha_cdc_mclk_enable(codec, true, false);
|
||||
|
||||
if (!TASHA_IS_2_0(priv->wcd9xxx->version))
|
||||
if (!TASHA_IS_2_0(priv->wcd9xxx))
|
||||
snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
|
||||
0x1E, 0x02);
|
||||
snd_soc_update_bits(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_CTL,
|
||||
|
@ -1282,7 +1282,7 @@ int tasha_enable_efuse_sensing(struct snd_soc_codec *codec)
|
|||
if (!(snd_soc_read(codec, WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01))
|
||||
WARN(1, "%s: Efuse sense is not complete\n", __func__);
|
||||
|
||||
if (TASHA_IS_2_0(priv->wcd9xxx->version)) {
|
||||
if (TASHA_IS_2_0(priv->wcd9xxx)) {
|
||||
if (!(snd_soc_read(codec,
|
||||
WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0) & 0x40))
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_R_ATEST,
|
||||
|
@ -1502,7 +1502,7 @@ static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
|
|||
dev_dbg(codec->dev, "%s: HS pull up current:%d\n",
|
||||
__func__, pull_up_cur);
|
||||
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
|
||||
0xC0, pull_up_cur << 6);
|
||||
else
|
||||
|
@ -1980,7 +1980,7 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
|||
};
|
||||
s16 *d1 = NULL;
|
||||
|
||||
if (!TASHA_IS_2_0(wcd9xxx->version)) {
|
||||
if (!TASHA_IS_2_0(wcd9xxx)) {
|
||||
dev_dbg(codec->dev, "%s: Z-det is not supported for this codec version\n",
|
||||
__func__);
|
||||
*zl = 0;
|
||||
|
@ -2168,13 +2168,13 @@ static void tasha_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec,
|
|||
if (enable) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
|
||||
0x40, 0x40);
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
|
||||
0x10, 0x10);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
|
||||
0x40, 0x00);
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2,
|
||||
0x10, 0x00);
|
||||
}
|
||||
|
@ -3663,7 +3663,7 @@ static int tasha_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
|
|||
case SND_SOC_DAPM_PRE_PMU:
|
||||
tasha->rx_bias_count++;
|
||||
if (tasha->rx_bias_count == 1) {
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
tasha_codec_init_flyback(codec);
|
||||
snd_soc_update_bits(codec, WCD9335_ANA_RX_SUPPLIES,
|
||||
0x01, 0x01);
|
||||
|
@ -3929,7 +3929,7 @@ static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
|
|||
{
|
||||
u8 scale_val = 0;
|
||||
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
|
@ -4414,7 +4414,7 @@ static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
|
|||
{
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
return;
|
||||
|
||||
switch (mode) {
|
||||
|
@ -4478,14 +4478,14 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
|||
/* 1000us required as per HW requirement */
|
||||
usleep_range(1000, 1100);
|
||||
if ((hph_mode == CLS_H_LP) &&
|
||||
(TASHA_IS_1_1(wcd9xxx->version))) {
|
||||
(TASHA_IS_1_1(wcd9xxx))) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
|
||||
0x03, 0x03);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
if ((hph_mode == CLS_H_LP) &&
|
||||
(TASHA_IS_1_1(wcd9xxx->version))) {
|
||||
(TASHA_IS_1_1(wcd9xxx))) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
|
||||
0x03, 0x00);
|
||||
}
|
||||
|
@ -4568,14 +4568,14 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|||
/* 1000us required as per HW requirement */
|
||||
usleep_range(1000, 1100);
|
||||
if ((hph_mode == CLS_H_LP) &&
|
||||
(TASHA_IS_1_1(wcd9xxx->version))) {
|
||||
(TASHA_IS_1_1(wcd9xxx))) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
|
||||
0x03, 0x03);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
if ((hph_mode == CLS_H_LP) &&
|
||||
(TASHA_IS_1_1(wcd9xxx->version))) {
|
||||
(TASHA_IS_1_1(wcd9xxx))) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_L_DAC_CTL,
|
||||
0x03, 0x00);
|
||||
}
|
||||
|
@ -4800,7 +4800,7 @@ static void tasha_codec_hd2_control(struct snd_soc_codec *codec,
|
|||
u16 hd2_scale_reg;
|
||||
u16 hd2_enable_reg = 0;
|
||||
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
return;
|
||||
|
||||
if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
|
||||
|
@ -8007,7 +8007,7 @@ static void wcd_vbat_adc_out_config(struct wcd_vbat *vbat,
|
|||
if (!vbat->adc_config) {
|
||||
tasha_cdc_mclk_enable(codec, true, false);
|
||||
|
||||
if (TASHA_IS_2_0(wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(wcd9xxx))
|
||||
wcd_vbat_adc_out_config_2_0(vbat, codec);
|
||||
else
|
||||
wcd_vbat_adc_out_config_1_x(vbat, codec);
|
||||
|
@ -10992,7 +10992,7 @@ static int tasha_set_channel_map(struct snd_soc_dai *dai,
|
|||
/* Reserve TX12/TX13 for MAD data channel */
|
||||
dai_data = &tasha->dai[AIF4_MAD_TX];
|
||||
if (dai_data) {
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
list_add_tail(&core->tx_chs[TASHA_TX13].list,
|
||||
&dai_data->wcd9xxx_ch_list);
|
||||
else
|
||||
|
@ -11943,9 +11943,9 @@ static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
|
|||
wcd9xxx = tasha->wcd9xxx;
|
||||
|
||||
if (wcd9xxx->codec_type->id_major == TASHA_MAJOR) {
|
||||
if (TASHA_IS_1_0(wcd9xxx->version))
|
||||
if (TASHA_IS_1_0(wcd9xxx))
|
||||
len = snprintf(buffer, sizeof(buffer), "WCD9335_1_0\n");
|
||||
else if (TASHA_IS_1_1(wcd9xxx->version))
|
||||
else if (TASHA_IS_1_1(wcd9xxx))
|
||||
len = snprintf(buffer, sizeof(buffer), "WCD9335_1_1\n");
|
||||
else
|
||||
snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
|
||||
|
@ -12287,7 +12287,7 @@ static void tasha_update_reg_reset_values(struct snd_soc_codec *codec)
|
|||
u32 i;
|
||||
struct wcd9xxx *tasha_core = dev_get_drvdata(codec->dev->parent);
|
||||
|
||||
if (TASHA_IS_1_1(tasha_core->version)) {
|
||||
if (TASHA_IS_1_1(tasha_core)) {
|
||||
for (i = 0; i < ARRAY_SIZE(tasha_reg_update_reset_val_1_1);
|
||||
i++)
|
||||
snd_soc_write(codec,
|
||||
|
@ -12307,27 +12307,27 @@ static void tasha_codec_init_reg(struct snd_soc_codec *codec)
|
|||
tasha_codec_reg_init_common_val[i].mask,
|
||||
tasha_codec_reg_init_common_val[i].val);
|
||||
|
||||
if (TASHA_IS_1_1(wcd9xxx->version) ||
|
||||
TASHA_IS_1_0(wcd9xxx->version))
|
||||
if (TASHA_IS_1_1(wcd9xxx) ||
|
||||
TASHA_IS_1_0(wcd9xxx))
|
||||
for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_1_x_val); i++)
|
||||
snd_soc_update_bits(codec,
|
||||
tasha_codec_reg_init_1_x_val[i].reg,
|
||||
tasha_codec_reg_init_1_x_val[i].mask,
|
||||
tasha_codec_reg_init_1_x_val[i].val);
|
||||
|
||||
if (TASHA_IS_1_1(wcd9xxx->version)) {
|
||||
if (TASHA_IS_1_1(wcd9xxx)) {
|
||||
for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_1); i++)
|
||||
snd_soc_update_bits(codec,
|
||||
tasha_codec_reg_init_val_1_1[i].reg,
|
||||
tasha_codec_reg_init_val_1_1[i].mask,
|
||||
tasha_codec_reg_init_val_1_1[i].val);
|
||||
} else if (TASHA_IS_1_0(wcd9xxx->version)) {
|
||||
} else if (TASHA_IS_1_0(wcd9xxx)) {
|
||||
for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_1_0); i++)
|
||||
snd_soc_update_bits(codec,
|
||||
tasha_codec_reg_init_val_1_0[i].reg,
|
||||
tasha_codec_reg_init_val_1_0[i].mask,
|
||||
tasha_codec_reg_init_val_1_0[i].val);
|
||||
} else if (TASHA_IS_2_0(wcd9xxx->version)) {
|
||||
} else if (TASHA_IS_2_0(wcd9xxx)) {
|
||||
for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_init_val_2_0); i++)
|
||||
snd_soc_update_bits(codec,
|
||||
tasha_codec_reg_init_val_2_0[i].reg,
|
||||
|
@ -12814,7 +12814,7 @@ static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
if (TASHA_IS_1_0(wcd9xxx->version)) {
|
||||
if (TASHA_IS_1_0(wcd9xxx)) {
|
||||
tasha_cdc_mclk_enable(codec, true, false);
|
||||
clk_sel_reg_val = 0x02;
|
||||
}
|
||||
|
@ -12853,7 +12853,7 @@ static int tasha_codec_cpe_fll_enable(struct snd_soc_codec *codec,
|
|||
snd_soc_update_bits(codec, WCD9335_CPE_FLL_USER_CTL_0,
|
||||
0x01, 0x00);
|
||||
|
||||
if (TASHA_IS_1_0(wcd9xxx->version))
|
||||
if (TASHA_IS_1_0(wcd9xxx))
|
||||
tasha_cdc_mclk_enable(codec, false, false);
|
||||
|
||||
/*
|
||||
|
@ -12982,7 +12982,7 @@ static int tasha_cpe_err_irq_control(struct snd_soc_codec *codec,
|
|||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
u8 irq_bits;
|
||||
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
irq_bits = 0xFF;
|
||||
else
|
||||
irq_bits = 0x3F;
|
||||
|
@ -13295,7 +13295,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec)
|
|||
}
|
||||
|
||||
/* Initialize MBHC module */
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version)) {
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx)) {
|
||||
wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].reg =
|
||||
WCD9335_MBHC_FSM_STATUS;
|
||||
wcd_mbhc_registers[WCD_MBHC_FSM_STATUS].mask = 0x01;
|
||||
|
@ -13680,7 +13680,7 @@ static int tasha_swrm_clock(void *handle, bool enable)
|
|||
if (enable) {
|
||||
tasha->swr_clk_users++;
|
||||
if (tasha->swr_clk_users == 1) {
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
regmap_update_bits(
|
||||
tasha->wcd9xxx->regmap,
|
||||
WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
|
||||
|
@ -13697,7 +13697,7 @@ static int tasha_swrm_clock(void *handle, bool enable)
|
|||
WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL,
|
||||
0x01, 0x00);
|
||||
__tasha_cdc_mclk_enable(tasha, false);
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
if (TASHA_IS_2_0(tasha->wcd9xxx))
|
||||
regmap_update_bits(
|
||||
tasha->wcd9xxx->regmap,
|
||||
WCD9335_TEST_DEBUG_NPL_DLY_TEST_1,
|
||||
|
|
|
@ -312,6 +312,43 @@ const struct snd_soc_dapm_route tavil_audio_map[] = {
|
|||
{"ADC MUX13", "DMIC", "DMIC MUX13"},
|
||||
{"ADC MUX13", "AMIC", "AMIC MUX13"},
|
||||
|
||||
{"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX0", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX1", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX2", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX3", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX4", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX5", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX6", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX7", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
{"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
|
||||
{"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
|
||||
{"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX12"},
|
||||
{"ADC MUX8", "ANC_FB_TUNE2", "ADC MUX13"},
|
||||
|
||||
{"DMIC MUX0", "DMIC0", "DMIC0"},
|
||||
{"DMIC MUX0", "DMIC1", "DMIC1"},
|
||||
{"DMIC MUX0", "DMIC2", "DMIC2"},
|
||||
|
@ -860,6 +897,29 @@ const struct snd_soc_dapm_route tavil_audio_map[] = {
|
|||
{"RX INT8 CHAIN", NULL, "RX_BIAS"},
|
||||
{"SPK2 OUT", NULL, "RX INT8 CHAIN"},
|
||||
|
||||
/* ANC Routing */
|
||||
{"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
|
||||
{"ANC0 FB MUX", "ANC_IN_HPHL", "RX INT1 MIX2"},
|
||||
{"ANC0 FB MUX", "ANC_IN_LO1", "RX INT3 MIX2"},
|
||||
{"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
|
||||
{"ANC1 FB MUX", "ANC_IN_HPHR", "RX INT2 MIX2"},
|
||||
{"ANC1 FB MUX", "ANC_IN_LO2", "RX INT4 MIX2"},
|
||||
|
||||
{"ANC OUT EAR Enable", "Switch", "ADC MUX10"},
|
||||
{"ANC OUT EAR Enable", "Switch", "ADC MUX11"},
|
||||
{"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"},
|
||||
|
||||
{"ANC EAR PA", NULL, "RX INT0 DAC"},
|
||||
{"ANC EAR", NULL, "ANC EAR PA"},
|
||||
|
||||
{"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
|
||||
{"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
|
||||
{"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
|
||||
|
||||
{"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
|
||||
{"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
|
||||
{"SPK1 OUT", NULL, "ANC SPK1 PA"},
|
||||
|
||||
/*
|
||||
* SRC0, SRC1 inputs to Sidetone RX Mixer
|
||||
* on RX0, RX1, RX2, RX3, RX4 and RX7 chains
|
||||
|
|
|
@ -66,6 +66,15 @@
|
|||
|
||||
#define WCD934X_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE)
|
||||
|
||||
/* Macros for packing register writes into a U32 */
|
||||
#define WCD934X_PACKED_REG_SIZE sizeof(u32)
|
||||
#define WCD934X_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \
|
||||
do { \
|
||||
((reg) = ((packed >> 16) & (0xffff))); \
|
||||
((mask) = ((packed >> 8) & (0xff))); \
|
||||
((val) = ((packed) & (0xff))); \
|
||||
} while (0)
|
||||
|
||||
#define STRING(name) #name
|
||||
#define WCD_DAPM_ENUM(name, reg, offset, text) \
|
||||
static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
|
||||
|
@ -391,6 +400,24 @@ static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
|
|||
(WCD934X_REGISTER_START_OFFSET + WCD934X_SB_PGD_PORT_RX_BASE),
|
||||
SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD934X_REG_BITS, 0x1
|
||||
},
|
||||
{
|
||||
1,
|
||||
(WCD934X_REGISTER_START_OFFSET +
|
||||
WCD934X_CDC_ANC0_IIR_ADAPT_CTL),
|
||||
AANC_FF_GAIN_ADAPTIVE, 0x4, WCD934X_REG_BITS, 0
|
||||
},
|
||||
{
|
||||
1,
|
||||
(WCD934X_REGISTER_START_OFFSET +
|
||||
WCD934X_CDC_ANC0_IIR_ADAPT_CTL),
|
||||
AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD934X_REG_BITS, 0
|
||||
},
|
||||
{
|
||||
1,
|
||||
(WCD934X_REGISTER_START_OFFSET +
|
||||
WCD934X_CDC_ANC0_FF_A_GAIN_CTL),
|
||||
AANC_GAIN_CONTROL, 0xFF, WCD934X_REG_BITS, 0
|
||||
},
|
||||
};
|
||||
|
||||
static struct afe_param_cdc_reg_cfg_data tavil_audio_reg_cfg = {
|
||||
|
@ -398,6 +425,11 @@ static struct afe_param_cdc_reg_cfg_data tavil_audio_reg_cfg = {
|
|||
.reg_data = audio_reg_cfg,
|
||||
};
|
||||
|
||||
static struct afe_param_id_cdc_aanc_version tavil_cdc_aanc_version = {
|
||||
.cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
|
||||
.aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
|
||||
};
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
|
||||
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
|
||||
|
@ -464,6 +496,10 @@ struct tavil_priv {
|
|||
s32 micb_ref[TAVIL_MAX_MICBIAS];
|
||||
s32 pullup_ref[TAVIL_MAX_MICBIAS];
|
||||
|
||||
/* ANC related */
|
||||
u32 anc_slot;
|
||||
bool anc_func;
|
||||
|
||||
/* compander */
|
||||
int comp_enabled[COMPANDER_MAX];
|
||||
/* class h specific data */
|
||||
|
@ -755,7 +791,7 @@ void *tavil_get_afe_config(struct snd_soc_codec *codec,
|
|||
case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
|
||||
return &tavil_slimbus_slave_port_cfg;
|
||||
case AFE_AANC_VERSION:
|
||||
return NULL;
|
||||
return &tavil_cdc_aanc_version;
|
||||
case AFE_CDC_REGISTER_PAGE_CONFIG:
|
||||
return &tavil_cdc_reg_page_cfg;
|
||||
default:
|
||||
|
@ -827,6 +863,212 @@ done:
|
|||
mutex_unlock(&tavil->svs_mutex);
|
||||
}
|
||||
|
||||
static int tavil_get_anc_slot(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
ucontrol->value.integer.value[0] = tavil->anc_slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_put_anc_slot(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
tavil->anc_slot = ucontrol->value.integer.value[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_get_anc_func(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
ucontrol->value.integer.value[0] = (tavil->anc_func == true ? 1 : 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_put_anc_func(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
||||
|
||||
mutex_lock(&tavil->codec_mutex);
|
||||
tavil->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
|
||||
dev_dbg(codec->dev, "%s: anc_func %x", __func__, tavil->anc_func);
|
||||
|
||||
if (tavil->anc_func == true) {
|
||||
snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
|
||||
snd_soc_dapm_enable_pin(dapm, "ANC EAR");
|
||||
snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
|
||||
snd_soc_dapm_disable_pin(dapm, "EAR PA");
|
||||
snd_soc_dapm_disable_pin(dapm, "EAR");
|
||||
} else {
|
||||
snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
|
||||
snd_soc_dapm_disable_pin(dapm, "ANC EAR");
|
||||
snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
|
||||
snd_soc_dapm_enable_pin(dapm, "EAR PA");
|
||||
snd_soc_dapm_enable_pin(dapm, "EAR");
|
||||
}
|
||||
mutex_unlock(&tavil->codec_mutex);
|
||||
|
||||
snd_soc_dapm_sync(dapm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_codec_enable_anc(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
const char *filename;
|
||||
const struct firmware *fw;
|
||||
int i;
|
||||
int ret = 0;
|
||||
int num_anc_slots;
|
||||
struct wcd9xxx_anc_header *anc_head;
|
||||
struct firmware_cal *hwdep_cal = NULL;
|
||||
u32 anc_writes_size = 0;
|
||||
u32 anc_cal_size = 0;
|
||||
int anc_size_remaining;
|
||||
u32 *anc_ptr;
|
||||
u16 reg;
|
||||
u8 mask, val;
|
||||
size_t cal_size;
|
||||
const void *data;
|
||||
|
||||
if (!tavil->anc_func)
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
hwdep_cal = wcdcal_get_fw_cal(tavil->fw_data, WCD9XXX_ANC_CAL);
|
||||
if (hwdep_cal) {
|
||||
data = hwdep_cal->data;
|
||||
cal_size = hwdep_cal->size;
|
||||
dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd",
|
||||
__func__, cal_size);
|
||||
} else {
|
||||
filename = "WCD934X/WCD934X_anc.bin";
|
||||
ret = request_firmware(&fw, filename, codec->dev);
|
||||
if (IS_ERR_VALUE(ret)) {
|
||||
dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
if (!fw) {
|
||||
dev_err(codec->dev, "%s: Failed to get anc fw\n",
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
data = fw->data;
|
||||
cal_size = fw->size;
|
||||
dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
|
||||
__func__);
|
||||
}
|
||||
if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
|
||||
dev_err(codec->dev, "%s: Invalid cal_size %zd\n",
|
||||
__func__, cal_size);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
/* First number is the number of register writes */
|
||||
anc_head = (struct wcd9xxx_anc_header *)(data);
|
||||
anc_ptr = (u32 *)(data + sizeof(struct wcd9xxx_anc_header));
|
||||
anc_size_remaining = cal_size -
|
||||
sizeof(struct wcd9xxx_anc_header);
|
||||
num_anc_slots = anc_head->num_anc_slots;
|
||||
|
||||
if (tavil->anc_slot >= num_anc_slots) {
|
||||
dev_err(codec->dev, "%s: Invalid ANC slot selected\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < num_anc_slots; i++) {
|
||||
if (anc_size_remaining < WCD934X_PACKED_REG_SIZE) {
|
||||
dev_err(codec->dev, "%s: Invalid register format\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
anc_writes_size = (u32)(*anc_ptr);
|
||||
anc_size_remaining -= sizeof(u32);
|
||||
anc_ptr += 1;
|
||||
|
||||
if ((anc_writes_size * WCD934X_PACKED_REG_SIZE) >
|
||||
anc_size_remaining) {
|
||||
dev_err(codec->dev, "%s: Invalid register format\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tavil->anc_slot == i)
|
||||
break;
|
||||
|
||||
anc_size_remaining -= (anc_writes_size *
|
||||
WCD934X_PACKED_REG_SIZE);
|
||||
anc_ptr += anc_writes_size;
|
||||
}
|
||||
if (i == num_anc_slots) {
|
||||
dev_err(codec->dev, "%s: Selected ANC slot not present\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
anc_cal_size = anc_writes_size;
|
||||
for (i = 0; i < anc_writes_size; i++) {
|
||||
WCD934X_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
|
||||
snd_soc_write(codec, reg, (val & mask));
|
||||
}
|
||||
|
||||
if (!hwdep_cal)
|
||||
release_firmware(fw);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* Remove ANC Rx from reset */
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_CLK_RESET_CTL,
|
||||
0x08, 0x00);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC1_CLK_RESET_CTL,
|
||||
0x08, 0x00);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (!strcmp(w->name, "ANC EAR PA") ||
|
||||
!strcmp(w->name, "ANC SPK1 PA")) {
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL,
|
||||
0x30, 0x00);
|
||||
msleep(50);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_1_CTL,
|
||||
0x01, 0x00);
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_CDC_ANC0_CLK_RESET_CTL,
|
||||
0x38, 0x38);
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_CDC_ANC0_CLK_RESET_CTL,
|
||||
0x07, 0x00);
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_CDC_ANC0_CLK_RESET_CTL,
|
||||
0x38, 0x00);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (!hwdep_cal)
|
||||
release_firmware(fw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tavil_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
@ -1419,10 +1661,40 @@ static int tavil_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (!tavil->anc_func)
|
||||
return 0;
|
||||
|
||||
dev_dbg(codec->dev, "%s: w: %s event: %d anc: %d\n", __func__,
|
||||
w->name, event, tavil->anc_func);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
ret = tavil_codec_enable_anc(w, kcontrol, event);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_CFG0,
|
||||
0x10, 0x10);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_RX7_RX_PATH_CFG0,
|
||||
0x10, 0x00);
|
||||
ret = tavil_codec_enable_anc(w, kcontrol, event);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
|
||||
|
@ -1443,11 +1715,43 @@ static int tavil_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||
WCD934X_CDC_RX0_RX_PATH_MIX_CTL,
|
||||
0x10, 0x00);
|
||||
break;
|
||||
default:
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/*
|
||||
* 5ms sleep is required after PA is disabled as per
|
||||
* HW requirement
|
||||
*/
|
||||
usleep_range(5000, 5500);
|
||||
|
||||
if (!(strcmp(w->name, "ANC EAR PA"))) {
|
||||
ret = tavil_codec_enable_anc(w, kcontrol, event);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CFG0,
|
||||
0x10, 0x00);
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tavil_codec_override(struct snd_soc_codec *codec, int mode,
|
||||
int event)
|
||||
{
|
||||
if (mode == CLS_AB || mode == CLS_AB_HIFI) {
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
if (!(snd_soc_read(codec,
|
||||
WCD934X_CDC_RX2_RX_PATH_CTL) & 0x10) &&
|
||||
(!(snd_soc_read(codec,
|
||||
WCD934X_CDC_RX1_RX_PATH_CTL) & 0x10)))
|
||||
snd_soc_update_bits(codec,
|
||||
WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x02);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
snd_soc_update_bits(codec,
|
||||
WCD9XXX_A_ANA_RX_SUPPLIES, 0x02, 0x00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
||||
|
@ -1462,6 +1766,8 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
|
||||
0x06, (0x03 << 1));
|
||||
set_bit(HPH_PA_DELAY, &tavil->status_mask);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1476,6 +1782,9 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||
/* Remove mute */
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_RX2_RX_PATH_CTL,
|
||||
0x10, 0x00);
|
||||
/* Enable GM3 boost */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_CNP_WG_CTL,
|
||||
0x80, 0x80);
|
||||
/* Enable AutoChop timer at the end of power up */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1,
|
||||
0x02, 0x02);
|
||||
|
@ -1493,6 +1802,7 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||
snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2,
|
||||
0x04, 0x00);
|
||||
}
|
||||
tavil_codec_override(codec, tavil->hph_mode, event);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
/* Enable DSD Mute before PA disable */
|
||||
|
@ -1502,6 +1812,9 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||
0x04, 0x04);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
tavil_codec_override(codec, tavil->hph_mode, event);
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
|
||||
0x06, 0x0);
|
||||
/* 5ms sleep is required after PA disable */
|
||||
usleep_range(5000, 5100);
|
||||
break;
|
||||
|
@ -1522,6 +1835,8 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
|
||||
0x06, (0x03 << 1));
|
||||
set_bit(HPH_PA_DELAY, &tavil->status_mask);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1536,6 +1851,12 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
/* Remove Mute on primary path */
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CTL,
|
||||
0x10, 0x00);
|
||||
/* Enable GM3 boost */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_CNP_WG_CTL,
|
||||
0x80, 0x80);
|
||||
/* Enable AutoChop timer at the end of power up */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1,
|
||||
0x02, 0x02);
|
||||
/* Remove mix path mute if it is enabled */
|
||||
if ((snd_soc_read(codec, WCD934X_CDC_RX1_RX_PATH_MIX_CTL)) &
|
||||
0x10)
|
||||
|
@ -1550,6 +1871,7 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2,
|
||||
0x04, 0x00);
|
||||
}
|
||||
tavil_codec_override(codec, tavil->hph_mode, event);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
/* Enable DSD Mute before PA disable */
|
||||
|
@ -1559,6 +1881,9 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
0x04, 0x04);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
tavil_codec_override(codec, tavil->hph_mode, event);
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
|
||||
0x06, 0x0);
|
||||
/* 5ms sleep is required after PA disable */
|
||||
usleep_range(5000, 5100);
|
||||
break;
|
||||
|
@ -1616,6 +1941,7 @@ static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
|
@ -1626,10 +1952,17 @@ static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
|
|||
/* Disable AutoChop timer during power up */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1,
|
||||
0x02, 0x00);
|
||||
|
||||
if (tavil->anc_func)
|
||||
ret = tavil_codec_enable_anc(w, kcontrol, event);
|
||||
|
||||
wcd_clsh_fsm(codec, &tavil->clsh_d,
|
||||
WCD_CLSH_EVENT_PRE_DAC,
|
||||
WCD_CLSH_STATE_EAR,
|
||||
CLS_H_NORMAL);
|
||||
if (tavil->anc_func)
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_RX0_RX_PATH_CFG0,
|
||||
0x10, 0x10);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
wcd_clsh_fsm(codec, &tavil->clsh_d,
|
||||
|
@ -1641,7 +1974,7 @@ static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
|
|||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
||||
|
@ -1668,9 +2001,17 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
|||
__func__, hph_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP))
|
||||
/* Ripple freq control enable */
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_SIDO_NEW_VOUT_D_FREQ2,
|
||||
0x01, 0x01);
|
||||
/* Disable AutoChop timer during power up */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1,
|
||||
0x02, 0x00);
|
||||
0x02, 0x00);
|
||||
/* Set RDAC gain */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL,
|
||||
0xF0, 0x40);
|
||||
|
||||
if (dsd_conf &&
|
||||
(snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01))
|
||||
|
@ -1679,8 +2020,7 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
|||
wcd_clsh_fsm(codec, &tavil->clsh_d,
|
||||
WCD_CLSH_EVENT_PRE_DAC,
|
||||
WCD_CLSH_STATE_HPHR,
|
||||
((hph_mode == CLS_H_LOHIFI) ?
|
||||
CLS_H_HIFI : hph_mode));
|
||||
hph_mode);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* 1000us required as per HW requirement */
|
||||
|
@ -1688,8 +2028,15 @@ static int tavil_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
|||
wcd_clsh_fsm(codec, &tavil->clsh_d,
|
||||
WCD_CLSH_EVENT_POST_PA,
|
||||
WCD_CLSH_STATE_HPHR,
|
||||
((hph_mode == CLS_H_LOHIFI) ?
|
||||
CLS_H_HIFI : hph_mode));
|
||||
hph_mode);
|
||||
if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP))
|
||||
/* Ripple freq control disable */
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_SIDO_NEW_VOUT_D_FREQ2,
|
||||
0x01, 0x0);
|
||||
/* Re-set RDAC gain */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL,
|
||||
0xF0, 0x0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1723,6 +2070,17 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|||
__func__, hph_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP))
|
||||
/* Ripple freq control enable */
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_SIDO_NEW_VOUT_D_FREQ2,
|
||||
0x01, 0x01);
|
||||
/* Disable AutoChop timer during power up */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_HPH_TIMER1,
|
||||
0x02, 0x00);
|
||||
/* Set RDAC gain */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL,
|
||||
0xF0, 0x40);
|
||||
if (dsd_conf &&
|
||||
(snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01))
|
||||
hph_mode = CLS_H_HIFI;
|
||||
|
@ -1730,8 +2088,7 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|||
wcd_clsh_fsm(codec, &tavil->clsh_d,
|
||||
WCD_CLSH_EVENT_PRE_DAC,
|
||||
WCD_CLSH_STATE_HPHL,
|
||||
((hph_mode == CLS_H_LOHIFI) ?
|
||||
CLS_H_HIFI : hph_mode));
|
||||
hph_mode);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* 1000us required as per HW requirement */
|
||||
|
@ -1739,8 +2096,15 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
|||
wcd_clsh_fsm(codec, &tavil->clsh_d,
|
||||
WCD_CLSH_EVENT_POST_PA,
|
||||
WCD_CLSH_STATE_HPHL,
|
||||
((hph_mode == CLS_H_LOHIFI) ?
|
||||
CLS_H_HIFI : hph_mode));
|
||||
hph_mode);
|
||||
if ((hph_mode != CLS_H_LP) && (hph_mode != CLS_H_ULP))
|
||||
/* Ripple freq control disable */
|
||||
snd_soc_update_bits(codec,
|
||||
WCD934X_SIDO_NEW_VOUT_D_FREQ2,
|
||||
0x01, 0x0);
|
||||
/* Re-set RDAC gain */
|
||||
snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL,
|
||||
0xF0, 0x0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2273,6 +2637,46 @@ static int tavil_enable_native_supply(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void tavil_codec_hphdelay_lutbypass(struct snd_soc_codec *codec,
|
||||
u16 interp_idx, int event)
|
||||
{
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
u8 hph_dly_mask;
|
||||
u16 hph_lut_bypass_reg = 0;
|
||||
u16 hph_comp_ctrl7 = 0;
|
||||
|
||||
|
||||
switch (interp_idx) {
|
||||
case INTERP_HPHL:
|
||||
hph_dly_mask = 1;
|
||||
hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHL_COMP_LUT;
|
||||
hph_comp_ctrl7 = WCD934X_CDC_COMPANDER1_CTL7;
|
||||
break;
|
||||
case INTERP_HPHR:
|
||||
hph_dly_mask = 2;
|
||||
hph_lut_bypass_reg = WCD934X_CDC_TOP_HPHR_COMP_LUT;
|
||||
hph_comp_ctrl7 = WCD934X_CDC_COMPANDER2_CTL7;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_CLSH_TEST0,
|
||||
hph_dly_mask, 0x0);
|
||||
snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80);
|
||||
if (tavil->hph_mode == CLS_H_ULP)
|
||||
snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20);
|
||||
}
|
||||
|
||||
if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_CLSH_TEST0,
|
||||
hph_dly_mask, hph_dly_mask);
|
||||
snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00);
|
||||
snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0);
|
||||
}
|
||||
}
|
||||
|
||||
static void tavil_codec_hd2_control(struct snd_soc_codec *codec,
|
||||
u16 interp_idx, int event)
|
||||
{
|
||||
|
@ -2291,14 +2695,12 @@ static void tavil_codec_hd2_control(struct snd_soc_codec *codec,
|
|||
}
|
||||
|
||||
if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x14);
|
||||
snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04);
|
||||
}
|
||||
|
||||
if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00);
|
||||
}
|
||||
}
|
||||
|
@ -2333,7 +2735,9 @@ static int tavil_config_compander(struct snd_soc_codec *codec, int interp_n,
|
|||
}
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
|
||||
snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
|
||||
snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
|
||||
snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
|
||||
snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
|
||||
snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
|
||||
|
@ -2404,6 +2808,8 @@ int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec,
|
|||
tavil_codec_idle_detect_control(codec, interp_idx,
|
||||
event);
|
||||
tavil_codec_hd2_control(codec, interp_idx, event);
|
||||
tavil_codec_hphdelay_lutbypass(codec, interp_idx,
|
||||
event);
|
||||
tavil_config_compander(codec, interp_idx, event);
|
||||
}
|
||||
tavil->main_clk_users[interp_idx]++;
|
||||
|
@ -2414,6 +2820,8 @@ int tavil_codec_enable_interp_clk(struct snd_soc_codec *codec,
|
|||
if (tavil->main_clk_users[interp_idx] <= 0) {
|
||||
tavil->main_clk_users[interp_idx] = 0;
|
||||
tavil_config_compander(codec, interp_idx, event);
|
||||
tavil_codec_hphdelay_lutbypass(codec, interp_idx,
|
||||
event);
|
||||
tavil_codec_hd2_control(codec, interp_idx, event);
|
||||
tavil_codec_idle_detect_control(codec, interp_idx,
|
||||
event);
|
||||
|
@ -4196,6 +4604,49 @@ static int tavil_ear_pa_gain_put(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
ucontrol->value.integer.value[0] = tavil->hph_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tavil_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
|
||||
u32 mode_val;
|
||||
|
||||
mode_val = ucontrol->value.enumerated.item[0];
|
||||
|
||||
dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val);
|
||||
|
||||
if (mode_val == 0) {
|
||||
dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n",
|
||||
__func__);
|
||||
mode_val = CLS_H_LOHIFI;
|
||||
}
|
||||
tavil->hph_mode = mode_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const rx_hph_mode_mux_text[] = {
|
||||
"CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
|
||||
"CLS_H_ULP", "CLS_AB_HIFI",
|
||||
};
|
||||
|
||||
static const struct soc_enum rx_hph_mode_mux_enum =
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
|
||||
rx_hph_mode_mux_text);
|
||||
|
||||
static const char *const tavil_anc_func_text[] = {"OFF", "ON"};
|
||||
static const struct soc_enum tavil_anc_func_enum =
|
||||
SOC_ENUM_SINGLE_EXT(2, tavil_anc_func_text);
|
||||
|
||||
/* Cutoff frequency for high pass filter */
|
||||
static const char * const cf_text[] = {
|
||||
"CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
|
||||
|
@ -4352,6 +4803,11 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = {
|
|||
WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0, -84, 40,
|
||||
digital_gain),
|
||||
|
||||
SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, tavil_get_anc_slot,
|
||||
tavil_put_anc_slot),
|
||||
SOC_ENUM_EXT("ANC Function", tavil_anc_func_enum, tavil_get_anc_func,
|
||||
tavil_put_anc_func),
|
||||
|
||||
SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
|
||||
SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
|
||||
SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
|
||||
|
@ -4377,6 +4833,9 @@ static const struct snd_kcontrol_new tavil_snd_controls[] = {
|
|||
SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
|
||||
SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
|
||||
|
||||
SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
|
||||
tavil_rx_hph_mode_get, tavil_rx_hph_mode_put),
|
||||
|
||||
SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
|
||||
tavil_iir_enable_audio_mixer_get,
|
||||
tavil_iir_enable_audio_mixer_put),
|
||||
|
@ -4720,6 +5179,15 @@ static const char * const amic4_5_sel_text[] = {
|
|||
"AMIC4", "AMIC5"
|
||||
};
|
||||
|
||||
static const char * const anc0_fb_mux_text[] = {
|
||||
"ZERO", "ANC_IN_HPHL", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
|
||||
"ANC_IN_LO1"
|
||||
};
|
||||
|
||||
static const char * const anc1_fb_mux_text[] = {
|
||||
"ZERO", "ANC_IN_HPHR", "ANC_IN_LO2"
|
||||
};
|
||||
|
||||
static const char * const rx_echo_mux_text[] = {
|
||||
"ZERO", "RX_MIX0", "RX_MIX1", "RX_MIX2", "RX_MIX3", "RX_MIX4",
|
||||
"RX_MIX5", "RX_MIX6", "RX_MIX7", "RX_MIX8"
|
||||
|
@ -5171,6 +5639,18 @@ WCD_DAPM_ENUM(int4_2_native, SND_SOC_NOPM, 0, native_mux_text);
|
|||
WCD_DAPM_ENUM(int7_2_native, SND_SOC_NOPM, 0, native_mux_text);
|
||||
WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text);
|
||||
|
||||
WCD_DAPM_ENUM(anc0_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text);
|
||||
WCD_DAPM_ENUM(anc1_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text);
|
||||
|
||||
static const struct snd_kcontrol_new anc_ear_switch =
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
|
||||
|
||||
static const struct snd_kcontrol_new anc_ear_spkr_switch =
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
|
||||
|
||||
static const struct snd_kcontrol_new anc_spkr_pa_switch =
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
|
||||
|
||||
static const struct snd_kcontrol_new mad_cpe1_switch =
|
||||
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
|
||||
|
||||
|
@ -5541,6 +6021,9 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
|
|||
|
||||
WCD_DAPM_MUX("AMIC4_5 SEL", 0, tx_amic4_5),
|
||||
|
||||
WCD_DAPM_MUX("ANC0 FB MUX", 0, anc0_fb),
|
||||
WCD_DAPM_MUX("ANC1 FB MUX", 0, anc1_fb),
|
||||
|
||||
SND_SOC_DAPM_INPUT("AMIC1"),
|
||||
SND_SOC_DAPM_INPUT("AMIC2"),
|
||||
SND_SOC_DAPM_INPUT("AMIC3"),
|
||||
|
@ -5772,6 +6255,12 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD934X_ANA_LO_1_2, 6, 0, NULL, 0,
|
||||
tavil_codec_enable_lineout_pa,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD934X_ANA_EAR, 7, 0, NULL, 0,
|
||||
tavil_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
tavil_codec_enable_spkr_anc,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("EAR"),
|
||||
SND_SOC_DAPM_OUTPUT("HPHL"),
|
||||
|
@ -5780,6 +6269,14 @@ static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_OUTPUT("LINEOUT2"),
|
||||
SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
|
||||
SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
|
||||
SND_SOC_DAPM_OUTPUT("ANC EAR"),
|
||||
|
||||
SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0,
|
||||
&anc_ear_switch),
|
||||
SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
|
||||
&anc_ear_spkr_switch),
|
||||
SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
|
||||
&anc_spkr_pa_switch),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0,
|
||||
tavil_codec_enable_rx_bias,
|
||||
|
@ -6710,7 +7207,6 @@ static const struct tavil_reg_mask_val tavil_codec_reg_defaults[] = {
|
|||
{WCD934X_BIAS_VBG_FINE_ADJ, 0xFF, 0x75},
|
||||
{WCD934X_CODEC_CPR_SVS_CX_VDD, 0xFF, 0x7C}, /* value in svs mode */
|
||||
{WCD934X_CODEC_CPR_SVS2_CX_VDD, 0xFF, 0x58}, /* value in svs2 mode */
|
||||
{WCD934X_SIDO_NEW_VOUT_D_FREQ2, 0x01, 0x01},
|
||||
{WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
|
||||
{WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
|
||||
{WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
|
||||
|
@ -6991,6 +7487,7 @@ static int tavil_handle_pdata(struct tavil_priv *tavil,
|
|||
{
|
||||
struct snd_soc_codec *codec = tavil->codec;
|
||||
u8 mad_dmic_ctl_val;
|
||||
u8 anc_ctl_value;
|
||||
u32 def_dmic_rate, dmic_clk_drv;
|
||||
int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
|
||||
int rc = 0;
|
||||
|
@ -7096,6 +7593,20 @@ static int tavil_handle_pdata(struct tavil_priv *tavil,
|
|||
snd_soc_update_bits(codec, WCD934X_CPE_SS_DMIC2_CTL,
|
||||
0x0E, mad_dmic_ctl_val << 1);
|
||||
|
||||
if (dmic_clk_drv == WCD934X_DMIC_CLK_DIV_2)
|
||||
anc_ctl_value = WCD934X_ANC_DMIC_X2_FULL_RATE;
|
||||
else
|
||||
anc_ctl_value = WCD934X_ANC_DMIC_X2_HALF_RATE;
|
||||
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_2_CTL,
|
||||
0x40, anc_ctl_value << 6);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC0_MODE_2_CTL,
|
||||
0x20, anc_ctl_value << 5);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_2_CTL,
|
||||
0x40, anc_ctl_value << 6);
|
||||
snd_soc_update_bits(codec, WCD934X_CDC_ANC1_MODE_2_CTL,
|
||||
0x20, anc_ctl_value << 5);
|
||||
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
@ -7215,8 +7726,8 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec)
|
|||
}
|
||||
/* Class-H Init */
|
||||
wcd_clsh_init(&tavil->clsh_d);
|
||||
/* Default HPH Mode to Class-H HiFi */
|
||||
tavil->hph_mode = CLS_H_HIFI;
|
||||
/* Default HPH Mode to Class-H Low HiFi */
|
||||
tavil->hph_mode = CLS_H_LOHIFI;
|
||||
|
||||
tavil->fw_data = devm_kzalloc(codec->dev, sizeof(*(tavil->fw_data)),
|
||||
GFP_KERNEL);
|
||||
|
@ -7310,6 +7821,12 @@ static int tavil_soc_codec_probe(struct snd_soc_codec *codec)
|
|||
if (IS_ERR_OR_NULL(tavil->dsd_config))
|
||||
dev_dbg(tavil->dev, "%s: DSD init failed\n", __func__);
|
||||
|
||||
mutex_lock(&tavil->codec_mutex);
|
||||
snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
|
||||
snd_soc_dapm_disable_pin(dapm, "ANC EAR");
|
||||
snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
|
||||
mutex_unlock(&tavil->codec_mutex);
|
||||
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
tavil_wdsp_initialize(codec);
|
||||
|
@ -7929,6 +8446,7 @@ static int tavil_probe(struct platform_device *pdev)
|
|||
tavil->swr.plat_data.bulk_write = tavil_swrm_bulk_write;
|
||||
tavil->swr.plat_data.clk = tavil_swrm_clock;
|
||||
tavil->swr.plat_data.handle_irq = tavil_swrm_handle_irq;
|
||||
tavil->swr.spkr_gain_offset = WCD934X_RX_GAIN_OFFSET_0_DB;
|
||||
|
||||
/* Register for Clock */
|
||||
wcd_ext_clk = clk_get(tavil->wcd9xxx->dev, "wcd_clk");
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
#define WCD934X_DMIC_CLK_DIV_16 0x5
|
||||
#define WCD934X_DMIC_CLK_DRIVE_DEFAULT 0x02
|
||||
|
||||
#define WCD934X_ANC_DMIC_X2_FULL_RATE 1
|
||||
#define WCD934X_ANC_DMIC_X2_HALF_RATE 0
|
||||
|
||||
#define TAVIL_MAX_MICBIAS 4
|
||||
#define TAVIL_NUM_INTERPOLATORS 9
|
||||
#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
|
||||
|
|
|
@ -237,10 +237,16 @@ static const char *mode_to_str(int mode)
|
|||
return "CLS_H_NORMAL";
|
||||
case CLS_H_HIFI:
|
||||
return "CLS_H_HIFI";
|
||||
case CLS_H_LOHIFI:
|
||||
return "CLS_H_LOHIFI";
|
||||
case CLS_H_LP:
|
||||
return "CLS_H_LP";
|
||||
case CLS_H_ULP:
|
||||
return "CLS_H_ULP";
|
||||
case CLS_AB:
|
||||
return "CLS_AB";
|
||||
case CLS_AB_HIFI:
|
||||
return "CLS_AB_HIFI";
|
||||
default:
|
||||
return "CLS_H_INVALID";
|
||||
};
|
||||
|
@ -332,7 +338,8 @@ static inline void wcd_clsh_set_int_mode(struct wcd_clsh_cdc_data *clsh_d,
|
|||
static inline void wcd_clsh_set_buck_mode(struct snd_soc_codec *codec,
|
||||
int mode)
|
||||
{
|
||||
if (mode == CLS_H_HIFI)
|
||||
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
|
||||
mode == CLS_AB_HIFI || mode == CLS_AB)
|
||||
snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES,
|
||||
0x08, 0x08); /* set to HIFI */
|
||||
else
|
||||
|
@ -343,7 +350,8 @@ static inline void wcd_clsh_set_buck_mode(struct snd_soc_codec *codec,
|
|||
static inline void wcd_clsh_set_flyback_mode(struct snd_soc_codec *codec,
|
||||
int mode)
|
||||
{
|
||||
if (mode == CLS_H_HIFI)
|
||||
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
|
||||
mode == CLS_AB_HIFI || mode == CLS_AB)
|
||||
snd_soc_update_bits(codec, WCD9XXX_A_ANA_RX_SUPPLIES,
|
||||
0x04, 0x04); /* set to HIFI */
|
||||
else
|
||||
|
@ -351,6 +359,55 @@ static inline void wcd_clsh_set_flyback_mode(struct snd_soc_codec *codec,
|
|||
0x04, 0x00); /* set to Default */
|
||||
}
|
||||
|
||||
static inline void wcd_clsh_gm3_boost_disable(struct snd_soc_codec *codec,
|
||||
int mode)
|
||||
{
|
||||
struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
|
||||
|
||||
if (!IS_CODEC_TYPE(wcd9xxx, WCD934X))
|
||||
return;
|
||||
|
||||
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
|
||||
mode == CLS_AB_HIFI || mode == CLS_AB) {
|
||||
snd_soc_update_bits(codec, WCD9XXX_HPH_CNP_WG_CTL,
|
||||
0x80, 0x0); /* disable GM3 Boost */
|
||||
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4,
|
||||
0xF0, 0x80);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, WCD9XXX_HPH_CNP_WG_CTL,
|
||||
0x80, 0x80); /* set to Default */
|
||||
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4,
|
||||
0xF0, 0x70);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void wcd_clsh_force_iq_ctl(struct snd_soc_codec *codec,
|
||||
int mode)
|
||||
{
|
||||
struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
|
||||
|
||||
if (!IS_CODEC_TYPE(wcd9xxx, WCD934X))
|
||||
return;
|
||||
|
||||
if (mode == CLS_H_LOHIFI || mode == CLS_AB) {
|
||||
snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2,
|
||||
0x20, 0x20);
|
||||
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER,
|
||||
0xF0, 0xC0);
|
||||
snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1,
|
||||
0x0E, 0x02);
|
||||
} else {
|
||||
|
||||
snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2,
|
||||
0x20, 0x0);
|
||||
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER,
|
||||
0xF0, 0x80);
|
||||
snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1,
|
||||
0x0E, 0x06);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec,
|
||||
struct wcd_clsh_cdc_data *clsh_d,
|
||||
int mode,
|
||||
|
@ -386,7 +443,7 @@ static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec,
|
|||
(1 << 6), (enable << 6));
|
||||
/* 100usec delay is needed as per HW requirement */
|
||||
usleep_range(100, 110);
|
||||
if (enable && (TASHA_IS_1_1(wcd9xxx->version))) {
|
||||
if (enable && (TASHA_IS_1_1(wcd9xxx))) {
|
||||
wcd_clsh_set_flyback_mode(codec, CLS_H_HIFI);
|
||||
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_EN,
|
||||
0x60, 0x40);
|
||||
|
@ -427,7 +484,7 @@ static void wcd_clsh_set_gain_path(struct snd_soc_codec *codec,
|
|||
u8 val = 0;
|
||||
struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
|
||||
|
||||
if (!TASHA_IS_2_0(wcd9xxx->version))
|
||||
if (!TASHA_IS_2_0(wcd9xxx))
|
||||
return;
|
||||
|
||||
switch (mode) {
|
||||
|
@ -470,11 +527,26 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec,
|
|||
gain = DAC_GAIN_0DB;
|
||||
ipeak = DELTA_I_50MA;
|
||||
break;
|
||||
case CLS_AB_HIFI:
|
||||
val = 0x08;
|
||||
break;
|
||||
case CLS_H_HIFI:
|
||||
val = 0x08;
|
||||
gain = DAC_GAIN_M0P2DB;
|
||||
ipeak = DELTA_I_50MA;
|
||||
break;
|
||||
case CLS_H_LOHIFI:
|
||||
val = 0x00;
|
||||
if ((IS_CODEC_TYPE(wcd9xxx, WCD9335)) ||
|
||||
(IS_CODEC_TYPE(wcd9xxx, WCD9326))) {
|
||||
val = 0x08;
|
||||
gain = DAC_GAIN_M0P2DB;
|
||||
ipeak = DELTA_I_50MA;
|
||||
}
|
||||
break;
|
||||
case CLS_H_ULP:
|
||||
val = 0x0C;
|
||||
break;
|
||||
case CLS_H_LP:
|
||||
val = 0x04;
|
||||
ipeak = DELTA_I_30MA;
|
||||
|
@ -483,8 +555,16 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec,
|
|||
return;
|
||||
};
|
||||
|
||||
/*
|
||||
* For tavil set mode to Lower_power for
|
||||
* CLS_H_LOHIFI and CLS_AB
|
||||
*/
|
||||
if ((IS_CODEC_TYPE(wcd9xxx, WCD934X)) &&
|
||||
(mode == CLS_H_LOHIFI || mode == CLS_AB))
|
||||
val = 0x04;
|
||||
|
||||
snd_soc_update_bits(codec, WCD9XXX_A_ANA_HPH, 0x0C, val);
|
||||
if (TASHA_IS_2_0(wcd9xxx->version)) {
|
||||
if (TASHA_IS_2_0(wcd9xxx)) {
|
||||
snd_soc_update_bits(codec, WCD9XXX_CLASSH_CTRL_VCL_2,
|
||||
0x30, (res_val << 4));
|
||||
if (mode != CLS_H_LP)
|
||||
|
@ -515,7 +595,7 @@ static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode)
|
|||
{
|
||||
struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
|
||||
|
||||
if (!TASHA_IS_2_0(wcd9xxx->version))
|
||||
if (!TASHA_IS_2_0(wcd9xxx))
|
||||
return;
|
||||
|
||||
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A);
|
||||
|
@ -538,7 +618,7 @@ static void wcd_clsh_state_lo(struct snd_soc_codec *codec,
|
|||
dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode),
|
||||
is_enable ? "enable" : "disable");
|
||||
|
||||
if (mode != CLS_AB) {
|
||||
if (mode != CLS_AB && mode != CLS_AB_HIFI) {
|
||||
dev_err(codec->dev, "%s: LO cannot be in this mode: %d\n",
|
||||
__func__, mode);
|
||||
return;
|
||||
|
@ -586,7 +666,8 @@ static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec,
|
|||
WCD_CLSH_STATE_HPHR);
|
||||
else
|
||||
return;
|
||||
if (hph_mode != CLS_AB && !is_native_44_1_active(codec))
|
||||
if (hph_mode != CLS_AB && hph_mode != CLS_AB_HIFI
|
||||
&& !is_native_44_1_active(codec))
|
||||
snd_soc_update_bits(codec,
|
||||
WCD9XXX_A_CDC_RX0_RX_PATH_CFG0,
|
||||
0x40, 0x40);
|
||||
|
@ -795,6 +876,7 @@ static void wcd_clsh_state_hph_lo(struct snd_soc_codec *codec,
|
|||
hph_mode);
|
||||
|
||||
if ((hph_mode == CLS_AB) ||
|
||||
(hph_mode == CLS_AB_HIFI) ||
|
||||
(hph_mode == CLS_NONE))
|
||||
goto end;
|
||||
|
||||
|
@ -843,7 +925,7 @@ static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec,
|
|||
dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode),
|
||||
is_enable ? "enable" : "disable");
|
||||
|
||||
if (mode == CLS_AB)
|
||||
if (mode == CLS_AB || mode == CLS_AB_HIFI)
|
||||
return;
|
||||
|
||||
if (is_enable) {
|
||||
|
@ -881,7 +963,7 @@ static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
|
|||
}
|
||||
|
||||
if (is_enable) {
|
||||
if (mode != CLS_AB) {
|
||||
if (mode != CLS_AB && mode != CLS_AB_HIFI) {
|
||||
wcd_enable_clsh_block(codec, clsh_d, true);
|
||||
/*
|
||||
* These K1 values depend on the Headphone Impedance
|
||||
|
@ -897,6 +979,8 @@ static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
|
|||
}
|
||||
wcd_clsh_set_buck_regulator_mode(codec, mode);
|
||||
wcd_clsh_set_flyback_mode(codec, mode);
|
||||
wcd_clsh_gm3_boost_disable(codec, mode);
|
||||
wcd_clsh_force_iq_ctl(codec, mode);
|
||||
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
|
||||
wcd_clsh_set_flyback_current(codec, mode);
|
||||
wcd_clsh_set_buck_mode(codec, mode);
|
||||
|
@ -906,7 +990,7 @@ static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
|
|||
} else {
|
||||
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
|
||||
|
||||
if (mode != CLS_AB) {
|
||||
if (mode != CLS_AB && mode != CLS_AB_HIFI) {
|
||||
snd_soc_update_bits(codec,
|
||||
WCD9XXX_A_CDC_RX2_RX_PATH_CFG0,
|
||||
0x40, 0x00);
|
||||
|
@ -915,6 +999,8 @@ static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
|
|||
/* buck and flyback set to default mode and disable */
|
||||
wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
|
||||
wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
|
||||
wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_gm3_boost_disable(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL);
|
||||
|
@ -935,7 +1021,7 @@ static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
|
|||
}
|
||||
|
||||
if (is_enable) {
|
||||
if (mode != CLS_AB) {
|
||||
if (mode != CLS_AB && mode != CLS_AB_HIFI) {
|
||||
wcd_enable_clsh_block(codec, clsh_d, true);
|
||||
/*
|
||||
* These K1 values depend on the Headphone Impedance
|
||||
|
@ -951,6 +1037,8 @@ static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
|
|||
}
|
||||
wcd_clsh_set_buck_regulator_mode(codec, mode);
|
||||
wcd_clsh_set_flyback_mode(codec, mode);
|
||||
wcd_clsh_gm3_boost_disable(codec, mode);
|
||||
wcd_clsh_force_iq_ctl(codec, mode);
|
||||
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
|
||||
wcd_clsh_set_flyback_current(codec, mode);
|
||||
wcd_clsh_set_buck_mode(codec, mode);
|
||||
|
@ -960,7 +1048,7 @@ static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
|
|||
} else {
|
||||
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
|
||||
|
||||
if (mode != CLS_AB) {
|
||||
if (mode != CLS_AB && mode != CLS_AB_HIFI) {
|
||||
snd_soc_update_bits(codec,
|
||||
WCD9XXX_A_CDC_RX1_RX_PATH_CFG0,
|
||||
0x40, 0x00);
|
||||
|
@ -969,6 +1057,8 @@ static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
|
|||
/* set buck and flyback to Default Mode */
|
||||
wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
|
||||
wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
|
||||
wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_gm3_boost_disable(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL);
|
||||
wcd_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL);
|
||||
|
|
|
@ -61,8 +61,10 @@ enum {
|
|||
CLS_H_NORMAL = 0, /* Class-H Default */
|
||||
CLS_H_HIFI, /* Class-H HiFi */
|
||||
CLS_H_LP, /* Class-H Low Power */
|
||||
CLS_AB, /* Class-AB */
|
||||
CLS_AB, /* Class-AB Low HIFI*/
|
||||
CLS_H_LOHIFI, /* LoHIFI */
|
||||
CLS_H_ULP, /* Ultra Low power */
|
||||
CLS_AB_HIFI, /* Class-AB */
|
||||
CLS_NONE, /* None of the above modes */
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue