[PATCH] ASoC: soc-pcm: fixup soc_pcm_params_symmetry()

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Thu Apr 15 03:56:14 CEST 2021


From: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>

commit 3a9067211122 ("ASoC: soc-pcm: cleanup soc_pcm_params_symmetry()")
cleanups soc_pcm_params_symmetry() by addig new
__soc_pcm_params_symmetry() macro.

It checks symmetry first, and checks each DAI settings if symmetry
was true.
But original code checked

	symmetric_rate		: DAI_Link / CPU         (A)
	symmetric_channels	: DAI_Link / CPU / Codec (B)
	symmetric_sample_bits	: DAI_Link / CPU / Codec (B)

	(A) was using for_each_rtd_cpu_dais()
	(B) was using for_each_rtd_dais()

Current code is using (B) for all symmetric_xxx. This is bug.

One note is that we can use .be_hw_params_fixup in DPCM case.
This means, BE settings might be fixuped/updated by FE.
It can be happen not only for rate, but for channels/sample_bits too.

And also, DPCM uses dummy-DAI which will be used for all DPCM
connectoin. ALSA SoC will clean DAI params (a) if it was last user (b).
But dummy-DAI is used from many place, it might not be cleaned.

	static int soc_pcm_hw_clean(...)
	{
		...
		for_each_rtd_dais(rtd, i, dai) {
			...
(b)			if (snd_soc_dai_active(dai) == 1)
(a)				soc_pcm_set_dai_params(dai, NULL);
			...
		}
		...
	}

The solution maybe
	(A1) Symmetric checks CPU only
	(A2) Symmetric checks both CPU / Codec, but ignores dummy-DAI

This patch selects A1.

For example, if Sound Card is exchanging all rate to 48kHz
by using .be_hw_params_fixup() on DPCM, below can be happen.
It is using 44100 Hz, but has mismatch between dummy-DAI which is keeping
48kHz from 1st aplay.

	# aplay 44100.wav
	# aplay 44100.wav
=>	[kernel] be.ak4613-hifi: ASoC: unmatched rate symmetry: 44100 - 48000
	[kernel] be.ak4613-hifi: ASoC: hw_params BE failed -22
	[kernel] fe.rsnd-dai.0: ASoC: hw_params BE failed -22
	aplay: set_params:1407: Unable to install hw params:
	ACCESS:  RW_INTERLEAVED
	FORMAT:  S16_LE
	SUBFORMAT:  STD
	SAMPLE_BITS: 16
	FRAME_BITS: 32
	CHANNELS: 2
	RATE: 44100
	PERIOD_TIME: (23219 23220)
	PERIOD_SIZE: 1024
	PERIOD_BYTES: 4096
	PERIODS: 4
	BUFFER_TIME: (92879 92880)
	BUFFER_SIZE: 4096
	BUFFER_BYTES: 16384
	TICK_TIME: 0

Fixes: 3a9067211122 ("ASoC: soc-pcm: cleanup soc_pcm_params_symmetry()")
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
Hi Mark

This patch is needed for latest linus tree (= for v5.12).
Please let me know if you want (A2).

 sound/soc/soc-pcm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 02968a4e52b4..92e95e4aef9f 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -388,7 +388,7 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
 
 #define __soc_pcm_params_symmetry(name)					\
 	symmetry = rtd->dai_link->symmetric_##name;			\
-	for_each_rtd_dais(rtd, i, dai)					\
+	for_each_rtd_cpu_dais(rtd, i, dai)					\
 		symmetry |= dai->driver->symmetric_##name;		\
 									\
 	if (symmetry)							\
-- 
2.25.1



More information about the Alsa-devel mailing list