diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 8c7ab5a8f358..178a77ac39e2 100755 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -5429,6 +5429,67 @@ out: return ret; } +static void tasha_set_anc_dmic_mode(struct snd_soc_codec *codec, + u8 dmic_ctl_val) +{ + u8 anc_ctl_value; + + if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2) + anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE; + else + anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE; + + snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, + 0x20, anc_ctl_value << 5); + snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, + 0x40, anc_ctl_value << 6); + snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, + 0x20, anc_ctl_value << 5); +} + +static u32 tasha_get_dmic_sample_rate(struct snd_soc_codec *codec, + unsigned int dmic, struct wcd9xxx_pdata *pdata) +{ + u8 tx_stream_fs; + u8 adc_mux_index = 0, adc_mux_sel = 0; + bool dec_found = false; + u16 adc_mux_ctl_reg, tx_fs_reg; + u32 dmic_fs; + + while (dec_found == 0 && adc_mux_index < WCD9335_MAX_VALID_ADC_MUX) { + if (adc_mux_index < 4) { + adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + (adc_mux_index * 2); + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0x78) >> 3) - 1; + } else if (adc_mux_index < 9) { + adc_mux_ctl_reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + ((adc_mux_index - 4) * 1); + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0x38) >> 3) - 1; + } else if (adc_mux_index == 9) { + continue; + } + if (adc_mux_sel == dmic) + dec_found = true; + else + ++adc_mux_index; + } + + if (dec_found == true && adc_mux_index <= 8) { + tx_fs_reg = WCD9335_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); + tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + dmic_fs = tx_stream_fs <= 4 ? WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ : + WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + } else { + dmic_fs = pdata->dmic_sample_rate; + } + + return dmic_fs; +} + static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec, u32 mclk_rate, u32 dmic_clk_rate) { @@ -5512,6 +5573,7 @@ static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, s32 *dmic_clk_cnt; u8 dmic_rate_val, dmic_rate_shift = 1; unsigned int dmic; + u32 dmic_sample_rate; int ret; char *wname; @@ -5554,10 +5616,15 @@ static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic, + pdata); dmic_rate_val = tasha_get_dmic_clk_val(codec, pdata->mclk_rate, - pdata->dmic_sample_rate); + dmic_sample_rate); + + /* Set ANC dmic control bits to match dmic rate */ + tasha_set_anc_dmic_mode(codec, dmic_rate_val); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { @@ -11910,7 +11977,6 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, { struct snd_soc_codec *codec = tasha->codec; u8 dmic_ctl_val, 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; @@ -12020,19 +12086,8 @@ static int tasha_handle_pdata(struct tasha_priv *tasha, pdata->mclk_rate, pdata->dmic_sample_rate); - if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2) - anc_ctl_value = WCD9335_ANC_DMIC_X2_FULL_RATE; - else - anc_ctl_value = WCD9335_ANC_DMIC_X2_HALF_RATE; + tasha_set_anc_dmic_mode(codec, dmic_ctl_val); - snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, - 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD9335_CDC_ANC0_MODE_2_CTL, - 0x20, anc_ctl_value << 5); - snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, - 0x40, anc_ctl_value << 6); - snd_soc_update_bits(codec, WCD9335_CDC_ANC1_MODE_2_CTL, - 0x20, anc_ctl_value << 5); done: return rc; }