aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-06-07 08:21:24 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-06-08 08:51:59 -0400
commit81628103dd8527d99ea39b054a3f002d5859d7c3 (patch)
tree0a3f003eb84a6378786f8c86c23599344eebe8f6 /sound
parente3d4dabd2d9b74778f6f15a830eb3a0027bb3799 (diff)
ASoC: Coalesce power updates for DAPM widgets with events
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-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,
740 struct list_head *pending) 740 struct list_head *pending)
741{ 741{
742 struct snd_soc_dapm_widget *w; 742 struct snd_soc_dapm_widget *w;
743 int reg, power; 743 int reg, power, ret;
744 unsigned int value = 0; 744 unsigned int value = 0;
745 unsigned int mask = 0; 745 unsigned int mask = 0;
746 unsigned int cur_mask; 746 unsigned int cur_mask;
@@ -764,13 +764,62 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
764 pop_dbg(codec->pop_time, 764 pop_dbg(codec->pop_time,
765 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 765 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
766 w->name, reg, value, mask); 766 w->name, reg, value, mask);
767
768 /* power up pre event */
769 if (w->power && w->event &&
770 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
771 pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n",
772 w->name);
773 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
774 if (ret < 0)
775 pr_err("%s: pre event failed: %d\n",
776 w->name, ret);
777 }
778
779 /* power down pre event */
780 if (!w->power && w->event &&
781 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
782 pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n",
783 w->name);
784 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
785 if (ret < 0)
786 pr_err("%s: pre event failed: %d\n",
787 w->name, ret);
788 }
789 }
790
791 if (reg >= 0) {
792 pop_dbg(codec->pop_time,
793 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
794 value, mask, reg, codec->pop_time);
795 pop_wait(codec->pop_time);
796 snd_soc_update_bits(codec, reg, mask, value);
767 } 797 }
768 798
769 pop_dbg(codec->pop_time, 799 list_for_each_entry(w, pending, power_list) {
770 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 800 /* power up post event */
771 value, mask, reg, codec->pop_time); 801 if (w->power && w->event &&
772 pop_wait(codec->pop_time); 802 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
773 snd_soc_update_bits(codec, reg, mask, value); 803 pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n",
804 w->name);
805 ret = w->event(w,
806 NULL, SND_SOC_DAPM_POST_PMU);
807 if (ret < 0)
808 pr_err("%s: post event failed: %d\n",
809 w->name, ret);
810 }
811
812 /* power down post event */
813 if (!w->power && w->event &&
814 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
815 pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n",
816 w->name);
817 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
818 if (ret < 0)
819 pr_err("%s: post event failed: %d\n",
820 w->name, ret);
821 }
822 }
774} 823}
775 824
776/* Apply a DAPM power sequence. 825/* Apply a DAPM power sequence.
@@ -843,16 +892,11 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
843 break; 892 break;
844 893
845 default: 894 default:
846 /* If there's an event or an invalid register 895 /* Queue it up for application */
847 * then run immediately, otherwise store the 896 cur_sort = sort[w->id];
848 * updates so that we can coalesce. */ 897 cur_reg = w->reg;
849 if (w->reg >= 0 && !w->event) { 898 list_move(&w->power_list, &pending);
850 cur_sort = sort[w->id]; 899 break;
851 cur_reg = w->reg;
852 list_move(&w->power_list, &pending);
853 } else {
854 ret = dapm_generic_apply_power(w);
855 }
856 } 900 }
857 901
858 if (ret < 0) 902 if (ret < 0)