[PATCH v2 1/2] ASoC: sdw_utils: prepare the stream again when resuming
From: Andrey Golovko
Date: Thu Aug 13 2026 - 12:33:11 EST
A peripheral loses its Data Port configuration when the controller is
power-gated during system suspend, so the ports have to be prepared
again before the stream can be enabled. That happens on its own when
userspace calls snd_pcm_prepare() after SNDRV_PCM_STATE_SUSPENDED, but
an application is also allowed to restart the stream with
SNDRV_PCM_IOCTL_RESUME on a card that advertises SNDRV_PCM_INFO_RESUME,
as the AMD ACP platforms do. That path only reaches the trigger
callback, sdw_enable_stream() writes the channels of ports that were
never prepared, and playback silently produces nothing: the PCM keeps
running, no error is reported anywhere, and the speakers stay quiet
until the stream is torn down and set up again.
Prepare the stream on SNDRV_PCM_TRIGGER_RESUME, before enabling it.
The SoundWire core expects exactly this: sdw_prepare_stream() accepts a
disabled stream and then reapplies the bus parameters without
recomputing them, which it documents as the resume case.
Signed-off-by: Andrey Golovko <andrey.golovko@xxxxxxxxx>
---
New in v2, after Mark Brown and Vijendar Mukunda pointed out that a stream
restarted with SNDRV_PCM_IOCTL_RESUME never prepares its ports again.
Measured on an ASUS ProArt PX13 HN7306EAC: without this patch a tone that
is resumed with snd_pcm_resume() alone comes back inaudible with DP1
PrepareCtrl at 0x0 and PDE23 at PS3, with it the ports are prepared again
and the tone returns at its pre-suspend level. Numbers are in the cover
letter.
sound/soc/sdw_utils/soc_sdw_utils.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 8a07ba2a29e5..3e091e78d8c2 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1510,9 +1510,24 @@ int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd)
}
switch (cmd) {
+ case SNDRV_PCM_TRIGGER_RESUME:
+ /*
+ * The peripherals lose their port configuration when the
+ * controller is power-gated during system suspend, and an
+ * application that restarts the stream with
+ * SNDRV_PCM_IOCTL_RESUME - which platforms advertising
+ * SNDRV_PCM_INFO_RESUME allow - never goes through
+ * .prepare() again. Prepare the stream here so that the
+ * ports are reprogrammed before they are enabled;
+ * sdw_prepare_stream() reapplies the parameters without
+ * recomputing them when the stream is disabled.
+ */
+ ret = sdw_prepare_stream(sdw_stream);
+ if (ret)
+ break;
+ fallthrough;
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
ret = sdw_enable_stream(sdw_stream);
break;
--
2.53.0