Subformat options are ignored when setting up hardware parameters and assigning PCM stream capabilities. Account for them to allow for granular format selection.
Signed-off-by: Cezary Rojewski cezary.rojewski@intel.com --- include/sound/soc.h | 1 + sound/soc/soc-pcm.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 755907fe82b4..cb74295ab020 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -619,6 +619,7 @@ enum snd_soc_trigger_order { struct snd_soc_pcm_stream { const char *stream_name; u64 formats; /* SNDRV_PCM_FMTBIT_* */ + u64 subformats; /* SNDRV_PCM_SUBFMTBIT_* */ unsigned int rates; /* SNDRV_PCM_RATE_* */ unsigned int rate_min; /* min rate */ unsigned int rate_max; /* max rate */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index dc5f41879cc0..80118c5cb194 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -525,6 +525,7 @@ static void soc_pcm_hw_init(struct snd_pcm_hardware *hw) hw->channels_min = 0; hw->channels_max = UINT_MAX; hw->formats = ULLONG_MAX; + hw->subformats = ULLONG_MAX; }
static void soc_pcm_hw_update_rate(struct snd_pcm_hardware *hw, @@ -553,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 @@ -591,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; @@ -612,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 */ @@ -636,6 +645,7 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream) { struct snd_pcm_hardware *hw = &substream->runtime->hw; struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + u64 subformats = hw->subformats; u64 formats = hw->formats;
/* @@ -647,6 +657,8 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
if (formats) hw->formats &= formats; + if (subformats) + hw->subformats &= subformats; }
static int soc_pcm_components_open(struct snd_pcm_substream *substream) @@ -1675,6 +1687,7 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream) struct snd_pcm_hardware *hw = &runtime->hw; struct snd_soc_dai *dai; int stream = substream->stream; + u64 subformats = hw->subformats; u64 formats = hw->formats; int i;
@@ -1682,6 +1695,8 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
if (formats) hw->formats &= formats; + if (subformats) + hw->subformats &= subformats;
for_each_rtd_cpu_dais(fe, i, dai) { struct snd_soc_pcm_stream *cpu_stream; @@ -1698,6 +1713,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); }
} @@ -1735,6 +1751,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); } } }