From 069df14aa0d5ed1c2a0180922e0220c41b87f9be Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Tue, 17 Sep 2019 23:43:34 +0530 Subject: [PATCH] asoc: codecs: Fix pop issue on WSA cold start Observe pop if FS clock is turned on at end of powerup sequence. Ensure WSA PA is turned on after FS clock to avoid pop. Change-Id: Ic1214d361e77db252b7a90a89fc99c69f51e270b Signed-off-by: Laxminath Kasam --- asoc/codecs/bolero/bolero-cdc.c | 23 +++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 4 ++++ asoc/codecs/bolero/internal.h | 1 + asoc/codecs/bolero/wsa-macro.c | 11 ++++++++++- asoc/codecs/wsa881x.c | 16 +++++++++++++++- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index abb88bef45..76c9d40642 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -581,6 +581,29 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) } EXPORT_SYMBOL(bolero_unregister_macro); +void bolero_wsa_pa_on(struct device *dev) +{ + struct bolero_priv *priv; + + if (!dev) { + pr_err("%s: dev is null\n", __func__); + return; + } + if (!bolero_is_valid_child_dev(dev)) { + dev_err(dev, "%s: not a valid child dev\n", + __func__); + return; + } + priv = dev_get_drvdata(dev->parent); + if (!priv) { + dev_err(dev, "%s: priv is null\n", __func__); + return; + } + + bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_ON_POST_FSCLK); +} +EXPORT_SYMBOL(bolero_wsa_pa_on); + static ssize_t bolero_version_read(struct snd_info_entry *entry, void *file_private_data, struct file *file, diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index 8a74e79f54..957389cea2 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -83,6 +83,7 @@ int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *dat int bolero_tx_clk_switch(struct snd_soc_component *component); int bolero_register_event_listener(struct snd_soc_component *component, bool enable); +void bolero_wsa_pa_on(struct device *dev); #else static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb) { @@ -154,5 +155,8 @@ static inline int bolero_register_event_listener( return 0; } +static void bolero_wsa_pa_on(struct device *dev) +{ +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h index d353a2d21b..d3f6894674 100644 --- a/asoc/codecs/bolero/internal.h +++ b/asoc/codecs/bolero/internal.h @@ -15,6 +15,7 @@ enum { BOLERO_WCD_EVT_PA_OFF_PRE_SSR, BOLERO_WCD_EVT_SSR_DOWN, BOLERO_WCD_EVT_SSR_UP, + BOLERO_WCD_EVT_PA_ON_POST_FSCLK, }; enum { diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 4747a96785..3c145b0ead 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -848,6 +848,7 @@ static int wsa_macro_digital_mute(struct snd_soc_dai *dai, int mute) mix_reg, 0x20, 0x20); } } + bolero_wsa_pa_on(wsa_dev); break; default: break; @@ -1422,14 +1423,22 @@ static int wsa_macro_enable_main_path(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); u16 reg = 0; + struct device *wsa_dev = NULL; + struct wsa_macro_priv *wsa_priv = NULL; + + if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__)) + return -EINVAL; + reg = BOLERO_CDC_WSA_RX0_RX_PATH_CTL + WSA_MACRO_RX_PATH_OFFSET * w->shift; switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (wsa_macro_adie_lb(component, w->shift)) + if (wsa_macro_adie_lb(component, w->shift)) { snd_soc_component_update_bits(component, reg, 0x20, 0x20); + bolero_wsa_pa_on(wsa_dev); + } break; default: break; diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c index daafcdc7f3..966fa8a208 100644 --- a/asoc/codecs/wsa881x.c +++ b/asoc/codecs/wsa881x.c @@ -117,6 +117,7 @@ enum { BOLERO_WSA_EVT_PA_OFF_PRE_SSR, BOLERO_WSA_EVT_SSR_DOWN, BOLERO_WSA_EVT_SSR_UP, + BOLERO_WSA_EVT_PA_ON_POST_FSCLK, }; struct wsa_ctrl_platform_data { @@ -1030,6 +1031,10 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMU: + if (!wsa881x->bolero_dev) + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x80); if (!wsa881x->comp_enable) { max_gain = wsa881x->pa_gain; /* @@ -1063,6 +1068,9 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, wsa881x->swr_slave->dev_num); break; case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x00); if (wsa881x->visense_enable) { wsa881x_visense_adc_ctrl(component, DISABLE); wsa881x_visense_txfe_ctrl(component, DISABLE, @@ -1088,7 +1096,7 @@ static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = { wsa881x_rdac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("SPKR PGA", WSA881X_SPKR_DRV_EN, 7, 0, NULL, 0, + SND_SOC_DAPM_PGA_E("SPKR PGA", SND_SOC_NOPM, 0, 0, NULL, 0, wsa881x_spkr_pa_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), @@ -1381,6 +1389,12 @@ static int wsa881x_event_notify(struct notifier_block *nb, WSA881X_SPKR_DRV_EN, 0x80, 0x00); break; + case BOLERO_WSA_EVT_PA_ON_POST_FSCLK: + if ((snd_soc_component_read32(wsa881x->component, + WSA881X_SPKR_DAC_CTL) & 0x80) == 0x80) + snd_soc_component_update_bits(wsa881x->component, + WSA881X_SPKR_DRV_EN, + 0x80, 0x80); default: break; }