aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/soc/dapm.txt1
-rw-r--r--include/sound/soc-dapm.h7
-rw-r--r--sound/soc/soc-dapm.c44
3 files changed, 46 insertions, 6 deletions
diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt
index 9e6763264a2e..9ac842be9b4f 100644
--- a/Documentation/sound/alsa/soc/dapm.txt
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -62,6 +62,7 @@ Audio DAPM widgets fall into a number of types:-
62 o Mic - Mic (and optional Jack) 62 o Mic - Mic (and optional Jack)
63 o Line - Line Input/Output (and optional Jack) 63 o Line - Line Input/Output (and optional Jack)
64 o Speaker - Speaker 64 o Speaker - Speaker
65 o Supply - Power or clock supply widget used by other widgets.
65 o Pre - Special PRE widget (exec before all others) 66 o Pre - Special PRE widget (exec before all others)
66 o Post - Special POST widget (exec after all others) 67 o Post - Special POST widget (exec after all others)
67 68
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 839a97b63269..533f9f256496 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -154,12 +154,16 @@
154 .shift = wshift, .invert = winvert, \ 154 .shift = wshift, .invert = winvert, \
155 .event = wevent, .event_flags = wflags} 155 .event = wevent, .event_flags = wflags}
156 156
157/* generic register modifier widget */ 157/* generic widgets */
158#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ 158#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
159{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \ 159{ .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \
160 .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \ 160 .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
161 .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \ 161 .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
162 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} 162 .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
163#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
164{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \
165 .shift = wshift, .invert = winvert, .event = wevent, \
166 .event_flags = wflags}
163 167
164/* dapm kcontrol types */ 168/* dapm kcontrol types */
165#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ 169#define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
@@ -308,6 +312,7 @@ enum snd_soc_dapm_type {
308 snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */ 312 snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */
309 snd_soc_dapm_pre, /* machine specific pre widget - exec first */ 313 snd_soc_dapm_pre, /* machine specific pre widget - exec first */
310 snd_soc_dapm_post, /* machine specific post widget - exec last */ 314 snd_soc_dapm_post, /* machine specific post widget - exec last */
315 snd_soc_dapm_supply, /* power/clock supply */
311}; 316};
312 317
313/* 318/*
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d3d17354e76c..7847f80e96d1 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -52,17 +52,19 @@
52 52
53/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
54static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, 55 snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias,
56 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, 56 snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux,
57 snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga, 57 snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl,
58 snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post 58 snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
59 snd_soc_dapm_post
59}; 60};
60 61
61static int dapm_down_seq[] = { 62static int dapm_down_seq[] = {
62 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 63 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
63 snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, 64 snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer,
64 snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, 65 snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias,
65 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post 66 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply,
67 snd_soc_dapm_post
66}; 68};
67 69
68static int dapm_status = 1; 70static int dapm_status = 1;
@@ -165,6 +167,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
165 case snd_soc_dapm_dac: 167 case snd_soc_dapm_dac:
166 case snd_soc_dapm_micbias: 168 case snd_soc_dapm_micbias:
167 case snd_soc_dapm_vmid: 169 case snd_soc_dapm_vmid:
170 case snd_soc_dapm_supply:
168 p->connect = 1; 171 p->connect = 1;
169 break; 172 break;
170 /* does effect routing - dynamically connected */ 173 /* does effect routing - dynamically connected */
@@ -435,6 +438,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
435 struct snd_soc_dapm_path *path; 438 struct snd_soc_dapm_path *path;
436 int con = 0; 439 int con = 0;
437 440
441 if (widget->id == snd_soc_dapm_supply)
442 return 0;
443
438 if (widget->id == snd_soc_dapm_adc && widget->active) 444 if (widget->id == snd_soc_dapm_adc && widget->active)
439 return 1; 445 return 1;
440 446
@@ -471,6 +477,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
471 struct snd_soc_dapm_path *path; 477 struct snd_soc_dapm_path *path;
472 int con = 0; 478 int con = 0;
473 479
480 if (widget->id == snd_soc_dapm_supply)
481 return 0;
482
474 /* active stream ? */ 483 /* active stream ? */
475 if (widget->id == snd_soc_dapm_dac && widget->active) 484 if (widget->id == snd_soc_dapm_dac && widget->active)
476 return 1; 485 return 1;
@@ -622,6 +631,26 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
622 } 631 }
623} 632}
624 633
634/* Check to see if a power supply is needed */
635static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
636{
637 struct snd_soc_dapm_path *path;
638 int power = 0;
639
640 /* Check if one of our outputs is connected */
641 list_for_each_entry(path, &w->sinks, list_source) {
642 if (path->sink && path->sink->power_check &&
643 path->sink->power_check(path->sink)) {
644 power = 1;
645 break;
646 }
647 }
648
649 dapm_clear_walk(w->codec);
650
651 return power;
652}
653
625/* 654/*
626 * Scan a single DAPM widget for a complete audio path and update the 655 * Scan a single DAPM widget for a complete audio path and update the
627 * power status appropriately. 656 * power status appropriately.
@@ -752,6 +781,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
752 case snd_soc_dapm_pga: 781 case snd_soc_dapm_pga:
753 case snd_soc_dapm_mixer: 782 case snd_soc_dapm_mixer:
754 case snd_soc_dapm_mixer_named_ctl: 783 case snd_soc_dapm_mixer_named_ctl:
784 case snd_soc_dapm_supply:
755 if (w->name) { 785 if (w->name) {
756 in = is_connected_input_ep(w); 786 in = is_connected_input_ep(w);
757 dapm_clear_walk(w->codec); 787 dapm_clear_walk(w->codec);
@@ -880,6 +910,7 @@ static ssize_t dapm_widget_show(struct device *dev,
880 case snd_soc_dapm_pga: 910 case snd_soc_dapm_pga:
881 case snd_soc_dapm_mixer: 911 case snd_soc_dapm_mixer:
882 case snd_soc_dapm_mixer_named_ctl: 912 case snd_soc_dapm_mixer_named_ctl:
913 case snd_soc_dapm_supply:
883 if (w->name) 914 if (w->name)
884 count += sprintf(buf + count, "%s: %s\n", 915 count += sprintf(buf + count, "%s: %s\n",
885 w->name, w->power ? "On":"Off"); 916 w->name, w->power ? "On":"Off");
@@ -1044,6 +1075,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1044 case snd_soc_dapm_vmid: 1075 case snd_soc_dapm_vmid:
1045 case snd_soc_dapm_pre: 1076 case snd_soc_dapm_pre:
1046 case snd_soc_dapm_post: 1077 case snd_soc_dapm_post:
1078 case snd_soc_dapm_supply:
1047 list_add(&path->list, &codec->dapm_paths); 1079 list_add(&path->list, &codec->dapm_paths);
1048 list_add(&path->list_sink, &wsink->sources); 1080 list_add(&path->list_sink, &wsink->sources);
1049 list_add(&path->list_source, &wsource->sinks); 1081 list_add(&path->list_source, &wsource->sinks);
@@ -1164,6 +1196,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1164 case snd_soc_dapm_line: 1196 case snd_soc_dapm_line:
1165 w->power_check = dapm_generic_check_power; 1197 w->power_check = dapm_generic_check_power;
1166 break; 1198 break;
1199 case snd_soc_dapm_supply:
1200 w->power_check = dapm_supply_check_power;
1167 case snd_soc_dapm_vmid: 1201 case snd_soc_dapm_vmid:
1168 case snd_soc_dapm_pre: 1202 case snd_soc_dapm_pre:
1169 case snd_soc_dapm_post: 1203 case snd_soc_dapm_post: