ASoC: Intel: avs: Initialize private data for subsequent HDA FEs
authorCezary Rojewski <cezary.rojewski@intel.com>
Fri, 18 Nov 2022 11:30:52 +0000 (12:30 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 18 Nov 2022 14:04:41 +0000 (14:04 +0000)
HDAudio implementation found in sound/pci/hda expects a valid stream
pointer in substream->runtime->private_data location. For ASoC users,
that should point to a valid link stream which is assigned when BE
opens.

As BE borrows its runtime from FE, the information may be lost when
reparenting comes into picture - see dpcm_be_reparent(). To support the
DPCM reparenting functionality for HDAudio scenarios while still
fulfilling expectations of HDAudio common code, have all FEs point to
the same private data.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20221118113052.1340593-1-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/avs/pcm.c

index ca624fbb5c0d0a20f47bc4ba6260875dd3e8937a..b4e7514f878906fd695c21580da26aeddf299004 100644 (file)
@@ -1394,9 +1394,29 @@ static int avs_component_hda_open(struct snd_soc_component *component,
 
        if (!rtd->dai_link->no_pcm) {
                struct snd_pcm_hardware hwparams = avs_pcm_hardware;
+               struct snd_soc_pcm_runtime *be;
+               struct snd_soc_dpcm *dpcm;
+               int dir = substream->stream;
+
+               /*
+                * Support the DPCM reparenting while still fulfilling expectations of HDAudio
+                * common code - a valid stream pointer at substream->runtime->private_data -
+                * by having all FEs point to the same private data.
+                */
+               for_each_dpcm_be(rtd, dir, dpcm) {
+                       struct snd_pcm_substream *be_substream;
+
+                       be = dpcm->be;
+                       if (be->dpcm[dir].users == 1)
+                               break;
+
+                       be_substream = snd_soc_dpcm_get_substream(be, dir);
+                       substream->runtime->private_data = be_substream->runtime->private_data;
+                       break;
+               }
 
                /* RESUME unsupported for de-coupled HD-Audio capture. */
-               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+               if (dir == SNDRV_PCM_STREAM_CAPTURE)
                        hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
 
                return snd_soc_set_runtime_hwparams(substream, &hwparams);