The patch ASoC: pcm: check if cpu-dai supports a given stream has been applied to the asoc tree at https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 0e9cf4c452ad7e2776441cbac0b9983abaf17ff0 Mon Sep 17 00:00:00 2001 From: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx> Date: Tue, 25 Feb 2020 21:39:17 +0800 Subject: [PATCH] ASoC: pcm: check if cpu-dai supports a given stream Now multi-cpu-dais are supported, we can skip cpi-dais which don't support the current stream, following the example of multi-codec-dais. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> Signed-off-by: Bard Liao <yung-chuan.liao@xxxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/20200225133917.21314-7-yung-chuan.liao@xxxxxxxxxxxxxxx Signed-off-by: Mark Brown <broonie@xxxxxxxxxx> --- sound/soc/soc-pcm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index adbceaff07b8..90857138c823 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -607,6 +607,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream) /* first calculate min/max only for CPUs in the DAI link */ for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + + /* + * Skip CPUs which don't support the current stream type. + * Otherwise, since the rate, channel, and format values will + * zero in that case, we would have no usable settings left, + * causing the resulting setup to fail. + * At least one CPU should match, otherwise we should have + * bailed out on a higher level, since there would be no + * CPU to support the transfer direction in that case. + */ + if (!snd_soc_dai_stream_valid(cpu_dai, + substream->stream)) + continue; + cpu_stream = snd_soc_dai_get_pcm_stream(cpu_dai, stream); cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min); @@ -1115,6 +1129,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + ret = snd_soc_dai_hw_params(cpu_dai, substream, params); if (ret < 0) goto interface_err; @@ -1150,6 +1171,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, interface_err: for_each_rtd_cpu_dai_rollback(rtd, i, cpu_dai) { + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + snd_soc_dai_hw_free(cpu_dai, substream); cpu_dai->rate = 0; } @@ -1226,8 +1250,12 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) snd_soc_dai_hw_free(codec_dai, substream); } - for_each_rtd_cpu_dai(rtd, i, cpu_dai) + for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + snd_soc_dai_hw_free(cpu_dai, substream); + } mutex_unlock(&rtd->card->pcm_mutex); return 0; @@ -1904,6 +1932,13 @@ static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream, int i; for_each_rtd_cpu_dai(be, i, dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(dai, stream)) + continue; + cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); *channels_min = max(*channels_min, @@ -1952,6 +1987,13 @@ static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream, int i; for_each_rtd_cpu_dai(be, i, dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(dai, stream)) + continue; + cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream); *rate_min = max(*rate_min, cpu_stream->rate_min); @@ -1989,6 +2031,13 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) int i; for_each_rtd_cpu_dai(rtd, i, cpu_dai) { + /* + * Skip CPUs which don't support the current stream + * type. See soc_pcm_init_runtime_hw() for more details + */ + if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) + continue; + cpu_dai_drv = cpu_dai->driver; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback); -- 2.20.1