Kaynağa Gözat

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 <[email protected]>
Laxminath Kasam 5 yıl önce
ebeveyn
işleme
069df14aa0

+ 23 - 0
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,

+ 4 - 0
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 */

+ 1 - 0
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 {

+ 10 - 1
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;

+ 15 - 1
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;
 	}