aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-01-15 08:40:50 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-01-19 08:02:32 -0500
commit20e4859dedfc7e7b620d1756b29f8483c5be5fcc (patch)
treee7fff82807a50a5e0930438d7bf2f93826a95ec7
parent828a842f2e02de5d884ee14bd3c21ddbc77ec60e (diff)
ASoC: Add support for sequencing within
With larger devices there may be many widgets of the same type in series in an audio path. Allow drivers to specify an additional level of ordering within each widget type by adding a subsequence number to widgets and then splitting operations on widgets so that widgets of the same type but different sequence numbers are processed separately. A typical example would be a supply widget which requires that another widget be enabled to provide power or clocking. SND_SOC_DAPM_PGA_S() and SND_SOC_DAPM_SUPPLY_S() macros are provided allowing this to be used with PGAs and supplies as these are the most commonly affected widgets. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--include/sound/soc-dapm.h13
-rw-r--r--sound/soc/soc-dapm.c11
2 files changed, 23 insertions, 1 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 8031769ac485..a3760c93a8a3 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -157,6 +157,18 @@
157 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ 157 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \
158 .event = wevent, .event_flags = wflags} 158 .event = wevent, .event_flags = wflags}
159 159
160/* additional sequencing control within an event type */
161#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, wcontrols, \
162 wncontrols, wevent, wflags) \
163{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
164 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \
165 .event = wevent, .event_flags = wflags, .subseq = wsubseq}
166#define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
167 wflags) \
168{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
169 .shift = wshift, .invert = winvert, .event = wevent, \
170 .event_flags = wflags, .subseq = wsubseq}
171
160/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ 172/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
161#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ 173#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
162 wevent, wflags) \ 174 wevent, wflags) \
@@ -450,6 +462,7 @@ struct snd_soc_dapm_widget {
450 unsigned char ext:1; /* has external widgets */ 462 unsigned char ext:1; /* has external widgets */
451 unsigned char force:1; /* force state */ 463 unsigned char force:1; /* force state */
452 unsigned char ignore_suspend:1; /* kept enabled over suspend */ 464 unsigned char ignore_suspend:1; /* kept enabled over suspend */
465 int subseq; /* sort within widget type */
453 466
454 int (*power_check)(struct snd_soc_dapm_widget *w); 467 int (*power_check)(struct snd_soc_dapm_widget *w);
455 468
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 57e1c9f71149..eb7436c7acad 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -737,6 +737,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
737 737
738 if (sort[a->id] != sort[b->id]) 738 if (sort[a->id] != sort[b->id])
739 return sort[a->id] - sort[b->id]; 739 return sort[a->id] - sort[b->id];
740 if (a->subseq != b->subseq) {
741 if (power_up)
742 return a->subseq - b->subseq;
743 else
744 return b->subseq - a->subseq;
745 }
740 if (a->reg != b->reg) 746 if (a->reg != b->reg)
741 return a->reg - b->reg; 747 return a->reg - b->reg;
742 if (a->dapm != b->dapm) 748 if (a->dapm != b->dapm)
@@ -869,6 +875,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
869 struct snd_soc_dapm_widget *w, *n; 875 struct snd_soc_dapm_widget *w, *n;
870 LIST_HEAD(pending); 876 LIST_HEAD(pending);
871 int cur_sort = -1; 877 int cur_sort = -1;
878 int cur_subseq = -1;
872 int cur_reg = SND_SOC_NOPM; 879 int cur_reg = SND_SOC_NOPM;
873 struct snd_soc_dapm_context *cur_dapm = NULL; 880 struct snd_soc_dapm_context *cur_dapm = NULL;
874 int ret; 881 int ret;
@@ -884,12 +891,13 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
884 891
885 /* Do we need to apply any queued changes? */ 892 /* Do we need to apply any queued changes? */
886 if (sort[w->id] != cur_sort || w->reg != cur_reg || 893 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
887 w->dapm != cur_dapm) { 894 w->dapm != cur_dapm || w->subseq != cur_subseq) {
888 if (!list_empty(&pending)) 895 if (!list_empty(&pending))
889 dapm_seq_run_coalesced(cur_dapm, &pending); 896 dapm_seq_run_coalesced(cur_dapm, &pending);
890 897
891 INIT_LIST_HEAD(&pending); 898 INIT_LIST_HEAD(&pending);
892 cur_sort = -1; 899 cur_sort = -1;
900 cur_subseq = -1;
893 cur_reg = SND_SOC_NOPM; 901 cur_reg = SND_SOC_NOPM;
894 cur_dapm = NULL; 902 cur_dapm = NULL;
895 } 903 }
@@ -934,6 +942,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
934 default: 942 default:
935 /* Queue it up for application */ 943 /* Queue it up for application */
936 cur_sort = sort[w->id]; 944 cur_sort = sort[w->id];
945 cur_subseq = w->subseq;
937 cur_reg = w->reg; 946 cur_reg = w->reg;
938 cur_dapm = w->dapm; 947 cur_dapm = w->dapm;
939 list_move(&w->power_list, &pending); 948 list_move(&w->power_list, &pending);