summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Oglesby <soglesby@codeaurora.org>2016-03-01 16:29:23 -0800
committerKyle Yan <kyan@codeaurora.org>2016-06-14 14:44:04 -0700
commit9fca33dfb64a271c82cb3f4caaf89ce7dabf95f9 (patch)
tree32aa9aca01c15af1a9b0b623416aec3141cfd47f
parentf47eab663ee4dc99a5c4e10b2495376d5f38d8e3 (diff)
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>
-rwxr-xr-xsound/soc/codecs/wcd9335.c83
1 files changed, 69 insertions, 14 deletions
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;
}