[PATCH 0/4] ASoC: soc-pcm: ignore dummy-DAI at soc_pcm_params_symmetry()
Hi Mark
I noticed if we have...
1) Sound Card used DPCM 2) It exchanges rate to 48kHz by using .be_hw_params_fixup() 3) Codec had symmetric_rate = 1
We will get below error. I didn't confirm, but maybe same things happen if it exchanged channels/sample_bits.
# aplay 44100.wav # aplay 44100.wav => [kernel] be.ak4613-hifi: ASoC: unmatched rate symmetry: snd-soc-dummy-dai:44100 - soc_pcm_params_symmetry: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
This patch-set solves this issue. patch 1) - 3) are just cleanup patches. 4) is fot this issue.
Link: https://lore.kernel.org/r/87a6q0z4xt.wl-kuninori.morimoto.gx@renesas.com
Kuninori Morimoto (4): ASoC: soc-pcm: don't use "name" on __soc_pcm_params_symmetry() macro ASoC: soc-pcm: indicate DAI name if soc_pcm_params_symmetry() failed ASoC: soc-utils: add snd_soc_component_is_dummy() ASoC: soc-pcm: ignore dummy-DAI at soc_pcm_params_symmetry()
include/sound/soc-component.h | 1 + sound/soc/soc-core.c | 2 +- sound/soc/soc-pcm.c | 14 ++++++++------ sound/soc/soc-utils.c | 6 ++++++ 4 files changed, 16 insertions(+), 7 deletions(-)
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
__soc_pcm_params_symmetry() macro is using "name" as parameter which will be exchanged to rate/channles/sample_bit, like below
dai->name => dai->rate dai->name => dai->channels dai->name => dai->sample_bit
But, dai itself has "name". This means
1) It is very confusable naming 2) It can't use dai->name
This patch use "xxx" instead of "name"
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-pcm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ad13dc6bba12..e1bca2165668 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -386,16 +386,16 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
soc_pcm_set_dai_params(&d, params);
-#define __soc_pcm_params_symmetry(name) \ - symmetry = rtd->dai_link->symmetric_##name; \ +#define __soc_pcm_params_symmetry(xxx) \ + symmetry = rtd->dai_link->symmetric_##xxx; \ for_each_rtd_dais(rtd, i, dai) \ - symmetry |= dai->driver->symmetric_##name; \ + symmetry |= dai->driver->symmetric_##xxx; \ \ if (symmetry) \ for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ - if (cpu_dai->name && cpu_dai->name != d.name) { \ + if (cpu_dai->xxx && cpu_dai->xxx != d.xxx) { \ dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %d - %d\n", \ - #name, cpu_dai->name, d.name); \ + #xxx, cpu_dai->xxx, d.xxx); \ return -EINVAL; \ }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
It indicates unmatched symmetry value, but not indicates on which DAI. This patch indicates it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-pcm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index e1bca2165668..09d63cbbc602 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -384,6 +384,7 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai; unsigned int symmetry, i;
+ d.name = __func__; soc_pcm_set_dai_params(&d, params);
#define __soc_pcm_params_symmetry(xxx) \ @@ -394,8 +395,8 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, if (symmetry) \ for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ if (cpu_dai->xxx && cpu_dai->xxx != d.xxx) { \ - dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %d - %d\n", \ - #xxx, cpu_dai->xxx, d.xxx); \ + dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %s:%d - %s:%d\n", \ + #xxx, cpu_dai->name, cpu_dai->xxx, d.name, d.xxx); \ return -EINVAL; \ }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
There is snd_soc_dai_is_dummy(), but not for component. This patch adds it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc-component.h | 1 + sound/soc/soc-core.c | 2 +- sound/soc/soc-utils.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 722cfab28d29..8c4d6830597f 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -338,6 +338,7 @@ static inline int snd_soc_component_cache_sync( void snd_soc_component_set_aux(struct snd_soc_component *component, struct snd_soc_aux_dev *aux); int snd_soc_component_init(struct snd_soc_component *component); +int snd_soc_component_is_dummy(struct snd_soc_component *component);
/* component IO */ unsigned int snd_soc_component_read(struct snd_soc_component *component, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 236e075b9e57..762fb5c23f21 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1169,7 +1169,7 @@ static int soc_probe_component(struct snd_soc_card *card, int probed = 0; int ret;
- if (!strcmp(component->name, "snd-soc-dummy")) + if (snd_soc_component_is_dummy(component)) return 0;
if (component->card) { diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index f27f94ca064b..98383fd76224 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -131,6 +131,12 @@ int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) return 0; }
+int snd_soc_component_is_dummy(struct snd_soc_component *component) +{ + return ((component->driver == &dummy_platform) || + (component->driver == &dummy_codec)); +} + static int snd_soc_dummy_probe(struct platform_device *pdev) { int ret;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
soc_pcm_params_symmetry() checks CPU / Codec symmetry. Unfortunately there was bug on it (= A) which didn't check Codec. But is back by (B).
A: v5.7: commit c840f7698d26 ("ASoC: soc-pcm: Merge for_each_rtd_cpu/codec_dais()") B: v5.12: commit 3a9067211122 ("ASoC: soc-pcm: cleanup soc_pcm_params_symmetry()")
In total, old - v5.6 (= Generation-1):
symmetric_rate : DAI_Link / CPU / Codec symmetric_channels : DAI_Link / CPU / Codec symmetric_sample_bits : DAI_Link / CPU / Codec
v5.7 - v5.11 (= Generation-2): (= because of bug by (A))
symmetric_rate : DAI_Link / CPU symmetric_channels : DAI_Link / CPU / Codec symmetric_sample_bits : DAI_Link / CPU / Codec
v5.12 - (= Generation-3): (= back by (B))
symmetric_rate : DAI_Link / CPU / Codec symmetric_channels : DAI_Link / CPU / Codec symmetric_sample_bits : DAI_Link / CPU / Codec
OTOH, we can use DPCM which is configured by FE / BE. Both FE / BE uses dummy-DAI.
FE: CPU <-> dummy-DAI BE: dummy-DAI <-> Codec
One note is that we can use .be_hw_params_fixup in DPCM case. This means BE settings might be fixuped/updated by FE. This feature is used for example on MIXer case. It can be happen not only for rate, but for channels/sample_bits too.
Because of these reasons, below issue happen on Generation-1 / Generation-3, if...
1) Sound Card used DPCM 2) It exchanges rate to 48kHz by using .be_hw_params_fixup() 3) Codec had symmetric_rate = 1
I didn't confirm, but maybe same things happen if it exchanged channels/sample_bits at Generation-1/2/3 too.
# aplay 44100.wav # aplay 44100.wav => [kernel] be.ak4613-hifi: ASoC: unmatched rate symmetry: snd-soc-dummy-dai:44100 - soc_pcm_params_symmetry: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
soc_pcm_params_symmetry() checks by below
if (symmetry) for_each_rtd_cpu_dais(rtd, i, cpu_dai) if (cpu_dai->xxx && cpu_dai->xxx != d.xxx) { dev_err(rtd->dev, "..."); return -EINVAL; }
Because of above reason 3) (= Codec had symmetric_rate = 1) BE can't ignore "if (symmetric)".
At 1st aplay, soc_pcm_params_symmetry() ignores it, because dummy-DAI->rate is 0. After this check, each DAI sets/keep settings.
In above sample case, BE gets 48000 and FE gets 44100, and it happen BE -> FE order. Because DPCM is sharing *same* dummy-DAI, dummy-DAI sets as 48000 by BE, and is overwrote by 44100 by FE.
This settings never be cleaned (= a) after 1st aplay, because dummy-DAI is used from FE/BE, never be last user (b).
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); ... } ... }
At 2nd aplay, BE gets 48000 but dummy-DAI is keeping 44100, soc_pcm_params_symmetry() checks will fail.
To solve this issue, this patch ignores dummy-DAI at soc_pcm_params_symmetry()
Link: https://lore.kernel.org/r/87a6q0z4xt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/soc-pcm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 09d63cbbc602..327bb91ee28e 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -394,7 +394,8 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, \ if (symmetry) \ for_each_rtd_cpu_dais(rtd, i, cpu_dai) \ - if (cpu_dai->xxx && cpu_dai->xxx != d.xxx) { \ + if (!snd_soc_dai_is_dummy(cpu_dai) && \ + cpu_dai->xxx && cpu_dai->xxx != d.xxx) { \ dev_err(rtd->dev, "ASoC: unmatched %s symmetry: %s:%d - %s:%d\n", \ #xxx, cpu_dai->name, cpu_dai->xxx, d.name, d.xxx); \ return -EINVAL; \
On 16 Apr 2021 10:59:12 +0900, Kuninori Morimoto wrote:
I noticed if we have...
- Sound Card used DPCM
- It exchanges rate to 48kHz by using .be_hw_params_fixup()
- Codec had symmetric_rate = 1
We will get below error. I didn't confirm, but maybe same things happen if it exchanged channels/sample_bits.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: soc-pcm: don't use "name" on __soc_pcm_params_symmetry() macro commit: 1cacbac447d9b29a4057d7bbffe8c3d4125ec82a [2/4] ASoC: soc-pcm: indicate DAI name if soc_pcm_params_symmetry() failed commit: ee39d77ed91f220b1458137118dea158a095d5c5 [3/4] ASoC: soc-utils: add snd_soc_component_is_dummy() commit: 8f1a16818a08047c83bc6e29efc07b15fd11fa29 [4/4] ASoC: soc-pcm: ignore dummy-DAI at soc_pcm_params_symmetry() commit: 9c2ae363f3347baacd2353a017eb62363420a1ea
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
participants (2)
-
Kuninori Morimoto
-
Mark Brown