diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 87c9477ad1..46c0937ea4 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/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, diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 4c3b507fec..6fb76a9362 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/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 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,17 +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); - if (!is_dmic_sva) - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, false); + SWR_REGISTER_WAKEUP, &dmic_sva); + msm_cdc_pinctrl_set_wakeup_capable( + tx_priv->tx_swr_gpio_p, false); } else { - if (!is_dmic_sva) - msm_cdc_pinctrl_set_wakeup_capable( - tx_priv->tx_swr_gpio_p, true); + /* while teardown we can reset the flag */ + dmic_sva = 0; + msm_cdc_pinctrl_set_wakeup_capable( + 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); } } @@ -3324,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; diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index a37eb16322..760537b623 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/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 { @@ -3229,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; diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 41981aa593..9ac809b198 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/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); diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index b2853b399a..4f2080cb32 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2458,6 +2458,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)) { @@ -2779,7 +2781,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; @@ -2798,7 +2799,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) || @@ -2817,6 +2818,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( @@ -2890,7 +2894,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); @@ -2913,7 +2917,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; @@ -2932,11 +2935,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)) { @@ -3005,6 +3003,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( @@ -3018,10 +3018,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); @@ -3353,10 +3354,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) { diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index c8444032d8..f6d5a186d6 100644 --- a/soc/swr-mstr-ctrl.h +++ b/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;