Browse Source

Merge "soc: mstr-ctrl: Retain Audio_HM voting until suspend"

qctecmdr 4 years ago
parent
commit
0f5df347f1

+ 3 - 2
asoc/codecs/bolero/bolero-cdc.c

@@ -1094,7 +1094,7 @@ EXPORT_SYMBOL(bolero_tx_mclk_enable);
  * Returns 0 on success or -EINVAL on error.
  */
 int bolero_register_event_listener(struct snd_soc_component *component,
-				   bool enable)
+				   bool enable, bool is_dmic_sva)
 {
 	struct bolero_priv *priv = NULL;
 	int ret = 0;
@@ -1113,7 +1113,8 @@ int bolero_register_event_listener(struct snd_soc_component *component,
 
 	if (priv->macro_params[TX_MACRO].reg_evt_listener)
 		ret = priv->macro_params[TX_MACRO].reg_evt_listener(component,
-								    enable);
+								    enable,
+								    is_dmic_sva);
 
 	return ret;
 }

+ 4 - 3
asoc/codecs/bolero/bolero-cdc.h

@@ -77,7 +77,8 @@ struct macro_ops {
 			    u32 size, void *data);
 	int (*clk_div_get)(struct snd_soc_component *component);
 	int (*clk_switch)(struct snd_soc_component *component, int clk_src);
-	int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
+	int (*reg_evt_listener)(struct snd_soc_component *component,
+			bool en, bool is_dmic_sva);
 	int (*clk_enable)(struct snd_soc_component *c, bool en);
 	char __iomem *io_base;
 	u16 clk_id_req;
@@ -104,7 +105,7 @@ int bolero_runtime_suspend(struct device *dev);
 int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
 int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src);
 int bolero_register_event_listener(struct snd_soc_component *component,
-				   bool enable);
+				   bool enable, bool is_dmic_sva);
 void bolero_wsa_pa_on(struct device *dev);
 bool bolero_check_core_votes(struct device *dev);
 int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable);
@@ -178,7 +179,7 @@ static inline int bolero_tx_clk_switch(struct snd_soc_component *component,
 
 static inline int bolero_register_event_listener(
 					struct snd_soc_component *component,
-					bool enable)
+					bool enable, bool is_dmic_sva)
 {
 	return 0;
 }

+ 2 - 0
asoc/codecs/bolero/rx-macro.c

@@ -378,6 +378,7 @@ struct rx_swr_ctrl_platform_data {
 							  void *data),
 			  void *swrm_handle,
 			  int action);
+	int (*pinctrl_setup)(void *handle, bool enable);
 };
 
 enum {
@@ -4104,6 +4105,7 @@ static int rx_macro_probe(struct platform_device *pdev)
 	rx_priv->swr_plat_data.clk = rx_swrm_clock;
 	rx_priv->swr_plat_data.core_vote = rx_macro_core_vote;
 	rx_priv->swr_plat_data.handle_irq = NULL;
+	rx_priv->swr_plat_data.pinctrl_setup = NULL;
 
 	ret = of_property_read_u8_array(pdev->dev.of_node,
 				"qcom,rx-bcl-pmic-params", bcl_pmic_params,

+ 27 - 5
asoc/codecs/bolero/tx-macro.c

@@ -81,6 +81,7 @@ struct tx_macro_swr_ctrl_platform_data {
 							  void *data),
 			  void *swrm_handle,
 			  int action);
+	int (*pinctrl_setup)(void *handle, bool enable);
 };
 
 enum {
@@ -2496,12 +2497,30 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
 		       tx_macro_get_bcs, tx_macro_set_bcs),
 };
 
