From 1c2c0e84de7158b46136faf4c5b761528192788c Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Mon, 22 Aug 2016 15:28:24 +0800 Subject: ASoC: wcd934x: 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 and dmic clock <=2.4MHz, it should be set to the value read from device tree and others should be set to 2.4MHz. Change-Id: If68fea97d2f0b27432e61d73d6841a2b194bb63b Signed-off-by: Meng Wang --- sound/soc/codecs/wcd934x/wcd934x.c | 55 +++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 631727fbdd8c..d01a83a8b193 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -2428,6 +2428,56 @@ out: return ret; } +static u32 tavil_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 < WCD934X_MAX_VALID_ADC_MUX) { + if (adc_mux_index < 4) { + adc_mux_ctl_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + + (adc_mux_index * 2); + } else if (adc_mux_index < WCD934X_INVALID_ADC_MUX) { + adc_mux_ctl_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + + adc_mux_index - 4; + } else if (adc_mux_index == WCD934X_INVALID_ADC_MUX) { + ++adc_mux_index; + continue; + } + adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) & + 0xF8) >> 3) - 1; + + if (adc_mux_sel == dmic) { + dec_found = true; + break; + } + + ++adc_mux_index; + } + + if (dec_found && adc_mux_index <= 8) { + tx_fs_reg = WCD934X_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index); + tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F; + if (tx_stream_fs <= 4) { + if (pdata->dmic_sample_rate <= + WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) + dmic_fs = pdata->dmic_sample_rate; + else + dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ; + } else + dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ; + } else { + dmic_fs = pdata->dmic_sample_rate; + } + + return dmic_fs; +} + static u8 tavil_get_dmic_clk_val(struct snd_soc_codec *codec, u32 mclk_rate, u32 dmic_clk_rate) { @@ -2511,6 +2561,7 @@ static int tavil_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; @@ -2553,10 +2604,12 @@ static int tavil_codec_enable_dmic(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: + dmic_sample_rate = tavil_get_dmic_sample_rate(codec, dmic, + pdata); dmic_rate_val = tavil_get_dmic_clk_val(codec, pdata->mclk_rate, - pdata->dmic_sample_rate); + dmic_sample_rate); (*dmic_clk_cnt)++; if (*dmic_clk_cnt == 1) { -- cgit v1.2.3