ASoC: pcm: Honor subformat when configuring runtime
authorCezary Rojewski <cezary.rojewski@intel.com>
Fri, 17 Nov 2023 12:05:57 +0000 (13:05 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 27 Nov 2023 16:27:20 +0000 (17:27 +0100)
Subformat options are ignored when setting up hardware parameters and
assigning PCM stream capabilities. Account for them to allow for
granular format selection.

As there is only one user currently (format S32_LE), subformat is
represented by a simple u32 and stores flags only for that one user
alone. Such approach allows for alloc/free-less code until there are
more users on the horizon.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Acked-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20231117120610.1755254-4-cezary.rojewski@intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/soc.h
sound/soc/soc-pcm.c

index 7792c393e2386d0f32f4fd963bf797293acd4772..ccc31bc41e922b5b0cacb174dff2a49e49370dea 100644 (file)
@@ -620,6 +620,7 @@ enum snd_soc_trigger_order {
 struct snd_soc_pcm_stream {
        const char *stream_name;
        u64 formats;                    /* SNDRV_PCM_FMTBIT_* */
+       u32 subformats;                 /* for S32_LE format, SNDRV_PCM_SUBFMTBIT_* */
        unsigned int rates;             /* SNDRV_PCM_RATE_* */
        unsigned int rate_min;          /* min rate */
        unsigned int rate_max;          /* max rate */
index 323e4d7b6adfe12162a8c1ac43bbb4caa2d5cdd2..9d688917cce2e4a8eb191ef5d41a78e10638e2dd 100644 (file)
@@ -554,6 +554,12 @@ static void soc_pcm_hw_update_format(struct snd_pcm_hardware *hw,
        hw->formats &= p->formats;
 }
 
+static void soc_pcm_hw_update_subformat(struct snd_pcm_hardware *hw,
+                                       struct snd_soc_pcm_stream *p)
+{
+       hw->subformats &= p->subformats;
+}
+
 /**
  * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream
  * @rtd: ASoC PCM runtime
@@ -592,6 +598,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
                soc_pcm_hw_update_chan(hw, cpu_stream);
                soc_pcm_hw_update_rate(hw, cpu_stream);
                soc_pcm_hw_update_format(hw, cpu_stream);
+               soc_pcm_hw_update_subformat(hw, cpu_stream);
        }
        cpu_chan_min = hw->channels_min;
        cpu_chan_max = hw->channels_max;
@@ -613,6 +620,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
                soc_pcm_hw_update_chan(hw, codec_stream);
                soc_pcm_hw_update_rate(hw, codec_stream);
                soc_pcm_hw_update_format(hw, codec_stream);
+               soc_pcm_hw_update_subformat(hw, codec_stream);
        }
 
        /* Verify both a valid CPU DAI and a valid CODEC DAI were found */
@@ -1713,6 +1721,7 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
                soc_pcm_hw_update_rate(hw, cpu_stream);
                soc_pcm_hw_update_chan(hw, cpu_stream);
                soc_pcm_hw_update_format(hw, cpu_stream);
+               soc_pcm_hw_update_subformat(hw, cpu_stream);
        }
 
 }
@@ -1750,6 +1759,7 @@ static void dpcm_runtime_setup_be_format(struct snd_pcm_substream *substream)
                        codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
 
                        soc_pcm_hw_update_format(hw, codec_stream);
+                       soc_pcm_hw_update_subformat(hw, codec_stream);
                }
        }
 }