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

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

ASoC: sdm660_cdc: Update micbias regulator to power saving on use basis



In internal codec, MICBIAS regulator uses LDO7B power rail.
Add changes to remove voting for voltage and current
when this regulator is not in use from audio to save power.

CRs-Fixed: 2033776
Change-Id: I3c7cea4afadd293a03787081895d451bcf7bea03
Signed-off-by: default avatarLaxminath Kasam <lkasam@codeaurora.org>
parent e3c33c9d
Loading
Loading
Loading
Loading
+86 −7
Original line number Diff line number Diff line
@@ -1400,8 +1400,26 @@ static int msm_anlg_cdc_codec_enable_on_demand_supply(
	}
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (atomic_inc_return(&supply->ref) == 1)
		if (atomic_inc_return(&supply->ref) == 1) {
			ret = regulator_set_voltage(supply->supply,
						    supply->min_uv,
						    supply->max_uv);
			if (ret) {
				dev_err(codec->dev,
					"Setting regulator voltage(en) for micbias with err = %d\n",
					ret);
				goto out;
			}
			ret = regulator_set_load(supply->supply,
						 supply->optimum_ua);
			if (ret < 0) {
				dev_err(codec->dev,
					"Setting regulator optimum mode(en) failed for micbias with err = %d\n",
					ret);
				goto out;
			}
			ret = regulator_enable(supply->supply);
		}
		if (ret)
			dev_err(codec->dev, "%s: Failed to enable %s\n",
				__func__,
@@ -1413,12 +1431,27 @@ static int msm_anlg_cdc_codec_enable_on_demand_supply(
				 __func__, on_demand_supply_name[w->shift]);
			goto out;
		}
		if (atomic_dec_return(&supply->ref) == 0)
		if (atomic_dec_return(&supply->ref) == 0) {
			ret = regulator_disable(supply->supply);
			if (ret)
				dev_err(codec->dev, "%s: Failed to disable %s\n",
					__func__,
					on_demand_supply_name[w->shift]);
			ret = regulator_set_voltage(supply->supply,
						    0,
						    supply->max_uv);
			if (ret) {
				dev_err(codec->dev,
					"Setting regulator voltage(dis) failed for micbias with err = %d\n",
					ret);
				goto out;
			}
			ret = regulator_set_load(supply->supply, 0);
			if (ret < 0)
				dev_err(codec->dev,
					"Setting regulator optimum mode(dis) failed for micbias with err = %d\n",
					ret);
		}
		break;
	default:
		break;
@@ -3685,6 +3718,30 @@ static struct regulator *msm_anlg_cdc_find_regulator(
	return NULL;
}

static void msm_anlg_cdc_update_micbias_regulator(
				const struct sdm660_cdc_priv *sdm660_cdc,
				const char *name,
				struct on_demand_supply *micbias_supply)
{
	int i;
	struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data;

	for (i = 0; i < sdm660_cdc->num_of_supplies; i++) {
		if (sdm660_cdc->supplies[i].supply &&
		    !strcmp(sdm660_cdc->supplies[i].supply, name)) {
			micbias_supply->supply =
				sdm660_cdc->supplies[i].consumer;
			micbias_supply->min_uv = pdata->regulator[i].min_uv;
			micbias_supply->max_uv = pdata->regulator[i].max_uv;
			micbias_supply->optimum_ua =
					pdata->regulator[i].optimum_ua;
			return;
		}
	}

	dev_err(sdm660_cdc->dev, "Error: regulator not found:%s\n", name);
}

static int msm_anlg_cdc_device_down(struct snd_soc_codec *codec)
{
	struct msm_asoc_mach_data *pdata = NULL;
@@ -4128,10 +4185,10 @@ static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec)

	wcd9xxx_spmi_set_codec(codec);

	sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS].supply =
				msm_anlg_cdc_find_regulator(
	msm_anlg_cdc_update_micbias_regulator(
				sdm660_cdc,
				on_demand_supply_name[ON_DEMAND_MICBIAS]);
				on_demand_supply_name[ON_DEMAND_MICBIAS],
				&sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS]);
	atomic_set(&sdm660_cdc->on_demand_list[ON_DEMAND_MICBIAS].ref,
		   0);

@@ -4331,6 +4388,28 @@ static int msm_anlg_cdc_init_supplies(struct sdm660_cdc_priv *sdm660_cdc,
		if (regulator_count_voltages(
			sdm660_cdc->supplies[i].consumer) <= 0)
			continue;
		if (pdata->regulator[i].ondemand) {
			ret = regulator_set_voltage(
					sdm660_cdc->supplies[i].consumer,
					0, pdata->regulator[i].max_uv);
			if (ret) {
				dev_err(sdm660_cdc->dev,
					"Setting regulator voltage failed for regulator %s err = %d\n",
					sdm660_cdc->supplies[i].supply, ret);
				goto err_supplies;
			}
			ret = regulator_set_load(
				sdm660_cdc->supplies[i].consumer, 0);
			if (ret < 0) {
				dev_err(sdm660_cdc->dev,
					"Setting regulator optimum mode failed for regulator %s err = %d\n",
					sdm660_cdc->supplies[i].supply, ret);
				goto err_supplies;
			} else {
				ret = 0;
				continue;
			}
		}
		ret = regulator_set_voltage(sdm660_cdc->supplies[i].consumer,
					    pdata->regulator[i].min_uv,
					    pdata->regulator[i].max_uv);
+3 −0
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ struct sdm660_cdc_regulator {
struct on_demand_supply {
	struct regulator *supply;
	atomic_t ref;
	int min_uv;
	int max_uv;
	int optimum_ua;
};

struct wcd_imped_i_ref {