Browse Source

Merge "asoc: wcd938x: Add vdd-buck as on demand supply"

qctecmdr 4 years ago
parent
commit
1727055d70
3 changed files with 144 additions and 0 deletions
  1. 41 0
      asoc/codecs/msm-cdc-supply.c
  2. 99 0
      asoc/codecs/wcd938x/wcd938x.c
  3. 4 0
      include/asoc/msm-cdc-supply.h

+ 41 - 0
asoc/codecs/msm-cdc-supply.c

@@ -119,6 +119,47 @@ static int msm_cdc_check_supply_param(struct device *dev,
 	return 0;
 }
 
+/*
+ * msm_cdc_is_ondemand_supply:
+ *	return if ondemand supply true or not
+ *
+ * @dev: pointer to codec device
+ * @supplies: pointer to regulator bulk data
+ * @cdc_vreg: pointer to platform regulator data
+ * @num_supplies: number of supplies
+ * @supply_name: supply name to be checked
+ *
+ * Return true/false
+ */
+bool msm_cdc_is_ondemand_supply(struct device *dev,
+				struct regulator_bulk_data *supplies,
+				struct cdc_regulator *cdc_vreg,
+				int num_supplies,
+				char *supply_name)
+{
+	bool rc = false;
+	int ret, i;
+
+	if ((!supply_name) || (!supplies)) {
+		pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
+				__func__);
+		return rc;
+	}
+	/* input parameter validation */
+	ret = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
+	if (ret)
+		return rc;
+
+	for (i = 0; i < num_supplies; i++) {
+		if (cdc_vreg[i].ondemand &&
+			!strcmp(cdc_vreg[i].name, supply_name))
+			return true;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(msm_cdc_is_ondemand_supply);
+
 /*
  * msm_cdc_disable_ondemand_supply:
  *	Disable codec ondemand supply

+ 99 - 0
asoc/codecs/wcd938x/wcd938x.c

@@ -2563,6 +2563,67 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int wcd938x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
+					 struct snd_kcontrol *kcontrol,
+					 int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+	struct wcd938x_pdata *pdata = NULL;
+	int ret = 0;
+
+	pdata = dev_get_platdata(wcd938x->dev);
+
+	if (!pdata) {
+		dev_err(component->dev, "%s: pdata is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (!msm_cdc_is_ondemand_supply(wcd938x->dev,
+					wcd938x->supplies,
+					pdata->regulator,
+					pdata->num_supplies,
+					"cdc-vdd-buck"))
+		return 0;
+
+	dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
+		w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (test_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask)) {
+			dev_dbg(component->dev,
+				"%s: buck already in enabled state\n",
+				__func__);
+			clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
+			return 0;
+		}
+		ret = msm_cdc_enable_ondemand_supply(wcd938x->dev,
+						wcd938x->supplies,
+						pdata->regulator,
+						pdata->num_supplies,
+						"cdc-vdd-buck");
+		if (ret == -EINVAL) {
+			dev_err(component->dev, "%s: vdd buck is not enabled\n",
+				__func__);
+			return ret;
+		}
+		clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
+		/*
+		 * 200us sleep is required after LDO is enabled as per
+		 * HW requirement
+		 */
+		usleep_range(200, 250);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		set_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
+		break;
+	}
+	return 0;
+}
+
+
 static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_value *ucontrol)
 {
@@ -3111,6 +3172,10 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
 		wcd938x_codec_force_enable_micbias,
 		SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
+	SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0,
+			     wcd938x_codec_enable_vdd_buck,
+			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0,
 			     wcd938x_enable_clsh,
 			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
@@ -3257,6 +3322,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
 	{"WCD_TX_OUTPUT", NULL, "DMIC8_MIXER"},
 	{"DMIC8_MIXER", "Switch", "DMIC8"},
 
+	{"IN1_HPHL", NULL, "VDD_BUCK"},
 	{"IN1_HPHL", NULL, "CLS_H_PORT"},
 	{"RX1", NULL, "IN1_HPHL"},
 	{"RDAC1", NULL, "RX1"},
@@ -3264,6 +3330,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
 	{"HPHL PGA", NULL, "HPHL_RDAC"},
 	{"HPHL", NULL, "HPHL PGA"},
 
+	{"IN2_HPHR", NULL, "VDD_BUCK"},
 	{"IN2_HPHR", NULL, "CLS_H_PORT"},
 	{"RX2", NULL, "IN2_HPHR"},
 	{"RDAC2", NULL, "RX2"},
@@ -3271,6 +3338,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
 	{"HPHR PGA", NULL, "HPHR_RDAC"},
 	{"HPHR", NULL, "HPHR PGA"},
 
+	{"IN3_AUX", NULL, "VDD_BUCK"},
 	{"IN3_AUX", NULL, "CLS_H_PORT"},
 	{"RX3", NULL, "IN3_AUX"},
 	{"RDAC4", NULL, "RX3"},
@@ -4122,6 +4190,37 @@ static int wcd938x_remove(struct platform_device *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int wcd938x_suspend(struct device *dev)
 {
+	struct wcd938x_priv *wcd938x = NULL;
+	int ret = 0;
+	struct wcd938x_pdata *pdata = NULL;
+
+	if (!dev)
+		return -ENODEV;
+
+	wcd938x = dev_get_drvdata(dev);
+	if (!wcd938x)
+		return -EINVAL;
+
+	pdata = dev_get_platdata(wcd938x->dev);
+
+	if (!pdata) {
+		dev_err(dev, "%s: pdata is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (test_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask)) {
+		ret = msm_cdc_disable_ondemand_supply(wcd938x->dev,
+						wcd938x->supplies,
+						pdata->regulator,
+						pdata->num_supplies,
+						"cdc-vdd-buck");
+		if (ret == -EINVAL) {
+			dev_err(dev, "%s: vdd buck is not disabled\n",
+				__func__);
+			return 0;
+		}
+		clear_bit(ALLOW_BUCK_DISABLE, &wcd938x->status_mask);
+	}
 	return 0;
 }
 

+ 4 - 0
include/asoc/msm-cdc-supply.h

@@ -27,6 +27,10 @@ struct cdc_wcd_supply {
 extern int msm_cdc_get_power_supplies(struct device *dev,
 				      struct cdc_regulator **cdc_vreg,
 				      int *total_num_supplies);
+extern bool msm_cdc_is_ondemand_supply(struct device *dev,
+				struct regulator_bulk_data *supplies,
+				struct cdc_regulator *cdc_vreg,
+				int num_supplies, char *supply_name);
 extern int msm_cdc_disable_ondemand_supply(struct device *dev,
 					struct regulator_bulk_data *supplies,
 					struct cdc_regulator *cdc_vreg,