diff options
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 44 |
1 files changed, 39 insertions, 5 deletions
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 */ |
54 | static int dapm_up_seq[] = { | 54 | static 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 | ||
61 | static int dapm_down_seq[] = { | 62 | static 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 | ||
68 | static int dapm_status = 1; | 70 | static 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 */ | ||
635 | static 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: |