+static int tx_macro_pinctrl_setup(void *handle, bool enable)
+{
+	struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
+
+	if (tx_priv == NULL) {
+		pr_err("%s: tx priv data is NULL\n", __func__);
+		return -EINVAL;
+	}
+	if (enable)
+		msm_cdc_pinctrl_set_wakeup_capable(
+			tx_priv->tx_swr_gpio_p, true);
+	else
+		msm_cdc_pinctrl_set_wakeup_capable(
+			tx_priv->tx_swr_gpio_p, false);
+	return 0;
+}
+
 static int tx_macro_register_event_listener(struct snd_soc_component *component,
-					    bool enable)
+					    bool enable, bool is_dmic_sva)
 {
 	struct device *tx_dev = NULL;
 	struct tx_macro_priv *tx_priv = NULL;
 	int ret = 0;
+	u32 dmic_sva = is_dmic_sva;
 
 	if (!component)
 		return -EINVAL;
@@ -2523,15 +2542,17 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component,
 		if (enable) {
 			ret = swrm_wcd_notify(
 				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
-				SWR_REGISTER_WAKEUP, NULL);
+				SWR_REGISTER_WAKEUP, &dmic_sva);
 			msm_cdc_pinctrl_set_wakeup_capable(
-					tx_priv->tx_swr_gpio_p, false);
+				tx_priv->tx_swr_gpio_p, false);
 		} else {
+			/* while teardown we can reset the flag */
+			dmic_sva = 0;
 			msm_cdc_pinctrl_set_wakeup_capable(
-					tx_priv->tx_swr_gpio_p, true);
+				tx_priv->tx_swr_gpio_p, true);
 			ret = swrm_wcd_notify(
 				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
-				SWR_DEREGISTER_WAKEUP, NULL);
+				SWR_DEREGISTER_WAKEUP, &dmic_sva);
 		}
 	}
 
@@ -3322,6 +3343,7 @@ static int tx_macro_probe(struct platform_device *pdev)
 		tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
 		tx_priv->swr_plat_data.core_vote = tx_macro_core_vote;
 		tx_priv->swr_plat_data.handle_irq = NULL;
+		tx_priv->swr_plat_data.pinctrl_setup = tx_macro_pinctrl_setup;
 		mutex_init(&tx_priv->swr_clk_lock);
 	}
 	tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio;

+ 69 - 2
asoc/codecs/bolero/va-macro.c

@@ -130,6 +130,7 @@ struct va_macro_swr_ctrl_platform_data {
 							  void *data),
 			  void *swrm_handle,
 			  int action);
+	int (*pinctrl_setup)(void *handle, bool enable);
 };
 
 struct va_macro_priv {
@@ -459,14 +460,14 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
 				dev_dbg(va_dev, "%s: clock switch failed\n",
 					__func__);
 		if (va_priv->lpi_enable) {
-			bolero_register_event_listener(component, true);
+			bolero_register_event_listener(component, true, false);
 			va_priv->register_event_listener = true;
 		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		if (va_priv->register_event_listener) {
 			va_priv->register_event_listener = false;
-			bolero_register_event_listener(component, false);
+			bolero_register_event_listener(component, false, false);
 		}
 		if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
 			dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
@@ -482,6 +483,45 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
 	return ret;
 }
 
+static int va_macro_swr_intr_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *va_dev = NULL;
+	struct va_macro_priv *va_priv = NULL;
+
+	if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n",
+		__func__, event, va_priv->lpi_enable);
+
+	if (!va_priv->lpi_enable)
+		return ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (va_priv->lpi_enable) {
+			bolero_register_event_listener(component, true, true);
+			va_priv->register_event_listener = true;
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (va_priv->register_event_listener) {
+			va_priv->register_event_listener = false;
+			bolero_register_event_listener(component, false, true);
+		}
+		break;
+	default:
+		dev_err(va_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
 static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
@@ -1989,6 +2029,10 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = {
 	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
 			      va_macro_swr_pwr_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0,
+			      va_macro_swr_intr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
@@ -2133,6 +2177,10 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
 			      va_macro_mclk_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0,
+			      va_macro_swr_intr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = {
@@ -2279,6 +2327,15 @@ static const struct snd_soc_dapm_route va_audio_map_v3[] = {
 	{"VA SMIC MUX3", "SWR_MIC9", "VA SWR_INPUT"},
 	{"VA SMIC MUX3", "SWR_MIC10", "VA SWR_INPUT"},
 	{"VA SMIC MUX3", "SWR_MIC11", "VA SWR_INPUT"},
+
+	{"VA DMIC0", NULL, "VA_SWR_INTR"},
+	{"VA DMIC1", NULL, "VA_SWR_INTR"},
+	{"VA DMIC2", NULL, "VA_SWR_INTR"},
+	{"VA DMIC3", NULL, "VA_SWR_INTR"},
+	{"VA DMIC4", NULL, "VA_SWR_INTR"},
+	{"VA DMIC5", NULL, "VA_SWR_INTR"},
+	{"VA DMIC6", NULL, "VA_SWR_INTR"},
+	{"VA DMIC7", NULL, "VA_SWR_INTR"},
 };
 
 static const struct snd_soc_dapm_route va_audio_map_v2[] = {
@@ -2515,6 +2572,15 @@ static const struct snd_soc_dapm_route va_audio_map[] = {
 	{"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"},
 	{"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"},
 
+	{"VA DMIC0", NULL, "VA_SWR_INTR"},
+	{"VA DMIC1", NULL, "VA_SWR_INTR"},
+	{"VA DMIC2", NULL, "VA_SWR_INTR"},
+	{"VA DMIC3", NULL, "VA_SWR_INTR"},
+	{"VA DMIC4", NULL, "VA_SWR_INTR"},
+	{"VA DMIC5", NULL, "VA_SWR_INTR"},
+	{"VA DMIC6", NULL, "VA_SWR_INTR"},
+	{"VA DMIC7", NULL, "VA_SWR_INTR"},
+
 	{"VA SWR_ADC0", NULL, "VA_SWR_PWR"},
 	{"VA SWR_ADC1", NULL, "VA_SWR_PWR"},
 	{"VA SWR_ADC2", NULL, "VA_SWR_PWR"},
@@ -3164,6 +3230,7 @@ static int va_macro_probe(struct platform_device *pdev)
 		va_priv->swr_plat_data.clk = va_macro_swrm_clock;
 		va_priv->swr_plat_data.core_vote = va_macro_core_vote;
 		va_priv->swr_plat_data.handle_irq = NULL;
+		va_priv->swr_plat_data.pinctrl_setup = NULL;
 		mutex_init(&va_priv->swr_clk_lock);
 	}
 	va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio;

+ 2 - 0
asoc/codecs/bolero/wsa-macro.c

@@ -166,6 +166,7 @@ struct wsa_macro_swr_ctrl_platform_data {
 							  void *data),
 			  void *swrm_handle,
 			  int action);
+	int (*pinctrl_setup)(void *handle, bool enable);
 };
 
 struct wsa_macro_bcl_pmic_params {
@@ -3194,6 +3195,7 @@ static int wsa_macro_probe(struct platform_device *pdev)
 	wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
 	wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote;
 	wsa_priv->swr_plat_data.handle_irq = NULL;
+	wsa_priv->swr_plat_data.pinctrl_setup = NULL;
 
 	ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
 				   &default_clk_id);

+ 13 - 10
soc/swr-mstr-ctrl.c

@@ -2469,6 +2469,8 @@ static int swrm_probe(struct platform_device *pdev)
 		ret = -EINVAL;
 		goto err_pdata_fail;
 	}
+	swrm->pinctrl_setup = pdata->pinctrl_setup;
+
 	if (of_property_read_u32(pdev->dev.of_node,
 			"qcom,swr-clock-stop-mode0",
 			&swrm->clk_stop_mode0_supp)) {
@@ -2801,7 +2803,6 @@ static int swrm_runtime_resume(struct device *dev)
 	int ret = 0;
 	bool swrm_clk_req_err = false;
 	bool hw_core_err = false;
-	bool aud_core_err = false;
 	struct swr_master *mstr = &swrm->master;
 	struct swr_device *swr_dev;
 	u32 temp = 0;
@@ -2820,7 +2821,7 @@ static int swrm_runtime_resume(struct device *dev)
 	if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
 		dev_err(dev, "%s:lpass audio hw enable failed\n",
 			__func__);
-		aud_core_err = true;
+		swrm->aud_core_err = true;
 	}
 
 	if ((swrm->state == SWR_MSTR_DOWN) ||
@@ -2839,6 +2840,9 @@ static int swrm_runtime_resume(struct device *dev)
 				    irq_get_irq_data(swrm->wake_irq)))
 					disable_irq_nosync(swrm->wake_irq);
 				mutex_unlock(&swrm->irq_lock);
+				if (swrm->dmic_sva && swrm->pinctrl_setup)
+					swrm->pinctrl_setup(swrm->handle,
+							    false);
 			}
 			if (swrm->ipc_wakeup)
 				msm_aud_evt_blocking_notifier_call_chain(
@@ -2912,7 +2916,7 @@ static int swrm_runtime_resume(struct device *dev)
 		swrm->state = SWR_MSTR_UP;
 	}
 exit:
