summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorMark Brown2009-06-07 14:21:24 +0200
committerMark Brown2009-06-08 14:51:59 +0200
commit81628103dd8527d99ea39b054a3f002d5859d7c3 (patch)
tree0a3f003eb84a6378786f8c86c23599344eebe8f6 /sound/soc/soc-dapm.c
parentASoC: Sort specialised mixers and muxes together (diff)
downloadkernel-qcow2-linux-81628103dd8527d99ea39b054a3f002d5859d7c3.tar.gz
kernel-qcow2-linux-81628103dd8527d99ea39b054a3f002d5859d7c3.tar.xz
kernel-qcow2-linux-81628103dd8527d99ea39b054a3f002d5859d7c3.zip
ASoC: Coalesce power updates for DAPM widgets with events
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c76
1 files changed, 60 insertions, 16 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 9187db18a042..3fc791c28aa8 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -740,7 +740,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
struct list_head *pending)
{
struct snd_soc_dapm_widget *w;
- int reg, power;
+ int reg, power, ret;
unsigned int value = 0;
unsigned int mask = 0;
unsigned int cur_mask;
@@ -764,13 +764,62 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
pop_dbg(codec->pop_time,
"pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
w->name, reg, value, mask);
+
+ /* power up pre event */
+ if (w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
+ pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n",
+ w->name);
+ ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
+ if (ret < 0)
+ pr_err("%s: pre event failed: %d\n",
+ w->name, ret);
+ }
+
+ /* power down pre event */
+ if (!w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
+ pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n",
+ w->name);
+ ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
+ if (ret < 0)
+ pr_err("%s: pre event failed: %d\n",
+ w->name, ret);
+ }
+ }
+
+ if (reg >= 0) {
+ pop_dbg(codec->pop_time,
+ "pop test : Applying 0x%x/0x%x to %x in %dms\n",
+ value, mask, reg, codec->pop_time);
+ pop_wait(codec->pop_time);
+ snd_soc_update_bits(codec, reg, mask, value);
}
- pop_dbg(codec->pop_time,
- "pop test : Applying 0x%x/0x%x to %x in %dms\n",
- value, mask, reg, codec->pop_time);
- pop_wait(codec->pop_time);
- snd_soc_update_bits(codec, reg, mask, value);
+ list_for_each_entry(w, pending, power_list) {
+ /* power up post event */
+ if (w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
+ pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n",
+ w->name);
+ ret = w->event(w,
+ NULL, SND_SOC_DAPM_POST_PMU);
+ if (ret < 0)
+ pr_err("%s: post event failed: %d\n",
+ w->name, ret);
+ }
+
+ /* power down post event */
+ if (!w->power && w->event &&
+ (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
+ pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n",
+ w->name);
+ ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
+ if (ret < 0)
+ pr_err("%s: post event failed: %d\n",
+ w->name, ret);
+ }
+ }
}
/* Apply a DAPM power sequence.
@@ -843,16 +892,11 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
break;
default:
- /* If there's an event or an invalid register
- * then run immediately, otherwise store the
- * updates so that we can coalesce. */
- if (w->reg >= 0 && !w->event) {
- cur_sort = sort[w->id];
- cur_reg = w->reg;
- list_move(&w->power_list, &pending);
- } else {
- ret = dapm_generic_apply_power(w);
- }
+ /* Queue it up for application */
+ cur_sort = sort[w->id];
+ cur_reg = w->reg;
+ list_move(&w->power_list, &pending);
+ break;
}
if (ret < 0)