mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
ASoC: sdw_utils: Set snd_soc_dai_link_ch_map.codec_ch_mask for capture
In asoc_sdw_hw_params() set the codec_ch_mask member of struct snd_soc_dai_link_ch_map for capture streams. ASoC will then pass the correct number of channels to each codec hw_params(). This prevents trying to enable more channels on the codec DP than have been allocated bitslots in the SoundWire frame, which would cause bus clash errors. In theory codec_ch_mask could also be set for playback streams, but for those the CPU is the only sender so there is no risk of bus clash. For playback streams codec_ch_mask is set to 0 to preserve the existing behavior and avoid introducing bugs. Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Link: https://patch.msgid.link/20260910114500.1586637-5-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
6b382bdfe2
commit
290845e151
|
|
@ -1565,7 +1565,7 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai_link_ch_map *ch_maps;
|
||||
int ch = params_channels(params);
|
||||
unsigned int ch_mask;
|
||||
unsigned int cpu_ch_mask, codec_ch_mask;
|
||||
int num_codecs;
|
||||
int step;
|
||||
int i;
|
||||
|
|
@ -1575,8 +1575,9 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
/* Identical data will be sent to all codecs in playback */
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
ch_mask = GENMASK(ch - 1, 0);
|
||||
cpu_ch_mask = GENMASK(ch - 1, 0);
|
||||
step = 0;
|
||||
codec_ch_mask = 0;
|
||||
} else {
|
||||
num_codecs = rtd->dai_link->num_codecs;
|
||||
|
||||
|
|
@ -1586,17 +1587,24 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ch_mask = GENMASK(ch / num_codecs - 1, 0);
|
||||
step = hweight_long(ch_mask);
|
||||
cpu_ch_mask = GENMASK(ch / num_codecs - 1, 0);
|
||||
step = hweight_long(cpu_ch_mask);
|
||||
codec_ch_mask = cpu_ch_mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* The captured data will be combined from each cpu DAI if the dai
|
||||
* link has more than one codec DAIs. Set codec channel mask and
|
||||
* ASoC will set the corresponding channel numbers for each cpu dai.
|
||||
*
|
||||
* sdw_stream_add_slave() assigns different payload offsets to each
|
||||
* codec in a capture stream, so that the same channels on each
|
||||
* codec map to different channels on the CPU.
|
||||
*/
|
||||
for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
|
||||
ch_maps->cpu_ch_mask = ch_mask << (i * step);
|
||||
for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
|
||||
ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
|
||||
ch_maps->codec_ch_mask = codec_ch_mask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user