Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ecf8184 authored by Laxminath Kasam's avatar Laxminath Kasam Committed by Gerrit - the friendly Code Review server
Browse files

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



On lagoon, vdd-buck need to be dynamic supply.
Add required support to handle buck as dynamic supply.

Change-Id: If6c27fffe0d0c44f178e61a6eae6ef63775c8988
Signed-off-by: default avatarLaxminath Kasam <lkasam@codeaurora.org>
parent 93afa626
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
@@ -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,