ASoC: wcd9335: Adjust DMIC clock based on sample rate

Currently DMIC clock is set at 4.8MHz for all sampling rates. For
optimal power, sampling rates <=48KHz should be set to 2.4MHz.

CRs-fixed: 971183
Change-Id: If3076f017d476cfb57fa22b75cc74ed615c8882e
Signed-off-by: Stephen Oglesby <soglesby@codeaurora.org>
Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
This commit is contained in:
Stephen Oglesby 2016-03-01 16:29:23 -08:00 committed by Kyle Yan
parent f47eab663e
commit 9fca33dfb6

View file

@ -5429,6 +5429,67 @@ out:
return ret; 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, static u8 tasha_get_dmic_clk_val(struct snd_soc_codec *codec,
u32 mclk_rate, u32 dmic_clk_rate) 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; s32 *dmic_clk_cnt;
u8 dmic_rate_val, dmic_rate_shift = 1; u8 dmic_rate_val, dmic_rate_shift = 1;
unsigned int dmic; unsigned int dmic;
u32 dmic_sample_rate;
int ret; int ret;
char *wname; char *wname;
@ -5554,10 +5616,15 @@ static int tasha_codec_enable_dmic(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
dmic_sample_rate = tasha_get_dmic_sample_rate(codec, dmic,
pdata);
dmic_rate_val = dmic_rate_val =
tasha_get_dmic_clk_val(codec, tasha_get_dmic_clk_val(codec,
pdata->mclk_rate, 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)++; (*dmic_clk_cnt)++;
if (*dmic_clk_cnt == 1) { 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; struct snd_soc_codec *codec = tasha->codec;
u8 dmic_ctl_val, mad_dmic_ctl_val; u8 dmic_ctl_val, mad_dmic_ctl_val;
u8 anc_ctl_value;
u32 def_dmic_rate, dmic_clk_drv; u32 def_dmic_rate, dmic_clk_drv;
int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4; int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
int rc = 0; int rc = 0;
@ -12020,19 +12086,8 @@ static int tasha_handle_pdata(struct tasha_priv *tasha,
pdata->mclk_rate, pdata->mclk_rate,
pdata->dmic_sample_rate); pdata->dmic_sample_rate);
if (dmic_ctl_val == WCD9335_DMIC_CLK_DIV_2) tasha_set_anc_dmic_mode(codec, dmic_ctl_val);
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);
done: done:
return rc; return rc;
} }