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

Commit 56fba41f authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: Specify target bias state directly as a bias state



Rather than a simple flag to say if we want the DAPM context to be at full
power specify the target bias state. This should have no current effect
but is a bit more direct and so makes it easier to change our decisions
about the which bias state to go into in future.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarLiam Girdwood <lrg@ti.com>
parent 6dffdea7
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -510,7 +510,7 @@ struct snd_soc_dapm_context {
	struct snd_soc_card *card; /* parent card */
	struct snd_soc_card *card; /* parent card */


	/* used during DAPM updates */
	/* used during DAPM updates */
	int dev_power;
	enum snd_soc_bias_level target_bias_level;
	struct list_head list;
	struct list_head list;


#ifdef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
+4 −4
Original line number Original line Diff line number Diff line
@@ -214,10 +214,10 @@
 * @OFF:     Power Off. No restrictions on transition times.
 * @OFF:     Power Off. No restrictions on transition times.
 */
 */
enum snd_soc_bias_level {
enum snd_soc_bias_level {
	SND_SOC_BIAS_OFF,
	SND_SOC_BIAS_OFF = 0,
	SND_SOC_BIAS_STANDBY,
	SND_SOC_BIAS_STANDBY = 1,
	SND_SOC_BIAS_PREPARE,
	SND_SOC_BIAS_PREPARE = 2,
	SND_SOC_BIAS_ON,
	SND_SOC_BIAS_ON = 3,
};
};


struct snd_jack;
struct snd_jack;
+33 −27
Original line number Original line Diff line number Diff line
@@ -1042,16 +1042,17 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
	struct snd_soc_dapm_context *d = data;
	struct snd_soc_dapm_context *d = data;
	int ret;
	int ret;


	if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
	/* If we're off and we're not supposed to be go into STANDBY */
	if (d->bias_level == SND_SOC_BIAS_OFF &&
	    d->target_bias_level != SND_SOC_BIAS_OFF) {
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
		if (ret != 0)
		if (ret != 0)
			dev_err(d->dev,
			dev_err(d->dev,
				"Failed to turn on bias: %d\n", ret);
				"Failed to turn on bias: %d\n", ret);
	}
	}


	/* If we're changing to all on or all off then prepare */
	/* Prepare for a STADDBY->ON or ON->STANDBY transition */
	if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
	if (d->bias_level != d->target_bias_level) {
	    (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
		if (ret != 0)
		if (ret != 0)
			dev_err(d->dev,
			dev_err(d->dev,
@@ -1068,7 +1069,9 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
	int ret;
	int ret;


	/* If we just powered the last thing off drop to standby bias */
	/* If we just powered the last thing off drop to standby bias */
	if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
	if (d->bias_level == SND_SOC_BIAS_PREPARE &&
	    (d->target_bias_level == SND_SOC_BIAS_STANDBY ||
	     d->target_bias_level == SND_SOC_BIAS_OFF)) {
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
		if (ret != 0)
		if (ret != 0)
			dev_err(d->dev, "Failed to apply standby bias: %d\n",
			dev_err(d->dev, "Failed to apply standby bias: %d\n",
@@ -1076,14 +1079,16 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
	}
	}


	/* If we're in standby and can support bias off then do that */
	/* If we're in standby and can support bias off then do that */
	if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) {
	if (d->bias_level == SND_SOC_BIAS_STANDBY &&
	    d->target_bias_level == SND_SOC_BIAS_OFF) {
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
		if (ret != 0)
		if (ret != 0)
			dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
			dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
	}
	}


	/* If we just powered up then move to active bias */
	/* If we just powered up then move to active bias */
	if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
	if (d->bias_level == SND_SOC_BIAS_PREPARE &&
	    d->target_bias_level == SND_SOC_BIAS_ON) {
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
		ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
		if (ret != 0)
		if (ret != 0)
			dev_err(d->dev, "Failed to apply active bias: %d\n",
			dev_err(d->dev, "Failed to apply active bias: %d\n",
@@ -1108,13 +1113,19 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
	LIST_HEAD(up_list);
	LIST_HEAD(up_list);
	LIST_HEAD(down_list);
	LIST_HEAD(down_list);
	LIST_HEAD(async_domain);
	LIST_HEAD(async_domain);
	enum snd_soc_bias_level bias;
	int power;
	int power;


	trace_snd_soc_dapm_start(card);
	trace_snd_soc_dapm_start(card);


	list_for_each_entry(d, &card->dapm_list, list)
	list_for_each_entry(d, &card->dapm_list, list) {
		if (d->n_widgets || d->codec == NULL)
		if (d->n_widgets || d->codec == NULL) {
			d->dev_power = 0;
			if (d->idle_bias_off)
				d->target_bias_level = SND_SOC_BIAS_OFF;
			else
				d->target_bias_level = SND_SOC_BIAS_STANDBY;
		}
	}


	/* Check which widgets we need to power and store them in
	/* Check which widgets we need to power and store them in
	 * lists indicating if they should be powered up or down.
	 * lists indicating if they should be powered up or down.
@@ -1137,7 +1148,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
			else
			else
				power = 1;
				power = 1;
			if (power)
			if (power)
				w->dapm->dev_power = 1;
				w->dapm->target_bias_level = SND_SOC_BIAS_ON;


			if (w->power == power)
			if (w->power == power)
				continue;
				continue;
@@ -1161,24 +1172,19 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
		switch (event) {
		switch (event) {
		case SND_SOC_DAPM_STREAM_START:
		case SND_SOC_DAPM_STREAM_START:
		case SND_SOC_DAPM_STREAM_RESUME:
		case SND_SOC_DAPM_STREAM_RESUME:
			dapm->dev_power = 1;
			dapm->target_bias_level = SND_SOC_BIAS_ON;
			break;
			break;
		case SND_SOC_DAPM_STREAM_STOP:
		case SND_SOC_DAPM_STREAM_STOP:
			dapm->dev_power = !!dapm->codec->active;
			if (dapm->codec->active)
				dapm->target_bias_level = SND_SOC_BIAS_ON;
			else
				dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
			break;
			break;
		case SND_SOC_DAPM_STREAM_SUSPEND:
		case SND_SOC_DAPM_STREAM_SUSPEND:
			dapm->dev_power = 0;
			dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
			break;
			break;
		case SND_SOC_DAPM_STREAM_NOP:
		case SND_SOC_DAPM_STREAM_NOP:
			switch (dapm->bias_level) {
			dapm->target_bias_level = dapm->bias_level;
				case SND_SOC_BIAS_STANDBY:
				case SND_SOC_BIAS_OFF:
					dapm->dev_power = 0;
					break;
				default:
					dapm->dev_power = 1;
					break;
			}
			break;
			break;
		default:
		default:
			break;
			break;
@@ -1186,12 +1192,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
	}
	}


	/* Force all contexts in the card to the same bias state */
	/* Force all contexts in the card to the same bias state */
	power = 0;
	bias = SND_SOC_BIAS_OFF;
	list_for_each_entry(d, &card->dapm_list, list)
	list_for_each_entry(d, &card->dapm_list, list)
		if (d->dev_power)
		if (d->target_bias_level > bias)
			power = 1;
			bias = d->target_bias_level;
	list_for_each_entry(d, &card->dapm_list, list)
	list_for_each_entry(d, &card->dapm_list, list)
		d->dev_power = power;
		d->target_bias_level = bias;




	/* Run all the bias changes in parallel */
	/* Run all the bias changes in parallel */