aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/soc-dapm.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 499730ab5638..57e1c9f71149 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -726,8 +726,15 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
726 726
727static int dapm_seq_compare(struct snd_soc_dapm_widget *a, 727static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
728 struct snd_soc_dapm_widget *b, 728 struct snd_soc_dapm_widget *b,
729 int sort[]) 729 bool power_up)
730{ 730{
731 int *sort;
732
733 if (power_up)
734 sort = dapm_up_seq;
735 else
736 sort = dapm_down_seq;
737
731 if (sort[a->id] != sort[b->id]) 738 if (sort[a->id] != sort[b->id])
732 return sort[a->id] - sort[b->id]; 739 return sort[a->id] - sort[b->id];
733 if (a->reg != b->reg) 740 if (a->reg != b->reg)
@@ -741,12 +748,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
741/* Insert a widget in order into a DAPM power sequence. */ 748/* Insert a widget in order into a DAPM power sequence. */
742static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, 749static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
743 struct list_head *list, 750 struct list_head *list,
744 int sort[]) 751 bool power_up)
745{ 752{
746 struct snd_soc_dapm_widget *w; 753 struct snd_soc_dapm_widget *w;
747 754
748 list_for_each_entry(w, list, power_list) 755 list_for_each_entry(w, list, power_list)
749 if (dapm_seq_compare(new_widget, w, sort) < 0) { 756 if (dapm_seq_compare(new_widget, w, power_up) < 0) {
750 list_add_tail(&new_widget->power_list, &w->power_list); 757 list_add_tail(&new_widget->power_list, &w->power_list);
751 return; 758 return;
752 } 759 }
@@ -857,7 +864,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
857 * handled. 864 * handled.
858 */ 865 */
859static void dapm_seq_run(struct snd_soc_dapm_context *dapm, 866static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
860 struct list_head *list, int event, int sort[]) 867 struct list_head *list, int event, bool power_up)
861{ 868{
862 struct snd_soc_dapm_widget *w, *n; 869 struct snd_soc_dapm_widget *w, *n;
863 LIST_HEAD(pending); 870 LIST_HEAD(pending);
@@ -865,6 +872,12 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
865 int cur_reg = SND_SOC_NOPM; 872 int cur_reg = SND_SOC_NOPM;
866 struct snd_soc_dapm_context *cur_dapm = NULL; 873 struct snd_soc_dapm_context *cur_dapm = NULL;
867 int ret; 874 int ret;
875 int *sort;
876
877 if (power_up)
878 sort = dapm_up_seq;
879 else
880 sort = dapm_down_seq;
868 881
869 list_for_each_entry_safe(w, n, list, power_list) { 882 list_for_each_entry_safe(w, n, list, power_list) {
870 ret = 0; 883 ret = 0;
@@ -1002,10 +1015,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1002 list_for_each_entry(w, &card->widgets, list) { 1015 list_for_each_entry(w, &card->widgets, list) {
1003 switch (w->id) { 1016 switch (w->id) {
1004 case snd_soc_dapm_pre: 1017 case snd_soc_dapm_pre:
1005 dapm_seq_insert(w, &down_list, dapm_down_seq); 1018 dapm_seq_insert(w, &down_list, false);
1006 break; 1019 break;
1007 case snd_soc_dapm_post: 1020 case snd_soc_dapm_post:
1008 dapm_seq_insert(w, &up_list, dapm_up_seq); 1021 dapm_seq_insert(w, &up_list, true);
1009 break; 1022 break;
1010 1023
1011 default: 1024 default:
@@ -1025,9 +1038,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1025 trace_snd_soc_dapm_widget_power(w, power); 1038 trace_snd_soc_dapm_widget_power(w, power);
1026 1039
1027 if (power) 1040 if (power)
1028 dapm_seq_insert(w, &up_list, dapm_up_seq); 1041 dapm_seq_insert(w, &up_list, true);
1029 else 1042 else
1030 dapm_seq_insert(w, &down_list, dapm_down_seq); 1043 dapm_seq_insert(w, &down_list, false);
1031 1044
1032 w->power = power; 1045 w->power = power;
1033 break; 1046 break;
@@ -1086,12 +1099,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1086 } 1099 }
1087 1100
1088 /* Power down widgets first; try to avoid amplifying pops. */ 1101 /* Power down widgets first; try to avoid amplifying pops. */
1089 dapm_seq_run(dapm, &down_list, event, dapm_down_seq); 1102 dapm_seq_run(dapm, &down_list, event, false);
1090 1103
1091 dapm_widget_update(dapm); 1104 dapm_widget_update(dapm);
1092 1105
1093 /* Now power up. */ 1106 /* Now power up. */
1094 dapm_seq_run(dapm, &up_list, event, dapm_up_seq); 1107 dapm_seq_run(dapm, &up_list, event, true);
1095 1108
1096 list_for_each_entry(d, &dapm->card->dapm_list, list) { 1109 list_for_each_entry(d, &dapm->card->dapm_list, list) {
1097 /* If we just powered the last thing off drop to standby bias */ 1110 /* If we just powered the last thing off drop to standby bias */
@@ -2372,7 +2385,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2372 if (w->dapm != dapm) 2385 if (w->dapm != dapm)
2373 continue; 2386 continue;
2374 if (w->power) { 2387 if (w->power) {
2375 dapm_seq_insert(w, &down_list, dapm_down_seq); 2388 dapm_seq_insert(w, &down_list, false);
2376 w->power = 0; 2389 w->power = 0;
2377 powerdown = 1; 2390 powerdown = 1;
2378 } 2391 }
@@ -2383,7 +2396,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2383 */ 2396 */
2384 if (powerdown) { 2397 if (powerdown) {
2385 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); 2398 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
2386 dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); 2399 dapm_seq_run(dapm, &down_list, 0, false);
2387 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); 2400 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
2388 } 2401 }
2389} 2402}