Browse Source

asoc: codecs: Update LPM voting support for vdd-mic-bias-supply

For power saving during RBSC, need to vote for minimum
or zero current on load for respective regulator to
enter LPM mode. Add required support from rouleur
to vote for mic bias accordingly during suspend/resume.

Change-Id: Idb2accbc77241e19f688225081e1b68b99c19e29
Signed-off-by: Aditya Bavanari <[email protected]>
Aditya Bavanari 4 years ago
parent
commit
5423077cb8
2 changed files with 60 additions and 4 deletions
  1. 1 0
      asoc/codecs/rouleur/internal.h
  2. 59 4
      asoc/codecs/rouleur/rouleur.c

+ 1 - 0
asoc/codecs/rouleur/internal.h

@@ -50,6 +50,7 @@ struct rouleur_priv {
 
 	bool comp1_enable;
 	bool comp2_enable;
+	bool dapm_bias_off;
 
 	struct irq_domain *virq;
 	struct wcd_irq_info irq_info;

+ 59 - 4
asoc/codecs/rouleur/rouleur.c

@@ -46,6 +46,7 @@ enum {
 	HPH_COMP_DELAY,
 	HPH_PA_DELAY,
 	AMIC2_BCS_ENABLE,
+	WCD_SUPPLIES_LPM_MODE,
 };
 
 /* TODO: Check on the step values */
@@ -2003,6 +2004,26 @@ static void rouleur_soc_codec_remove(struct snd_soc_component *component)
 						false);
 }
 
+static int rouleur_soc_codec_suspend(struct snd_soc_component *component)
+{
+	struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
+
+	if (!rouleur)
+		return 0;
+	rouleur->dapm_bias_off = true;
+	return 0;
+}
+
+static int rouleur_soc_codec_resume(struct snd_soc_component *component)
+{
+	struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
+
+	if (!rouleur)
+		return 0;
+	rouleur->dapm_bias_off = false;
+	return 0;
+}
+
 static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
 	.name = DRV_NAME,
 	.probe = rouleur_soc_codec_probe,
@@ -2013,6 +2034,8 @@ static const struct snd_soc_component_driver soc_codec_dev_rouleur = {
 	.num_dapm_widgets = ARRAY_SIZE(rouleur_dapm_widgets),
 	.dapm_routes = rouleur_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(rouleur_audio_map),
+	.suspend = rouleur_soc_codec_suspend,
+	.resume = rouleur_soc_codec_resume,
 };
 
 #ifdef CONFIG_PM_SLEEP
@@ -2049,11 +2072,45 @@ static int rouleur_suspend(struct device *dev)
 		}
 		clear_bit(ALLOW_VPOS_DISABLE, &rouleur->status_mask);
 	}
+	if (rouleur->dapm_bias_off) {
+		 msm_cdc_set_supplies_lpm_mode(rouleur->dev,
+					      rouleur->supplies,
+					      pdata->regulator,
+					      pdata->num_supplies,
+					      true);
+		set_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask);
+	}
 	return 0;
 }
 
 static int rouleur_resume(struct device *dev)
 {
+	struct rouleur_priv *rouleur = NULL;
+	struct rouleur_pdata *pdata = NULL;
+
+	if (!dev)
+		return -ENODEV;
+
+	rouleur = dev_get_drvdata(dev);
+	if (!rouleur)
+		return -EINVAL;
+
+	pdata = dev_get_platdata(rouleur->dev);
+
+	if (!pdata) {
+		dev_err(dev, "%s: pdata is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (test_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask)) {
+		msm_cdc_set_supplies_lpm_mode(rouleur->dev,
+						rouleur->supplies,
+						pdata->regulator,
+						pdata->num_supplies,
+						false);
+		clear_bit(WCD_SUPPLIES_LPM_MODE, &rouleur->status_mask);
+	}
+
 	return 0;
 }
 #endif
@@ -2484,10 +2541,8 @@ static int rouleur_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_PM_SLEEP
 static const struct dev_pm_ops rouleur_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(
-		rouleur_suspend,
-		rouleur_resume
-	)
+	.suspend_late = rouleur_suspend,
+	.resume_early = rouleur_resume
 };
 #endif