aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7a61b5cc2d4f..68acec667242 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -707,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
707} 707}
708 708
709/* reset 'walked' bit for each dapm path */ 709/* reset 'walked' bit for each dapm path */
710static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) 710static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm,
711 struct list_head *sink)
711{ 712{
712 struct snd_soc_dapm_path *p; 713 struct snd_soc_dapm_path *p;
713 714
714 list_for_each_entry(p, &dapm->card->paths, list) 715 list_for_each_entry(p, sink, list_source) {
715 p->walked = 0; 716 if (p->walked) {
717 p->walked = 0;
718 dapm_clear_walk_output(dapm, &p->sink->sinks);
719 }
720 }
721}
722
723static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm,
724 struct list_head *source)
725{
726 struct snd_soc_dapm_path *p;
727
728 list_for_each_entry(p, source, list_sink) {
729 if (p->walked) {
730 p->walked = 0;
731 dapm_clear_walk_input(dapm, &p->source->sources);
732 }
733 }
716} 734}
717 735
736
718/* We implement power down on suspend by checking the power state of 737/* We implement power down on suspend by checking the power state of
719 * the ALSA card - when we are suspending the ALSA state for the card 738 * the ALSA card - when we are suspending the ALSA state for the card
720 * is set to D3. 739 * is set to D3.
@@ -983,13 +1002,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
983 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 1002 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
984 dapm_reset(card); 1003 dapm_reset(card);
985 1004
986 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 1005 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
987 paths = is_connected_output_ep(dai->playback_widget, list); 1006 paths = is_connected_output_ep(dai->playback_widget, list);
988 else 1007 dapm_clear_walk_output(&card->dapm,
1008 &dai->playback_widget->sinks);
1009 } else {
989 paths = is_connected_input_ep(dai->capture_widget, list); 1010 paths = is_connected_input_ep(dai->capture_widget, list);
1011 dapm_clear_walk_input(&card->dapm,
1012 &dai->capture_widget->sources);
1013 }
990 1014
991 trace_snd_soc_dapm_connected(paths, stream); 1015 trace_snd_soc_dapm_connected(paths, stream);
992 dapm_clear_walk(&card->dapm);
993 mutex_unlock(&card->dapm_mutex); 1016 mutex_unlock(&card->dapm_mutex);
994 1017
995 return paths; 1018 return paths;
@@ -1092,9 +1115,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
1092 DAPM_UPDATE_STAT(w, power_checks); 1115 DAPM_UPDATE_STAT(w, power_checks);
1093 1116
1094 in = is_connected_input_ep(w, NULL); 1117 in = is_connected_input_ep(w, NULL);
1095 dapm_clear_walk(w->dapm); 1118 dapm_clear_walk_input(w->dapm, &w->sources);
1096 out = is_connected_output_ep(w, NULL); 1119 out = is_connected_output_ep(w, NULL);
1097 dapm_clear_walk(w->dapm); 1120 dapm_clear_walk_output(w->dapm, &w->sinks);
1098 return out != 0 && in != 0; 1121 return out != 0 && in != 0;
1099} 1122}
1100 1123
@@ -1117,7 +1140,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
1117 1140
1118 if (w->active) { 1141 if (w->active) {
1119 in = is_connected_input_ep(w, NULL); 1142 in = is_connected_input_ep(w, NULL);
1120 dapm_clear_walk(w->dapm); 1143 dapm_clear_walk_input(w->dapm, &w->sources);
1121 return in != 0; 1144 return in != 0;
1122 } else { 1145 } else {
1123 return dapm_generic_check_power(w); 1146 return dapm_generic_check_power(w);
@@ -1133,7 +1156,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
1133 1156
1134 if (w->active) { 1157 if (w->active) {
1135 out = is_connected_output_ep(w, NULL); 1158 out = is_connected_output_ep(w, NULL);
1136 dapm_clear_walk(w->dapm); 1159 dapm_clear_walk_output(w->dapm, &w->sinks);
1137 return out != 0; 1160 return out != 0;
1138 } else { 1161 } else {
1139 return dapm_generic_check_power(w); 1162 return dapm_generic_check_power(w);
@@ -1745,9 +1768,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1745 return -ENOMEM; 1768 return -ENOMEM;
1746 1769
1747 in = is_connected_input_ep(w, NULL); 1770 in = is_connected_input_ep(w, NULL);
1748 dapm_clear_walk(w->dapm); 1771 dapm_clear_walk_input(w->dapm, &w->sources);
1749 out = is_connected_output_ep(w, NULL); 1772 out = is_connected_output_ep(w, NULL);
1750 dapm_clear_walk(w->dapm); 1773 dapm_clear_walk_output(w->dapm, &w->sinks);
1751 1774
1752 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1775 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
1753 w->name, w->power ? "On" : "Off", 1776 w->name, w->power ? "On" : "Off",