diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-09-29 11:20:59 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-29 11:20:58 -0700 |
| commit | e18b1f64decbf4d8c5fd1feb6b649ed556b6b268 (patch) | |
| tree | fc595550bae03edb30bfc622ff6b121060005b78 | |
| parent | 71acb6aa276c96bf0f5d2bfe2f3cd9c6799e8c06 (diff) | |
| parent | 74c432dc9a7e60668c06f155e9db0506abcdaacd (diff) | |
Merge "ASoC: wcd934x: Avoid pop during dsd path tear down"
| -rw-r--r-- | sound/soc/codecs/wcd934x/wcd934x-dsd.c | 36 | ||||
| -rw-r--r-- | sound/soc/codecs/wcd934x/wcd934x.c | 56 |
2 files changed, 71 insertions, 21 deletions
diff --git a/sound/soc/codecs/wcd934x/wcd934x-dsd.c b/sound/soc/codecs/wcd934x/wcd934x-dsd.c index 246b3bfab876..55072466af55 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-dsd.c +++ b/sound/soc/codecs/wcd934x/wcd934x-dsd.c @@ -378,6 +378,14 @@ static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, int interp_idx; u8 pcm_rate_val; + if (!dsd_conf) { + dev_err(codec->dev, "%s: null dsd_config pointer\n", __func__); + return -EINVAL; + } + + dev_dbg(codec->dev, "%s: DSD%d, event: %d\n", __func__, + w->shift, event); + if (w->shift == DSD0) { /* Read out select */ if (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & 0x02) @@ -422,10 +430,6 @@ static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, snd_soc_write(codec, WCD934X_CDC_DSD0_CFG1, dsd_conf->volume[DSD0]); - if (clk_users > 1) - snd_soc_update_bits(codec, - WCD934X_CDC_DSD0_CFG2, - 0x04, 0x00); } else if (w->shift == DSD1) { snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, 0x02, 0x02); @@ -436,26 +440,35 @@ static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, /* Apply Gain */ snd_soc_write(codec, WCD934X_CDC_DSD1_CFG1, dsd_conf->volume[DSD1]); + } + /* 10msec sleep required after DSD clock is set */ + usleep_range(10000, 10100); - if (clk_users > 1) + if (clk_users > 1) { + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); + if (w->shift == DSD0) + snd_soc_update_bits(codec, + WCD934X_CDC_DSD0_CFG2, + 0x04, 0x00); + if (w->shift == DSD1) snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x00); + } - /* 10msec sleep required after DSD clock is set */ - usleep_range(10000, 10100); break; case SND_SOC_DAPM_POST_PMD: if (w->shift == DSD0) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, - 0x01, 0x00); snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, 0x04, 0x04); - } else if (w->shift == DSD1) { - snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_PATH_CTL, 0x01, 0x00); + } else if (w->shift == DSD1) { snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, 0x04, 0x04); + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_PATH_CTL, + 0x01, 0x00); } tavil_codec_enable_interp_clk(codec, event, interp_idx); @@ -466,6 +479,7 @@ static int tavil_enable_dsd(struct snd_soc_dapm_widget *w, WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x01, 0x00); tavil_dsd_data_pull(codec, 0x03, 0x04, false); + tavil_dsd_reset(dsd_conf); } break; } diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index e959a43c6c42..56a2ab8ed285 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -1404,6 +1404,34 @@ static int tavil_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai, return ret; } +static void tavil_codec_mute_dsd(struct snd_soc_codec *codec, + struct list_head *ch_list) +{ + u8 dsd0_in; + u8 dsd1_in; + struct wcd9xxx_ch *ch; + + /* Read DSD Input Ports */ + dsd0_in = (snd_soc_read(codec, WCD934X_CDC_DSD0_CFG0) & 0x3C) >> 2; + dsd1_in = (snd_soc_read(codec, WCD934X_CDC_DSD1_CFG0) & 0x3C) >> 2; + + if ((dsd0_in == 0) && (dsd1_in == 0)) + return; + + /* + * Check if the ports getting disabled are connected to DSD inputs. + * If connected, enable DSD mute to avoid DC entering into DSD Filter + */ + list_for_each_entry(ch, ch_list, list) { + if (ch->port == (dsd0_in + WCD934X_RX_PORT_START_NUMBER - 1)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD0_CFG2, + 0x04, 0x04); + if (ch->port == (dsd1_in + WCD934X_RX_PORT_START_NUMBER - 1)) + snd_soc_update_bits(codec, WCD934X_CDC_DSD1_CFG2, + 0x04, 0x04); + } +} + static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1413,6 +1441,7 @@ static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec); int ret = 0; struct wcd9xxx_codec_dai_data *dai; + struct tavil_dsd_config *dsd_conf = tavil_p->dsd_config; core = dev_get_drvdata(codec->dev->parent); @@ -1435,6 +1464,9 @@ static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w, &dai->grph); break; case SND_SOC_DAPM_POST_PMD: + if (dsd_conf) + tavil_codec_mute_dsd(codec, &dai->wcd9xxx_ch_list); + ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list, dai->grph); dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n", @@ -1771,6 +1803,12 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, (0x03 << 1)); set_bit(HPH_PA_DELAY, &tavil->status_mask); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { + /* Set regulator mode to AB if DSD is enabled */ + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); + } break; case SND_SOC_DAPM_POST_PMU: /* @@ -1797,13 +1835,9 @@ static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, WCD934X_CDC_RX2_RX_PATH_MIX_CTL, 0x10, 0x00); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) { - /* Set regulator mode to AB if DSD is enabled */ - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x02, 0x02); + (snd_soc_read(codec, WCD934X_CDC_DSD1_PATH_CTL) & 0x01)) 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: @@ -1840,6 +1874,12 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL, 0x06, (0x03 << 1)); set_bit(HPH_PA_DELAY, &tavil->status_mask); + if (dsd_conf && + (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) { + /* Set regulator mode to AB if DSD is enabled */ + snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, + 0x02, 0x02); + } break; case SND_SOC_DAPM_POST_PMU: /* @@ -1866,13 +1906,9 @@ static int tavil_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, WCD934X_CDC_RX1_RX_PATH_MIX_CTL, 0x10, 0x00); if (dsd_conf && - (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) { - /* Set regulator mode to AB if DSD is enabled */ - snd_soc_update_bits(codec, WCD934X_ANA_RX_SUPPLIES, - 0x02, 0x02); + (snd_soc_read(codec, WCD934X_CDC_DSD0_PATH_CTL) & 0x01)) 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: |
