All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
To: vkoul@kernel.org, perex@perex.cz, tiwai@suse.com,
	lgirdwood@gmail.com, broonie@kernel.org,
	srinivas.kandagatla@oss.qualcomm.com
Cc: linux-sound@vger.kernel.org, kai.vehmanen@linux.intel.com,
	yung-chuan.liao@linux.intel.com, pierre-louis.bossart@linux.dev,
	daniel.baluta@nxp.com
Subject: [PATCH v2 04/24] ASoC: soc-compress: Provide a runtime for the compressed FE substream
Date: Wed,  9 Sep 2026 12:09:29 +0300	[thread overview]
Message-ID: <20260909090949.7503-5-peter.ujfalusi@linux.intel.com> (raw)
In-Reply-To: <20260909090949.7503-1-peter.ujfalusi@linux.intel.com>

When a compressed stream is used on the FE side of a DPCM link, the
BE is still running as 'normal' PCM.

DPCM lends the runtime of the FE to every BE it opens and
dpcm_be_reparent() re-points it at another FE when the lending one
disconnects. The internal PCM created for a compressed FE by
snd_soc_new_compress() is never opened via the PCM API, so its
substream has no runtime and the BEs of a compressed FE were left
with a NULL one.

BE DAI and codec drivers can look at substream->runtime, they add
their constraints to it in startup(), for example cs42l43, cs42l42,
hdac_hdmi.

The other users of compressed DPCM do not hit this as their BEs are
DSP internal ports, driven by code which takes everything from the
hw_params it is passed and never looks at substream->runtime. The
BEs here end at generic CODEC drivers which are shared with the non
DPCM case and cannot be expected to know about the FE type.

Allocate a runtime for the compressed FE substream while the stream
is open, initialize its constraints as snd_pcm_open() does and fill
it in from the BE parameters once the mandatory machine level
be_hw_params_fixup() has run, so that the compressed FE lends a valid
and populated runtime just like a PCM FE does.

This also allows a BE to be shared between a compressed and a PCM
FE, which is needed to play a notification over PCM to an endpoint
which a compressed stream is already using.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
---
 sound/soc/soc-compress.c | 109 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index b8402802ae78..e5a70c9b3d31 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -16,6 +16,7 @@
 #include <sound/core.h>
 #include <sound/compress_params.h>
 #include <sound/compress_driver.h>
+#include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/initval.h>
 #include <sound/soc-dpcm.h>
@@ -130,6 +131,104 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
 	return ret;
 }
 
