Skip to content

Commit

Permalink
ASoC: Add support for sequencing within
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mark Brown committed Jan 19, 2011
1 parent 828a842 commit 20e4859
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
13 changes: 13 additions & 0 deletions include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \
.event = wevent, .event_flags = wflags}

/* additional sequencing control within an event type */
#define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, wcontrols, \
wncontrols, wevent, wflags) \
{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
.invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \
.event = wevent, .event_flags = wflags, .subseq = wsubseq}
#define SND_SOC_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, winvert, wevent, \
wflags) \
{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
.shift = wshift, .invert = winvert, .event = wevent, \
.event_flags = wflags, .subseq = wsubseq}

/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
wevent, wflags) \
Expand Down Expand Up @@ -450,6 +462,7 @@ struct snd_soc_dapm_widget {
unsigned char ext:1; /* has external widgets */
unsigned char force:1; /* force state */
unsigned char ignore_suspend:1; /* kept enabled over suspend */
int subseq; /* sort within widget type */

int (*power_check)(struct snd_soc_dapm_widget *w);

Expand Down
11 changes: 10 additions & 1 deletion sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,

if (sort[a->id] != sort[b->id])
return sort[a->id] - sort[b->id];
if (a->subseq != b->subseq) {
if (power_up)
return a->subseq - b->subseq;
else
return b->subseq - a->subseq;
}
if (a->reg != b->reg)
return a->reg - b->reg;
if (a->dapm != b->dapm)
Expand Down Expand Up @@ -869,6 +875,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *w, *n;
LIST_HEAD(pending);
int cur_sort = -1;
int cur_subseq = -1;
int cur_reg = SND_SOC_NOPM;
struct snd_soc_dapm_context *cur_dapm = NULL;
int ret;
Expand All @@ -884,12 +891,13 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,

/* Do we need to apply any queued changes? */
if (sort[w->id] != cur_sort || w->reg != cur_reg ||
w->dapm != cur_dapm) {
w->dapm != cur_dapm || w->subseq != cur_subseq) {
if (!list_empty(&pending))
dapm_seq_run_coalesced(cur_dapm, &pending);

INIT_LIST_HEAD(&pending);
cur_sort = -1;
cur_subseq = -1;
cur_reg = SND_SOC_NOPM;
cur_dapm = NULL;
}
Expand Down Expand Up @@ -934,6 +942,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
default:
/* Queue it up for application */
cur_sort = sort[w->id];
cur_subseq = w->subseq;
cur_reg = w->reg;
cur_dapm = w->dapm;
list_move(&w->power_list, &pending);
Expand Down

0 comments on commit 20e4859

Please sign in to comment.