|
@@ -707,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
|
|
|
}
|
|
|
|
|
|
/* reset 'walked' bit for each dapm path */
|
|
|
-static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
|
|
|
+static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm,
|
|
|
+ struct list_head *sink)
|
|
|
{
|
|
|
struct snd_soc_dapm_path *p;
|
|
|
|
|
|
- list_for_each_entry(p, &dapm->card->paths, list)
|
|
|
- p->walked = 0;
|
|
|
+ list_for_each_entry(p, sink, list_source) {
|
|
|
+ if (p->walked) {
|
|
|
+ p->walked = 0;
|
|
|
+ dapm_clear_walk_output(dapm, &p->sink->sinks);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm,
|
|
|
+ struct list_head *source)
|
|
|
+{
|
|
|
+ struct snd_soc_dapm_path *p;
|
|
|
+
|
|
|
+ list_for_each_entry(p, source, list_sink) {
|
|
|
+ if (p->walked) {
|
|
|
+ p->walked = 0;
|
|
|
+ dapm_clear_walk_input(dapm, &p->source->sources);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/* We implement power down on suspend by checking the power state of
|
|
|
* the ALSA card - when we are suspending the ALSA state for the card
|
|
|
* is set to D3.
|
|
@@ -983,13 +1002,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
|
|
|
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
|
|
|
dapm_reset(card);
|
|
|
|
|
|
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
|
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
|
paths = is_connected_output_ep(dai->playback_widget, list);
|
|
|
- else
|
|
|
+ dapm_clear_walk_output(&card->dapm,
|
|
|
+ &dai->playback_widget->sinks);
|
|
|
+ } else {
|
|
|
paths = is_connected_input_ep(dai->capture_widget, list);
|
|
|
+ dapm_clear_walk_input(&card->dapm,
|
|
|
+ &dai->capture_widget->sources);
|
|
|
+ }
|
|
|
|
|
|
trace_snd_soc_dapm_connected(paths, stream);
|
|
|
- dapm_clear_walk(&card->dapm);
|
|
|
mutex_unlock(&card->dapm_mutex);
|
|
|
|
|
|
return paths;
|
|
@@ -1092,9 +1115,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
|
|
|
DAPM_UPDATE_STAT(w, power_checks);
|
|
|
|
|
|
in = is_connected_input_ep(w, NULL);
|
|
|
- dapm_clear_walk(w->dapm);
|
|
|
+ dapm_clear_walk_input(w->dapm, &w->sources);
|
|
|
out = is_connected_output_ep(w, NULL);
|
|
|
- dapm_clear_walk(w->dapm);
|
|
|
+ dapm_clear_walk_output(w->dapm, &w->sinks);
|
|
|
return out != 0 && in != 0;
|
|
|
}
|
|
|
|
|
@@ -1117,7 +1140,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
|
|
|
|
|
|
if (w->active) {
|
|
|
in = is_connected_input_ep(w, NULL);
|
|
|
- dapm_clear_walk(w->dapm);
|
|
|
+ dapm_clear_walk_input(w->dapm, &w->sources);
|
|
|
return in != 0;
|
|
|
} else {
|
|
|
return dapm_generic_check_power(w);
|
|
@@ -1133,7 +1156,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
|
|
|
|
|
|
if (w->active) {
|
|
|
out = is_connected_output_ep(w, NULL);
|
|
|
- dapm_clear_walk(w->dapm);
|
|
|
+ dapm_clear_walk_output(w->dapm, &w->sinks);
|
|
|
return out != 0;
|
|
|
} else {
|
|
|
return dapm_generic_check_power(w);
|
|
@@ -1745,9 +1768,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
|
|
|
return -ENOMEM;
|
|
|
|
|
|
in = is_connected_input_ep(w, NULL);
|
|
|
- dapm_clear_walk(w->dapm);
|
|
|
+ dapm_clear_walk_input(w->dapm, &w->sources);
|
|
|
out = is_connected_output_ep(w, NULL);
|
|
|
- dapm_clear_walk(w->dapm);
|
|
|
+ dapm_clear_walk_output(w->dapm, &w->sinks);
|
|
|
|
|
|
ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
|
|
|
w->name, w->power ? "On" : "Off",
|