-	if (!aud_core_err)
+	if (ret && !swrm->aud_core_err)
 		swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
 	if (!hw_core_err)
 		swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
@@ -2935,7 +2939,6 @@ static int swrm_runtime_suspend(struct device *dev)
 	struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
 	int ret = 0;
 	bool hw_core_err = false;
-	bool aud_core_err = false;
 	struct swr_master *mstr = &swrm->master;
 	struct swr_device *swr_dev;
 	int current_state = 0;
@@ -2954,11 +2957,6 @@ static int swrm_runtime_suspend(struct device *dev)
 			__func__);
 		hw_core_err = true;
 	}
-	if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
-		dev_err(dev, "%s:lpass audio hw enable failed\n",
-			__func__);
-		aud_core_err = true;
-	}
 
 	if ((current_state == SWR_MSTR_UP) ||
 	    (current_state == SWR_MSTR_SSR)) {
@@ -3027,6 +3025,8 @@ static int swrm_runtime_suspend(struct device *dev)
 
 		if (swrm->clk_stop_mode0_supp) {
 			if (swrm->wake_irq > 0) {
+				if (swrm->dmic_sva && swrm->pinctrl_setup)
+					swrm->pinctrl_setup(swrm->handle, true);
 				enable_irq(swrm->wake_irq);
 			} else if (swrm->ipc_wakeup) {
 				msm_aud_evt_blocking_notifier_call_chain(
@@ -3040,10 +3040,11 @@ static int swrm_runtime_suspend(struct device *dev)
 	if (current_state != SWR_MSTR_SSR)
 		swrm->state = SWR_MSTR_DOWN;
 exit:
-	if (!aud_core_err)
+	if (!swrm->aud_core_err)
 		swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
 	if (!hw_core_err)
 		swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
+	swrm->aud_core_err = false;
 	mutex_unlock(&swrm->reslock);
 	trace_printk("%s: pm_runtime: suspend done state: %d\n",
 		__func__, swrm->state);
@@ -3375,10 +3376,12 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
 	case SWR_REGISTER_WAKEUP:
 		msm_aud_evt_blocking_notifier_call_chain(
 					SWR_WAKE_IRQ_REGISTER, (void *)swrm);
+		swrm->dmic_sva = *(u32 *)data;
 		break;
 	case SWR_DEREGISTER_WAKEUP:
 		msm_aud_evt_blocking_notifier_call_chain(
 					SWR_WAKE_IRQ_DEREGISTER, (void *)swrm);
+		swrm->dmic_sva = 0;
 		break;
 	case SWR_SET_PORT_MAP:
 		if (!data) {

+ 4 - 0
soc/swr-mstr-ctrl.h

@@ -115,6 +115,7 @@ struct swr_ctrl_platform_data {
 	int (*core_vote)(void *handle, bool enable);
 	int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq,
 			void *data), void *swr_handle, int type);
+	int (*pinctrl_setup)(void *handle, bool enable);
 };
 
 struct swr_mstr_ctrl {
@@ -148,6 +149,7 @@ struct swr_mstr_ctrl {
 	int (*core_vote)(void *handle, bool enable);
 	int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq,
 			void *data), void *swr_handle, int type);
+	int (*pinctrl_setup)(void *handle, bool enable);
 	int irq;
 	int wake_irq;
 	int version;
@@ -173,8 +175,10 @@ struct swr_mstr_ctrl {
 	u32 clk_stop_mode0_supp;
 	struct work_struct wakeup_work;
 	u32 ipc_wakeup;
+	u32 dmic_sva;
 	bool dev_up;
 	bool ipc_wakeup_triggered;
+	bool aud_core_err;
 	struct pm_qos_request pm_qos_req;
 	enum swrm_pm_state pm_state;
 	wait_queue_head_t pm_wq;