From e7f3e815ec3b09510055ece3fd0c746077ceba59 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Sep 2026 09:30:30 +0300 Subject: [PATCH] fixup! ASoC: soc-compress: Provide a runtime for the compressed FE substream The runtime handed to the BEs is allocated with kzalloc(), but a zeroed snd_pcm_hw_constraints is not the neutral state: every mask is empty and every interval is [0, 0]. snd_pcm_open() runs snd_pcm_hw_constraints_init() to set them to 'anything goes' before any startup callback is called. Without that, a BE codec which refines a constraint directly in its startup() gets an empty result and returns -EINVAL, failing dpcm_be_dai_startup() and with it the compressed open: - hdac_hdmi_pcm_open() calls snd_pcm_hw_constraint_mask64() on the format mask, and an empty mask ANDed with anything stays empty - cs42l42_dai_startup() calls snd_pcm_hw_constraint_minmax() to limit the rate to [44100, 96000], and refining [0, 0] with it gives min > max Rule based helpers such as snd_pcm_hw_constraint_list() are not affected, they only append to the rules array, which is why this is not seen with the BE codecs on a cs42l43 playback path. Initialize the masks and intervals the same way the PCM core does, so the runtime the compressed FE lends out is indistinguishable from one set up by snd_pcm_open(). Signed-off-by: Peter Ujfalusi --- sound/soc/soc-compress.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 46986220d4ced1..b562a634d10778 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -146,6 +146,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream) 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; @@ -154,6 +156,23 @@ static int soc_compr_alloc_fe_runtime(struct snd_soc_pcm_runtime *fe, int stream 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; }