+/*
+ * The internal PCM of a compressed FE is never opened via the PCM API, so its
+ * substream has no runtime attached to it.
+ *
+ * DPCM lends the runtime of the FE to every BE it opens and re-points it at
+ * another FE when the lending one goes away, so the compressed FE must provide
+ * one as well. Without it the BEs are left with a NULL runtime, which oopses
+ * in BE DAI and CODEC drivers looking at substream->runtime, and a BE can not
+ * be shared between a compressed and a PCM FE at all.
+ *
+ * The runtime is owned by the FE for as long as the compressed stream is open.
+ */
+static int soc_compr_alloc_fe_runtime(struct snd_soc_pcm_runtime *fe, int stream)
+{
+	struct snd_pcm_substream *fe_substream = snd_soc_dpcm_get_substream(fe, stream);
+	struct snd_pcm_hw_constraints *constrs;
+	int i;
+
+	if (!fe_substream || fe_substream->runtime)
+		return 0;
+
+	fe_substream->runtime = kzalloc_obj(*fe_substream->runtime);
+	if (!fe_substream->runtime)
+		return -ENOMEM;
+
+	/*
+	 * snd_pcm_open() initializes the constraints of a PCM runtime to
+	 * 'anything goes'. A zeroed one means an empty mask and a [0, 0]
+	 * interval instead, which the constraint helpers refine against and
+	 * reject, so initialize them the same way the PCM core does.
+	 *
+	 * The hw rules snd_pcm_hw_constraints_init() installs on top are only
+	 * evaluated by snd_pcm_hw_refine(), which never runs for this
+	 * substream, so they are not needed here.
+	 */
+	constrs = &fe_substream->runtime->hw_constraints;
+	for (i = SNDRV_PCM_HW_PARAM_FIRST_MASK; i <= SNDRV_PCM_HW_PARAM_LAST_MASK; i++)
+		snd_mask_any(constrs_mask(constrs, i));
+
+	for (i = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; i <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; i++)
+		snd_interval_any(constrs_interval(constrs, i));
+
+	return 0;
+}
+
+static void soc_compr_free_fe_runtime(struct snd_soc_pcm_runtime *fe, int stream)
+{
+	struct snd_pcm_substream *fe_substream = snd_soc_dpcm_get_substream(fe, stream);
+
+	if (!fe_substream || !fe_substream->runtime)
+		return;
+
+	/* BE startup callbacks may have added hw constraint rules */
+	kfree(fe_substream->runtime->hw_constraints.rules);
+	kfree(fe_substream->runtime);
+	fe_substream->runtime = NULL;
+}
+
+/*
+ * The BE parameters of a compressed FE are set up by the machine level
+ * be_hw_params_fixup(), which is mandatory for a compressed BE, see
+ * soc_compr_set_params_fe(). Once they are fixed up, use them to fill in the
+ * runtime the BEs have been lent, so that a BE DAI or CODEC driver sees the
+ * format it is being configured for.
+ */
+static void soc_compr_set_fe_runtime(struct snd_soc_pcm_runtime *fe, int stream)
+{
+	struct snd_pcm_substream *fe_substream = snd_soc_dpcm_get_substream(fe, stream);
+	struct snd_pcm_runtime *runtime;
+	struct snd_soc_dpcm *dpcm;
+
+	snd_soc_dpcm_mutex_assert_held(fe);
+
+	if (!fe_substream || !fe_substream->runtime)
+		return;
+
+	runtime = fe_substream->runtime;
+
+	for_each_dpcm_be(fe, stream, dpcm) {
+		struct snd_pcm_hw_params *params = &dpcm->be->dpcm[stream].hw_params;
+		int bits = snd_pcm_format_physical_width(params_format(params));
+
+		/* skip a BE which has not been fixed up */
+		if (bits <= 0)
+			continue;
+
+		runtime->access		= params_access(params);
+		runtime->format		= params_format(params);
+		runtime->subformat	= params_subformat(params);
+		runtime->channels	= params_channels(params);
+		runtime->rate		= params_rate(params);
+
+		runtime->sample_bits	= bits;
+		runtime->frame_bits	= bits * runtime->channels;
+		break;
+	}
+}
+
 static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 {
 	struct snd_soc_pcm_runtime *fe = cstream->private_data;
@@ -141,6 +240,10 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 
 	snd_soc_card_mutex_lock(fe->card);
 
+	ret = soc_compr_alloc_fe_runtime(fe, stream);
+	if (ret < 0)
+		goto be_err;
+
 	ret = dpcm_path_get(fe, stream, &list);
 	if (ret < 0)
 		goto be_err;
@@ -195,6 +298,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 	dpcm_path_put(&list);
 	snd_soc_dpcm_mutex_unlock(fe);
 be_err:
+	soc_compr_free_fe_runtime(fe, stream);
 	fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
 	snd_soc_card_mutex_unlock(fe->card);
 	return ret;
@@ -237,6 +341,9 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
 
 	snd_soc_dai_compr_shutdown(cpu_dai, cstream, 0);
 
+	/* all BEs are shut down and disconnected, the runtime is unused now */
+	soc_compr_free_fe_runtime(fe, stream);
+
 	snd_soc_card_mutex_unlock(fe->card);
 	return 0;
 }
@@ -387,6 +494,8 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
 
 	snd_soc_dpcm_mutex_lock(fe);
 	ret = dpcm_be_dai_hw_params(fe, stream);
+	if (!ret)
+		soc_compr_set_fe_runtime(fe, stream);
 	snd_soc_dpcm_mutex_unlock(fe);
 	if (ret < 0)
 		goto out;
-- 
2.55.0


  parent reply	other threads:[~2026-09-09  9:09 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-09  9:09 [PATCH v2 00/24] ALSA compress / ASoC compress / SOF: Compressed audio support with IPC4 Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 01/24] ALSA: compress: pin card module while stream is open Peter Ujfalusi
2026-09-09 15:12   ` Takashi Iwai
2026-09-09  9:09 ` [PATCH v2 02/24] ALSA: compress: register the open file with the card Peter Ujfalusi
2026-09-09 15:12   ` Takashi Iwai
2026-09-09  9:09 ` [PATCH v2 03/24] ALSA: compress: stop active streams on disconnect Peter Ujfalusi
2026-09-09  9:09 ` Peter Ujfalusi [this message]
2026-09-09  9:09 ` [PATCH v2 05/24] ASoC: soc-compress: Implement trigger FE-BE sequencing as with normal PCMs Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 06/24] ASoC: soc-compress: Stop running dpcm on free Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 07/24] ASoC: SOF: compress: Rename compress ops with ipc3 prefix Peter Ujfalusi
2026-09-09 12:34   ` Pierre-Louis Bossart
2026-09-10 14:13     ` Péter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 08/24] ASoC: SOF: ipc4-pcm: harden pipeline teardown races Peter Ujfalusi
2026-09-09 12:37   ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 09/24] ASoC: SOF: sof-audio: do not dereference swidget->spipe unconditionally on free Peter Ujfalusi
2026-09-09 12:39   ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 10/24] ASoC: SOF: sof-audio: Expose a couple of functions Peter Ujfalusi
2026-09-09 12:41   ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 11/24] ASoC: SOF: pcm: Modify the signature of a couple of PCM IPC ops Peter Ujfalusi
2026-09-09 12:43   ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 12/24] ASoC: SOF: intel: hda-stream: Clear the current position when releasing stream Peter Ujfalusi
2026-09-09 12:45   ` Pierre-Louis Bossart
2026-09-11  6:31     ` Péter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 13/24] ASoC: SOF: ops: Add new platform-specific ops for compress Peter Ujfalusi
2026-09-09 14:23   ` Pierre-Louis Bossart
2026-09-10 14:25     ` Péter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 14/24] ASoC: SOF: ipc4: Add definition of module data in init_ext object type Peter Ujfalusi
2026-09-09 12:49   ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 15/24] ASoC: SOF: ipc4-topology: Support init_ext_module_data for process modules Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 16/24] ASoC: SOF: ipc4-pcm: Make the timestamp info usable outside of ipc4-pcm.c Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 17/24] ASoC: SOF: ipc4/ipc4-loader: Add SOF_INFO and CODEC_INFO to fw_config_params Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 18/24] ASoC: SOF: ipc4-pcm: Handle COMPR DRAIN triggers as EOS pipeline state Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 19/24] ASoC: SOF: ipc4-topology: Set FAST_MODE for host copier in compr mode Peter Ujfalusi
2026-09-09 13:21   ` Pierre-Louis Bossart
2026-09-10 14:49     ` Péter Ujfalusi
2026-09-11 19:08       ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 20/24] ASoC: SOF: Add support for IPC4 compressed Peter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 21/24] ASoC: SOF: ipc4: Handle compressed drain done notification from firmware Peter Ujfalusi
2026-09-09 13:28   ` Pierre-Louis Bossart
2026-09-10 15:08     ` Péter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 22/24] ASoC: SOF: Intel: Kconfig: Remove redundant IPC version selects Peter Ujfalusi
2026-09-09 13:29   ` Pierre-Louis Bossart
2026-09-09  9:09 ` [PATCH v2 23/24] ASoC: SOF: Intel: Kconfig: Select compress support for TGL+ platforms Peter Ujfalusi
2026-09-09 13:37   ` Pierre-Louis Bossart
2026-09-10 14:57     ` Péter Ujfalusi
2026-09-09  9:09 ` [PATCH v2 24/24] ASoC: SOF: topology: Add support for decoder and encoder widgets Peter Ujfalusi
2026-09-09 13:42 ` [PATCH v2 00/24] ALSA compress / ASoC compress / SOF: Compressed audio support with IPC4 Pierre-Louis Bossart

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260909090949.7503-5-peter.ujfalusi@linux.intel.com \
    --to=peter.ujfalusi@linux.intel.com \
    --cc=broonie@kernel.org \
    --cc=daniel.baluta@nxp.com \
    --cc=kai.vehmanen@linux.intel.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=srinivas.kandagatla@oss.qualcomm.com \
    --cc=tiwai@suse.com \
    --cc=vkoul@kernel.org \
    --cc=yung-chuan.liao@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.