diff options
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 47 |
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 */ |
710 | static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) | 710 | static 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 | |||
723 | static 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", |