Commit 163cac06 authored by Mark Brown's avatar Mark Brown

ASoC: Factor out DAPM sequence execution

Lump the list walk into a single function, and pull in the power
application too so we can do some further refactoring. Pure code
motion.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 38357ab2
...@@ -707,79 +707,89 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) ...@@ -707,79 +707,89 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
return power; return power;
} }
/* static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
* Scan a single DAPM widget for a complete audio path and update the struct snd_soc_dapm_widget *b,
* power status appropriately. int sort[])
*/ {
static int dapm_power_widget(struct snd_soc_codec *codec, int event, if (sort[a->id] != sort[b->id])
struct snd_soc_dapm_widget *w) return sort[a->id] - sort[b->id];
return 0;
}
/* Insert a widget in order into a DAPM power sequence. */
static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
struct list_head *list,
int sort[])
{
struct snd_soc_dapm_widget *w;
list_for_each_entry(w, list, power_list)
if (dapm_seq_compare(new_widget, w, sort) < 0) {
list_add_tail(&new_widget->power_list, &w->power_list);
return;
}
list_add_tail(&new_widget->power_list, list);
}
/* Apply a DAPM power sequence */
static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
int event)
{ {
struct snd_soc_dapm_widget *w;
int ret; int ret;
list_for_each_entry(w, list, power_list) {
switch (w->id) { switch (w->id) {
case snd_soc_dapm_pre: case snd_soc_dapm_pre:
if (!w->event) if (!w->event)
return 0; list_for_each_entry_continue(w, list,
power_list);
if (event == SND_SOC_DAPM_STREAM_START) { if (event == SND_SOC_DAPM_STREAM_START) {
ret = w->event(w, ret = w->event(w,
NULL, SND_SOC_DAPM_PRE_PMU); NULL, SND_SOC_DAPM_PRE_PMU);
if (ret < 0) if (ret < 0)
return ret; pr_err("PRE widget failed: %d\n",
ret);
} else if (event == SND_SOC_DAPM_STREAM_STOP) { } else if (event == SND_SOC_DAPM_STREAM_STOP) {
ret = w->event(w, ret = w->event(w,
NULL, SND_SOC_DAPM_PRE_PMD); NULL, SND_SOC_DAPM_PRE_PMD);
if (ret < 0) if (ret < 0)
return ret; pr_err("PRE widget failed: %d\n",
ret);
} }
return 0; break;
case snd_soc_dapm_post: case snd_soc_dapm_post:
if (!w->event) if (!w->event)
return 0; list_for_each_entry_continue(w, list,
power_list);
if (event == SND_SOC_DAPM_STREAM_START) { if (event == SND_SOC_DAPM_STREAM_START) {
ret = w->event(w, ret = w->event(w,
NULL, SND_SOC_DAPM_POST_PMU); NULL, SND_SOC_DAPM_POST_PMU);
if (ret < 0) if (ret < 0)
return ret; pr_err("POST widget failed: %d\n",
ret);
} else if (event == SND_SOC_DAPM_STREAM_STOP) { } else if (event == SND_SOC_DAPM_STREAM_STOP) {
ret = w->event(w, ret = w->event(w,
NULL, SND_SOC_DAPM_POST_PMD); NULL, SND_SOC_DAPM_POST_PMD);
if (ret < 0) if (ret < 0)
return ret; pr_err("POST widget failed: %d\n",
ret);
} }
return 0; break;
default: default:
return dapm_generic_apply_power(w); ret = dapm_generic_apply_power(w);
if (ret < 0)
pr_err("Failed to apply widget power: %d\n",
ret);
break;
} }
}
static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
struct snd_soc_dapm_widget *b,
int sort[])
{
if (sort[a->id] != sort[b->id])
return sort[a->id] - sort[b->id];
return 0;
}
/* Insert a widget in order into a DAPM power sequence. */
static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
struct list_head *list,
int sort[])
{
struct snd_soc_dapm_widget *w;
list_for_each_entry(w, list, power_list)
if (dapm_seq_compare(new_widget, w, sort) < 0) {
list_add_tail(&new_widget->power_list, &w->power_list);
return;
} }
list_add_tail(&new_widget->power_list, list);
} }
/* /*
...@@ -847,20 +857,10 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) ...@@ -847,20 +857,10 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
} }
/* Power down widgets first; try to avoid amplifying pops. */ /* Power down widgets first; try to avoid amplifying pops. */
list_for_each_entry(w, &codec->down_list, power_list) { dapm_seq_run(codec, &codec->down_list, event);
ret = dapm_power_widget(codec, event, w);
if (ret != 0)
pr_err("Failed to power down %s: %d\n",
w->name, ret);
}
/* Now power up. */ /* Now power up. */
list_for_each_entry(w, &codec->up_list, power_list) { dapm_seq_run(codec, &codec->up_list, event);
ret = dapm_power_widget(codec, event, w);
if (ret != 0)
pr_err("Failed to power up %s: %d\n",
w->name, 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 (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment