From fcc4348adafe53928fda46d104c1798e5a4de4ff Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 17 Jan 2023 14:35:34 +0200 Subject: ASoC: SOF: sof-audio: start with the right widget type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there is a connection between a playback stream and a capture stream, all widgets that are connected to the playback stream and the capture stream will be in the list. So, we have to start with the exactly right widget type. snd_soc_dapm_aif_out is for capture stream and a playback stream should start with a snd_soc_dapm_aif_in widget. Contrarily, snd_soc_dapm_dai_in is for playback stream, and a capture stream should start with a snd_soc_dapm_dai_out widget. Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Kai Vehmanen Reviewed-by: Péter Ujfalusi Reviewed-by: Pierre-Louis Bossart Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20230117123534.2075-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sof/sof-audio.c') diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 7306a2649857..41e4dd447b92 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -429,11 +429,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l for_each_dapm_widgets(list, i, widget) { /* starting widget for playback is AIF type */ - if (dir == SNDRV_PCM_STREAM_PLAYBACK && !WIDGET_IS_AIF(widget->id)) + if (dir == SNDRV_PCM_STREAM_PLAYBACK && widget->id != snd_soc_dapm_aif_in) continue; /* starting widget for capture is DAI type */ - if (dir == SNDRV_PCM_STREAM_CAPTURE && !WIDGET_IS_DAI(widget->id)) + if (dir == SNDRV_PCM_STREAM_CAPTURE && widget->id != snd_soc_dapm_dai_out) continue; switch (op) { -- cgit v1.2.3 From 7d2a67e02549c4b1feaac4d8b4151bf46424a047 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 18 Jan 2023 12:12:53 +0200 Subject: ASoC: SOF: sof-audio: unprepare when swidget->use_count > 0 We should unprepare the widget if its use_count = 1. Fixes: 9862dcf70245 ("ASoC: SOF: don't unprepare widget used other pipelines") Cc: # 6.1 Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20230118101255.29139-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/sof/sof-audio.c') diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 7306a2649857..e52ef62ce7a3 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -272,7 +272,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg struct snd_soc_dapm_path *p; /* return if the widget is in use or if it is already unprepared */ - if (!swidget->prepared || swidget->use_count > 1) + if (!swidget->prepared || swidget->use_count > 0) return; if (widget_ops[widget->id].ipc_unprepare) -- cgit v1.2.3 From 0ad84b11f2f8dd19d62d0b2ffd95ece897e6c3dc Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 18 Jan 2023 12:12:54 +0200 Subject: ASoC: SOF: sof-audio: skip prepare/unprepare if swidget is NULL Skip preparing/unpreparing widgets if the swidget pointer is NULL. This will be true in the case of virtual widgets in topology that were added for reusing the legacy HDA machine driver with SOF. Fixes: 9862dcf70245 ("ASoC: SOF: don't unprepare widget used other pipelines") Cc: # 6.1 Signed-off-by: Ranjani Sridharan Signed-off-by: Peter Ujfalusi Reviewed-by: Rander Wang Reviewed-by: AngeloGioacchino Del Regno Tested-by: AngeloGioacchino Del Regno Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20230118101255.29139-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/sof/sof-audio.c') diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index e52ef62ce7a3..8c114e6a23c6 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -272,7 +272,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg struct snd_soc_dapm_path *p; /* return if the widget is in use or if it is already unprepared */ - if (!swidget->prepared || swidget->use_count > 0) + if (!swidget || !swidget->prepared || swidget->use_count > 0) return; if (widget_ops[widget->id].ipc_unprepare) @@ -303,7 +303,7 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget struct snd_soc_dapm_path *p; int ret; - if (!widget_ops[widget->id].ipc_prepare || swidget->prepared) + if (!swidget || !widget_ops[widget->id].ipc_prepare || swidget->prepared) goto sink_prepare; /* prepare the source widget */ -- cgit v1.2.3 From cc755b4377b0520d594ae573497cf0824baea648 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 18 Jan 2023 12:12:55 +0200 Subject: ASoC: SOF: keep prepare/unprepare widgets in sink path The existing code return when a widget doesn't need to prepare/unprepare. This will prevent widgets in the sink path from being prepared/unprepared. Cc: # 6.1 Link: https://github.com/thesofproject/linux/issues/4021 Signed-off-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Signed-off-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20230118101255.29139-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/sof-audio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/soc/sof/sof-audio.c') diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 8c114e6a23c6..ff716bfbcb67 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -271,9 +271,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg struct snd_sof_widget *swidget = widget->dobj.private; struct snd_soc_dapm_path *p; - /* return if the widget is in use or if it is already unprepared */ + /* skip if the widget is in use or if it is already unprepared */ if (!swidget || !swidget->prepared || swidget->use_count > 0) - return; + goto sink_unprepare; if (widget_ops[widget->id].ipc_unprepare) /* unprepare the source widget */ @@ -281,6 +281,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg swidget->prepared = false; +sink_unprepare: /* unprepare all widgets in the sink paths */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { if (!p->walking && p->sink->dobj.private) { -- cgit v1.2.3