When handling dai_link events on codec to codec links, run all .startup() callbacks on sinks and sources before running any .hw_params(). Same goes for hw_free() and shutdown(). This is closer to the behavior of regular dai links
Signed-off-by: Jerome Brunet jbrunet@baylibre.com --- sound/soc/soc-dapm.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1d04612601ad..5348abda7ce2 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3835,11 +3835,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, goto out; } source->active++; - ret = snd_soc_dai_hw_params(source, &substream, params); - if (ret < 0) - goto out; - - dapm_update_dai_unlocked(&substream, params, source); }
substream.stream = SNDRV_PCM_STREAM_PLAYBACK; @@ -3853,7 +3848,24 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, goto out; } sink->active++; - ret = snd_soc_dai_hw_params(sink, &substream, params); + } + + substream.stream = SNDRV_PCM_STREAM_CAPTURE; + snd_soc_dapm_widget_for_each_source_path(w, path) { + source = path->source->priv; + + ret = soc_dai_hw_params(&substream, params, source); + if (ret < 0) + goto out; + + dapm_update_dai_unlocked(&substream, params, source); + } + + substream.stream = SNDRV_PCM_STREAM_PLAYBACK; + snd_soc_dapm_widget_for_each_sink_path(w, path) { + sink = path->sink->priv; + + ret = soc_dai_hw_params(&substream, params, sink); if (ret < 0) goto out;
@@ -3889,9 +3901,18 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, substream.stream = SNDRV_PCM_STREAM_CAPTURE; snd_soc_dapm_widget_for_each_source_path(w, path) { source = path->source->priv; - snd_soc_dai_hw_free(source, &substream); + }
+ substream.stream = SNDRV_PCM_STREAM_PLAYBACK; + snd_soc_dapm_widget_for_each_sink_path(w, path) { + sink = path->sink->priv; + snd_soc_dai_hw_free(sink, &substream); + } + + substream.stream = SNDRV_PCM_STREAM_CAPTURE; + snd_soc_dapm_widget_for_each_source_path(w, path) { + source = path->source->priv; source->active--; snd_soc_dai_shutdown(source, &substream); } @@ -3899,9 +3920,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w, substream.stream = SNDRV_PCM_STREAM_PLAYBACK; snd_soc_dapm_widget_for_each_sink_path(w, path) { sink = path->sink->priv; - - snd_soc_dai_hw_free(sink, &substream); - sink->active--; snd_soc_dai_shutdown(sink, &substream); }