From 04c93ea9ce1421a6778bcda21856599f4821e737 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:22:50 +0000 Subject: ASoC: remove SND_SOC_POSSIBLE_xBx_xFx Clock provider / consumer selection is based on board, we can't select automatically from software. Let's remove SND_SOC_POSSIBLE_xBx_xFx. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87tsrc36li.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 8 -------- sound/soc/codecs/ak4613.c | 5 ----- sound/soc/codecs/ak4619.c | 6 ------ sound/soc/codecs/da7213.c | 5 ----- sound/soc/codecs/pcm3168a.c | 6 ------ sound/soc/generic/test-component.c | 7 ------- sound/soc/renesas/fsi.c | 5 ----- sound/soc/renesas/rcar/core.c | 3 --- sound/soc/renesas/rcar/msiof.c | 5 ----- sound/soc/soc-core.c | 15 --------------- sound/soc/soc-utils.c | 7 ------- 11 files changed, 72 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index df010a91b350..c40823ba5456 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -140,14 +140,6 @@ struct clk; #define SND_SOC_DAIFMT_BP_FC SND_SOC_DAIFMT_CBP_CFC #define SND_SOC_DAIFMT_BC_FC SND_SOC_DAIFMT_CBC_CFC -/* Describes the possible PCM format */ -#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT 48 -#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_MASK (0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT) -#define SND_SOC_POSSIBLE_DAIFMT_CBP_CFP (0x1ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT) -#define SND_SOC_POSSIBLE_DAIFMT_CBC_CFP (0x2ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT) -#define SND_SOC_POSSIBLE_DAIFMT_CBP_CFC (0x4ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT) -#define SND_SOC_POSSIBLE_DAIFMT_CBC_CFC (0x8ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT) - #define SND_SOC_DAIFMT_FORMAT_MASK 0x000f #define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 #define SND_SOC_DAIFMT_INV_MASK 0x0f00 diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 3b198b9b4605..3e0696b5abf5 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -748,11 +748,6 @@ static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -/* - * Select below from Sound Card, not Auto - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP - */ static const u64 ak4613_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J; diff --git a/sound/soc/codecs/ak4619.c b/sound/soc/codecs/ak4619.c index 755c002f0f15..192b0c341396 100644 --- a/sound/soc/codecs/ak4619.c +++ b/sound/soc/codecs/ak4619.c @@ -778,12 +778,6 @@ static int ak4619_dai_startup(struct snd_pcm_substream *substream, } static u64 ak4619_dai_formats[] = { - /* - * Select below from Sound Card, not here - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP - */ - /* First Priority */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J, diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 98b8858ded02..4bf91ab2553a 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1720,11 +1720,6 @@ static int da7213_set_component_pll(struct snd_soc_component *component, return _da7213_set_component_pll(component, pll_id, source, fref, fout); } -/* - * Select below from Sound Card, not Auto - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP - */ static const u64 da7213_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J | diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 4503f2f0724e..55a7fd5f9251 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -563,12 +563,6 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, } static const u64 pcm3168a_dai_formats[] = { - /* - * Select below from Sound Card, not here - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP - */ - /* * First Priority */ diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c index fc40d024152e..6f9f498c4c5c 100644 --- a/sound/soc/generic/test-component.c +++ b/sound/soc/generic/test-component.c @@ -191,13 +191,6 @@ static int test_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct } static const u64 test_dai_formats = - /* - * Select below from Sound Card, not auto - * SND_SOC_POSSIBLE_DAIFMT_BP_FP - * SND_SOC_POSSIBLE_DAIFMT_BC_FP - * SND_SOC_POSSIBLE_DAIFMT_BP_FC - * SND_SOC_POSSIBLE_DAIFMT_BC_FC - */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | SND_SOC_POSSIBLE_DAIFMT_LEFT_J | diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c index fb376569b470..ae86014c3819 100644 --- a/sound/soc/renesas/fsi.c +++ b/sound/soc/renesas/fsi.c @@ -1773,11 +1773,6 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, return 0; } -/* - * Select below from Sound Card, not auto - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP - */ static const u64 fsi_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J | diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c index 9ce56cd84f46..82fbdd550714 100644 --- a/sound/soc/renesas/rcar/core.c +++ b/sound/soc/renesas/rcar/core.c @@ -1058,9 +1058,6 @@ static const u64 rsnd_soc_dai_formats[] = { * 1st Priority * * Well tested formats. - * Select below from Sound Card, not auto - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | diff --git a/sound/soc/renesas/rcar/msiof.c b/sound/soc/renesas/rcar/msiof.c index 2671abc028cc..128543fc4fc9 100644 --- a/sound/soc/renesas/rcar/msiof.c +++ b/sound/soc/renesas/rcar/msiof.c @@ -363,11 +363,6 @@ static int msiof_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } -/* - * Select below from Sound Card, not auto - * SND_SOC_DAIFMT_CBC_CFC - * SND_SOC_DAIFMT_CBP_CFP - */ static const u64 msiof_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J | SND_SOC_POSSIBLE_DAIFMT_NB_NF; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ac9b2269c26e..b87219be5860 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1401,21 +1401,6 @@ found: case SND_SOC_POSSIBLE_DAIFMT_IB_IF: dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_IF; break; - /* - * for clock provider / consumer - */ - case SND_SOC_POSSIBLE_DAIFMT_CBP_CFP: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBP_CFP; - break; - case SND_SOC_POSSIBLE_DAIFMT_CBC_CFP: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBC_CFP; - break; - case SND_SOC_POSSIBLE_DAIFMT_CBP_CFC: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBP_CFC; - break; - case SND_SOC_POSSIBLE_DAIFMT_CBC_CFC: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBC_CFC; - break; } } diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 9cb7567e263e..87e9c86ca4f8 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -183,13 +183,6 @@ static const struct snd_soc_component_driver dummy_codec = { SNDRV_PCM_FMTBIT_U32_LE | \ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) -/* - * Select these from Sound Card Manually - * SND_SOC_POSSIBLE_DAIFMT_CBP_CFP - * SND_SOC_POSSIBLE_DAIFMT_CBP_CFC - * SND_SOC_POSSIBLE_DAIFMT_CBC_CFP - * SND_SOC_POSSIBLE_DAIFMT_CBC_CFC - */ static const u64 dummy_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | -- cgit v1.2.3 From da2d7ecd6b32dd753089b4629326019791d052e9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:22:57 +0000 Subject: ASoC: codecs: framer-codec: don't use array if single pattern Because it is confusable during debugging ASoC FW update, tidyup auto format style not to use array if single pattern case. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87se6w36la.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/framer-codec.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/framer-codec.c b/sound/soc/codecs/framer-codec.c index 6f57a3aeecc8..a87a78390172 100644 --- a/sound/soc/codecs/framer-codec.c +++ b/sound/soc/codecs/framer-codec.c @@ -238,15 +238,13 @@ static int framer_dai_startup(struct snd_pcm_substream *substream, return 0; } -static const u64 framer_dai_formats[] = { - SND_SOC_POSSIBLE_DAIFMT_DSP_B, -}; +static const u64 framer_dai_formats = SND_SOC_POSSIBLE_DAIFMT_DSP_B; static const struct snd_soc_dai_ops framer_dai_ops = { .startup = framer_dai_startup, .set_tdm_slot = framer_dai_set_tdm_slot, - .auto_selectable_formats = framer_dai_formats, - .num_auto_selectable_formats = ARRAY_SIZE(framer_dai_formats), + .auto_selectable_formats = &framer_dai_formats, + .num_auto_selectable_formats = 1, }; static struct snd_soc_dai_driver framer_dai_driver = { -- cgit v1.2.3 From 9b5101c373081750523fe9647bbff18f814c6cbe Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:09 +0000 Subject: ASoC: codecs: idt821034: don't use array if single pattern Because it is confusable during debugging ASoC FW update, tidyup auto format style not to use array if single pattern case. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87qzmg36ky.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/idt821034.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/idt821034.c b/sound/soc/codecs/idt821034.c index 39bafefa6a18..084090ccef77 100644 --- a/sound/soc/codecs/idt821034.c +++ b/sound/soc/codecs/idt821034.c @@ -860,18 +860,17 @@ static int idt821034_dai_startup(struct snd_pcm_substream *substream, return 0; } -static const u64 idt821034_dai_formats[] = { +static const u64 idt821034_dai_formats = SND_SOC_POSSIBLE_DAIFMT_DSP_A | - SND_SOC_POSSIBLE_DAIFMT_DSP_B, -}; + SND_SOC_POSSIBLE_DAIFMT_DSP_B; static const struct snd_soc_dai_ops idt821034_dai_ops = { .startup = idt821034_dai_startup, .hw_params = idt821034_dai_hw_params, .set_tdm_slot = idt821034_dai_set_tdm_slot, .set_fmt = idt821034_dai_set_fmt, - .auto_selectable_formats = idt821034_dai_formats, - .num_auto_selectable_formats = ARRAY_SIZE(idt821034_dai_formats), + .auto_selectable_formats = &idt821034_dai_formats, + .num_auto_selectable_formats = 1, }; static struct snd_soc_dai_driver idt821034_dai_driver = { -- cgit v1.2.3 From ca446ac6b38bc311d400db7049ada9e9cf1cd109 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:14 +0000 Subject: ASoC: codecs: peb2466: don't use array if single pattern Because it is confusable during debugging ASoC FW update, tidyup auto format style not to use array if single pattern case. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87pl2036kt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/peb2466.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/peb2466.c b/sound/soc/codecs/peb2466.c index 2d5163c15d0d..2d71d204d8fa 100644 --- a/sound/soc/codecs/peb2466.c +++ b/sound/soc/codecs/peb2466.c @@ -817,18 +817,17 @@ static int peb2466_dai_startup(struct snd_pcm_substream *substream, &peb2466_sample_bits_constr); } -static const u64 peb2466_dai_formats[] = { +static const u64 peb2466_dai_formats = SND_SOC_POSSIBLE_DAIFMT_DSP_A | - SND_SOC_POSSIBLE_DAIFMT_DSP_B, -}; + SND_SOC_POSSIBLE_DAIFMT_DSP_B; static const struct snd_soc_dai_ops peb2466_dai_ops = { .startup = peb2466_dai_startup, .hw_params = peb2466_dai_hw_params, .set_tdm_slot = peb2466_dai_set_tdm_slot, .set_fmt = peb2466_dai_set_fmt, - .auto_selectable_formats = peb2466_dai_formats, - .num_auto_selectable_formats = ARRAY_SIZE(peb2466_dai_formats), + .auto_selectable_formats = &peb2466_dai_formats, + .num_auto_selectable_formats = 1, }; static struct snd_soc_dai_driver peb2466_dai_driver = { -- cgit v1.2.3 From 23ad6257cea2d64c37da6d6973ccd7981bf566e9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:18 +0000 Subject: ASoC: codecs: ak4619: update auto select format Current auto select format start with the highest priority format and gradually add lower priority formats one by one, and search matched format. Like A+X -> A+B+X -> A+B+C+X+Y... (a) But in this method, we can't handle format if HW has some kind of patterns, like A+X or B+Y etc (b). Current drivers are using (a) style, this patch switch to use (b) style. This is needed before update auto select format method. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87o6hk36kp.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ak4619.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/ak4619.c b/sound/soc/codecs/ak4619.c index 192b0c341396..d9c9f6b20028 100644 --- a/sound/soc/codecs/ak4619.c +++ b/sound/soc/codecs/ak4619.c @@ -783,6 +783,8 @@ static u64 ak4619_dai_formats[] = { SND_SOC_POSSIBLE_DAIFMT_LEFT_J, /* Second Priority */ + SND_SOC_POSSIBLE_DAIFMT_I2S | + SND_SOC_POSSIBLE_DAIFMT_LEFT_J | SND_SOC_POSSIBLE_DAIFMT_DSP_A | SND_SOC_POSSIBLE_DAIFMT_DSP_B, }; -- cgit v1.2.3 From 06449c0c47b190d75ac0185cdc5e827d8deee13e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:22 +0000 Subject: ASoC: codecs: pcm3168a: update auto select format Current auto select format start with the highest priority format and gradually add lower priority formats one by one, and search matched format. Like A+X -> A+B+X -> A+B+C+X+Y... (a) But in this method, we can't handle format if HW has some kind of patterns, like A+X or B+Y etc (b). Current drivers are using (a) style, this patch switch to use (b) style. This is needed before update auto select format method. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87mrx436kl.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 55a7fd5f9251..cb6a6f08f2f8 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -575,6 +575,8 @@ static const u64 pcm3168a_dai_formats[] = { * see * pcm3168a_hw_params() */ + SND_SOC_POSSIBLE_DAIFMT_I2S | + SND_SOC_POSSIBLE_DAIFMT_LEFT_J | SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | SND_SOC_POSSIBLE_DAIFMT_DSP_A | SND_SOC_POSSIBLE_DAIFMT_DSP_B, -- cgit v1.2.3 From 97c7d3d20348b480a0bd714fc152768a08e12696 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:28 +0000 Subject: ASoC: renesas: rcar: update auto select format Current auto select format start with the highest priority format and gradually add lower priority formats one by one, and search matched format. Like A+X -> A+B+X -> A+B+C+X+Y... (a) But in this method, we can't handle format if HW has some kind of patterns, like A+X or B+Y etc (b). Current drivers are using (a) style, this patch switch to use (b) style. This is needed before update auto select format method. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ldco36kf.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/renesas/rcar/core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/renesas/rcar/core.c b/sound/soc/renesas/rcar/core.c index 82fbdd550714..b7954746e953 100644 --- a/sound/soc/renesas/rcar/core.c +++ b/sound/soc/renesas/rcar/core.c @@ -1071,8 +1071,15 @@ static const u64 rsnd_soc_dai_formats[] = { * * Supported, but not well tested */ + SND_SOC_POSSIBLE_DAIFMT_I2S | + SND_SOC_POSSIBLE_DAIFMT_RIGHT_J | + SND_SOC_POSSIBLE_DAIFMT_LEFT_J | SND_SOC_POSSIBLE_DAIFMT_DSP_A | - SND_SOC_POSSIBLE_DAIFMT_DSP_B, + SND_SOC_POSSIBLE_DAIFMT_DSP_B | + SND_SOC_POSSIBLE_DAIFMT_NB_NF | + SND_SOC_POSSIBLE_DAIFMT_NB_IF | + SND_SOC_POSSIBLE_DAIFMT_IB_NF | + SND_SOC_POSSIBLE_DAIFMT_IB_IF, }; static void rsnd_parse_tdm_split_mode(struct rsnd_priv *priv, -- cgit v1.2.3 From c6b09cda390496bcc7bbbc4ec7eec26cf43d3f97 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:35 +0000 Subject: ASoC: update auto format selection method Current DAI supports auto format selection. It allow to have array like below. (X) static u64 xxx_auto_formats[] = { (A) /* First Priority */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J, /* Second Priority */ (B) SND_SOC_POSSIBLE_DAIFMT_DSP_A | SND_SOC_POSSIBLE_DAIFMT_DSP_B, }; It try to find available format from I2S/LEFT_J first (A). Then, try to find from I2S/LEFT_J/DSP_A/DSP_B if couldn't find (A)+(B). (OR:ed) In this method, it can't handle if there is format combination. For example, some driver has pattern. Pattern1 I2S/RIFHT_J/LEFT_J (FORMAT) and NB_NF/IB_IF/IB_NF/NB_IF (INV)_ Pattern2 DSP_A/DSP_B (FORMAT) and NB_NF/ IB_NF Because it will try to OR Pattern1 and Pattern2, un-supported pattern might be selected. This patch update method not to use OR, and assumes full format array. Above sample (X) need to be static u64 xxx_auto_formats[] = { /* First Priority */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J, /* Second Priority */ SND_SOC_POSSIBLE_DAIFMT_I2S | SND_SOC_POSSIBLE_DAIFMT_LEFT_J | SND_SOC_POSSIBLE_DAIFMT_DSP_A | SND_SOC_POSSIBLE_DAIFMT_DSP_B, }; Note: It doesn't support Multi CPU/Codec for now Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87jys836k8.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 7 +- sound/soc/soc-core.c | 145 +-------------------------------- sound/soc/soc-dai.c | 207 +++++++++++++++++++++++++++++++++++++----------- 3 files changed, 166 insertions(+), 193 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index c40823ba5456..ba3ae56c6b06 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -81,10 +81,10 @@ struct clk; /* * define GATED -> CONT. GATED will be selected if both are selected. * see - * snd_soc_runtime_get_dai_fmt() + * soc_dai_convert_possiblefmt_to_daifmt() */ #define SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT 16 -#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_MASK (0xFFFF << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT) +#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_MASK (0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT) #define SND_SOC_POSSIBLE_DAIFMT_GATED (0x1ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT) #define SND_SOC_POSSIBLE_DAIFMT_CONT (0x2ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT) @@ -184,8 +184,7 @@ int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio); void snd_soc_dai_set_bclk_clk(struct snd_soc_dai *dai, struct clk *bclk); /* Digital Audio interface formatting */ -int snd_soc_dai_get_fmt_max_priority(const struct snd_soc_pcm_runtime *rtd); -u64 snd_soc_dai_get_fmt(const struct snd_soc_dai *dai, int priority); +unsigned int snd_soc_dai_auto_select_format(const struct snd_soc_pcm_runtime *rtd); int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt); int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b87219be5860..86b6c752a56b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1284,148 +1284,6 @@ int snd_soc_add_pcm_runtimes(struct snd_soc_card *card, } EXPORT_SYMBOL_GPL(snd_soc_add_pcm_runtimes); -static void snd_soc_runtime_get_dai_fmt(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dai_link *dai_link = rtd->dai_link; - struct snd_soc_dai *dai, *not_used; - u64 pos, possible_fmt; - unsigned int mask = 0, dai_fmt = 0; - int i, j, priority, pri, until; - - /* - * Get selectable format from each DAIs. - * - **************************** - * NOTE - * Using .auto_selectable_formats is not mandatory, - * we can select format manually from Sound Card. - * When use it, driver should list well tested format only. - **************************** - * - * ex) - * auto_selectable_formats (= SND_SOC_POSSIBLE_xxx) - * (A) (B) (C) - * DAI0_: { 0x000F, 0x00F0, 0x0F00 }; - * DAI1 : { 0xF000, 0x0F00 }; - * (X) (Y) - * - * "until" will be 3 in this case (MAX array size from DAI0 and DAI1) - * Here is dev_dbg() message and comments - * - * priority = 1 - * DAI0: (pri, fmt) = (1, 000000000000000F) // 1st check (A) DAI1 is not selected - * DAI1: (pri, fmt) = (0, 0000000000000000) // Necessary Waste - * DAI0: (pri, fmt) = (1, 000000000000000F) // 2nd check (A) - * DAI1: (pri, fmt) = (1, 000000000000F000) // (X) - * priority = 2 - * DAI0: (pri, fmt) = (2, 00000000000000FF) // 3rd check (A) + (B) - * DAI1: (pri, fmt) = (1, 000000000000F000) // (X) - * DAI0: (pri, fmt) = (2, 00000000000000FF) // 4th check (A) + (B) - * DAI1: (pri, fmt) = (2, 000000000000FF00) // (X) + (Y) - * priority = 3 - * DAI0: (pri, fmt) = (3, 0000000000000FFF) // 5th check (A) + (B) + (C) - * DAI1: (pri, fmt) = (2, 000000000000FF00) // (X) + (Y) - * found auto selected format: 0000000000000F00 - */ - until = snd_soc_dai_get_fmt_max_priority(rtd); - for (priority = 1; priority <= until; priority++) { - for_each_rtd_dais(rtd, j, not_used) { - - possible_fmt = ULLONG_MAX; - for_each_rtd_dais(rtd, i, dai) { - u64 fmt = 0; - - pri = (j >= i) ? priority : priority - 1; - fmt = snd_soc_dai_get_fmt(dai, pri); - possible_fmt &= fmt; - } - if (possible_fmt) - goto found; - } - } - /* Not Found */ - return; -found: - /* - * convert POSSIBLE_DAIFMT to DAIFMT - * - * Some basic/default settings on each is defined as 0. - * see - * SND_SOC_DAIFMT_NB_NF - * SND_SOC_DAIFMT_GATED - * - * SND_SOC_DAIFMT_xxx_MASK can't notice it if Sound Card specify - * these value, and will be overwrite to auto selected value. - * - * To avoid such issue, loop from 63 to 0 here. - * Small number of SND_SOC_POSSIBLE_xxx will be Hi priority. - * Basic/Default settings of each part and above are defined - * as Hi priority (= small number) of SND_SOC_POSSIBLE_xxx. - */ - for (i = 63; i >= 0; i--) { - pos = 1ULL << i; - switch (possible_fmt & pos) { - /* - * for format - */ - case SND_SOC_POSSIBLE_DAIFMT_I2S: - case SND_SOC_POSSIBLE_DAIFMT_RIGHT_J: - case SND_SOC_POSSIBLE_DAIFMT_LEFT_J: - case SND_SOC_POSSIBLE_DAIFMT_DSP_A: - case SND_SOC_POSSIBLE_DAIFMT_DSP_B: - case SND_SOC_POSSIBLE_DAIFMT_AC97: - case SND_SOC_POSSIBLE_DAIFMT_PDM: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) | i; - break; - /* - * for clock - */ - case SND_SOC_POSSIBLE_DAIFMT_CONT: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_CONT; - break; - case SND_SOC_POSSIBLE_DAIFMT_GATED: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_GATED; - break; - /* - * for clock invert - */ - case SND_SOC_POSSIBLE_DAIFMT_NB_NF: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_NF; - break; - case SND_SOC_POSSIBLE_DAIFMT_NB_IF: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_IF; - break; - case SND_SOC_POSSIBLE_DAIFMT_IB_NF: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_NF; - break; - case SND_SOC_POSSIBLE_DAIFMT_IB_IF: - dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_IF; - break; - } - } - - /* - * Some driver might have very complex limitation. - * In such case, user want to auto-select non-limitation part, - * and want to manually specify complex part. - * - * Or for example, if both CPU and Codec can be clock provider, - * but because of its quality, user want to specify it manually. - * - * Use manually specified settings if sound card did. - */ - if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK)) - mask |= SND_SOC_DAIFMT_FORMAT_MASK; - if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_MASK)) - mask |= SND_SOC_DAIFMT_CLOCK_MASK; - if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_INV_MASK)) - mask |= SND_SOC_DAIFMT_INV_MASK; - if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) - mask |= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; - - dai_link->dai_fmt |= (dai_fmt & mask); -} - /** * snd_soc_runtime_set_dai_fmt() - Change DAI link format for a ASoC runtime * @rtd: The runtime for which the DAI link format should be changed @@ -1504,8 +1362,7 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card, if (ret < 0) return ret; - snd_soc_runtime_get_dai_fmt(rtd); - ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt); + ret = snd_soc_runtime_set_dai_fmt(rtd, snd_soc_dai_auto_select_format(rtd)); if (ret) goto err; diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index 1719ddcefa4b..b098d1100b4b 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -138,68 +138,185 @@ void snd_soc_dai_set_bclk_clk(struct snd_soc_dai *dai, struct clk *bclk) } EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_clk); -int snd_soc_dai_get_fmt_max_priority(const struct snd_soc_pcm_runtime *rtd) +static int soc_dai_fmt_match_cnt(u64 fmt) +{ + int cnt = 0; + + if (fmt & SND_SOC_POSSIBLE_DAIFMT_FORMAT_MASK) + cnt++; + if (fmt & SND_SOC_POSSIBLE_DAIFMT_CLOCK_MASK) + cnt++; + if (fmt & SND_SOC_POSSIBLE_DAIFMT_INV_MASK) + cnt++; + + return cnt; +} + +static void soc_dai_auto_select_format(u64 fmt, const struct snd_soc_pcm_runtime *rtd, + int idx, u64 *best_fmt) { struct snd_soc_dai *dai; - int i, max = 0; + const struct snd_soc_dai_ops *ops; + int max_idx = rtd->dai_link->num_cpus + rtd->dai_link->num_codecs; + u64 available_fmt; /* - * return max num if *ALL* DAIs have .auto_selectable_formats + * NOTE + * It doesn't support Multi CPU/Codec for now */ - for_each_rtd_dais(rtd, i, dai) { - if (dai->driver->ops && - dai->driver->ops->num_auto_selectable_formats) - max = max(max, dai->driver->ops->num_auto_selectable_formats); - else - return 0; - } + if (rtd->dai_link->num_cpus != 1 || + rtd->dai_link->num_codecs != 1) + return; - return max; -} + if (idx >= max_idx) + return; -/** - * snd_soc_dai_get_fmt - get supported audio format. - * @dai: DAI - * @priority: priority level of supported audio format. - * - * This should return only formats implemented with high - * quality by the DAI so that the core can configure a - * format which will work well with other devices. - * For example devices which don't support both edges of the - * LRCLK signal in I2S style formats should only list DSP - * modes. This will mean that sometimes fewer formats - * are reported here than are supported by set_fmt(). - */ -u64 snd_soc_dai_get_fmt(const struct snd_soc_dai *dai, int priority) -{ - const struct snd_soc_dai_ops *ops = dai->driver->ops; - u64 fmt = 0; - int i, max = 0, until = priority; + dai = rtd->dais[idx]; + ops = dai->driver->ops; + + /* zero chance of auto select format */ + if (!ops || !ops->num_auto_selectable_formats) + return; /* - * Collect auto_selectable_formats until priority + **************************** + * NOTE + **************************** + * Using .auto_selectable_formats is not mandatory, + * It try to find best formats as much as possible, but automatically selecting the + * perfect format is impossible. So you can select full or missing format manually + * from Sound Card. * * ex) - * auto_selectable_formats[] = { A, B, C }; - * (A, B, C = SND_SOC_POSSIBLE_DAIFMT_xxx) + * CPU Codec + * (A)[0] I2S/LEFT_J : IB_NF/IB_IF (X)[0] I2S/DSP_A: NB_NF : GATED + * (B)[1] DSP_A/DSP_B: NB_NF/IB_NF (Y)[1] LEFT_J: NB_NF : GATED + * (C)[2] ... * - * priority = 1 : A - * priority = 2 : A | B - * priority = 3 : A | B | C - * priority = 4 : A | B | C + * 1. (A) -> (X) : I2S :update best format + * 2. (A) -> (Y) : LEFT_J + * 3. (B) -> (X) : DSP_A/NB_NF :update best format + * 4. (B) -> (Y) : NB_NF + * 5. (C) -> (X) ... + * 6. (C) -> (Y) ... * ... + * + * In above case GATED will not be selected */ - if (ops) - max = ops->num_auto_selectable_formats; - if (max < until) - until = max; + /* find best formats */ + for (int i = 0; i < ops->num_auto_selectable_formats; i++) { + available_fmt = fmt & ops->auto_selectable_formats[i]; + + /* In case of last DAI */ + if (idx + 1 >= max_idx) { + int cnt1 = soc_dai_fmt_match_cnt(*best_fmt); + int cnt2 = soc_dai_fmt_match_cnt(available_fmt); + + if (cnt1 < cnt2) + *best_fmt = available_fmt; + } + /* parse with next DAI */ + else { + soc_dai_auto_select_format(available_fmt, rtd, idx + 1, best_fmt); + } + } +} + +static unsigned int soc_dai_convert_possiblefmt_to_daifmt(u64 possible_fmt, unsigned int configured_fmt) +{ + unsigned int fmt = 0; + unsigned int mask = 0; + + /* + * convert POSSIBLE_DAIFMT to DAIFMT + * + * Some basic/default settings on each is defined as 0. + * see + * SND_SOC_DAIFMT_NB_NF + * SND_SOC_DAIFMT_GATED + * + * SND_SOC_DAIFMT_xxx_MASK can't notice it if Sound Card specify + * these value, and will be overwrite to auto selected value. + * + * To avoid such issue, loop from 63 to 0 here. + * Small number of SND_SOC_POSSIBLE_xxx will be Hi priority. + * Basic/Default settings of each part and above are defined + * as Hi priority (= small number) of SND_SOC_POSSIBLE_xxx. + */ + for (int i = 63; i >= 0; i--) { + u64 pos = 1ULL << i; + + switch (possible_fmt & pos) { + /* + * for format + */ + case SND_SOC_POSSIBLE_DAIFMT_I2S: + case SND_SOC_POSSIBLE_DAIFMT_RIGHT_J: + case SND_SOC_POSSIBLE_DAIFMT_LEFT_J: + case SND_SOC_POSSIBLE_DAIFMT_DSP_A: + case SND_SOC_POSSIBLE_DAIFMT_DSP_B: + case SND_SOC_POSSIBLE_DAIFMT_AC97: + case SND_SOC_POSSIBLE_DAIFMT_PDM: + fmt = (fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) | i; + break; + /* + * for clock + */ + case SND_SOC_POSSIBLE_DAIFMT_CONT: + fmt = (fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_CONT; + break; + case SND_SOC_POSSIBLE_DAIFMT_GATED: + fmt = (fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_GATED; + break; + /* + * for clock invert + */ + case SND_SOC_POSSIBLE_DAIFMT_NB_NF: + fmt = (fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_NF; + break; + case SND_SOC_POSSIBLE_DAIFMT_NB_IF: + fmt = (fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_IF; + break; + case SND_SOC_POSSIBLE_DAIFMT_IB_NF: + fmt = (fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_NF; + break; + case SND_SOC_POSSIBLE_DAIFMT_IB_IF: + fmt = (fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_IF; + break; + } + } + + /* + * Some driver might have very complex limitation. + * In such case, user want to auto-select non-limitation part, + * and want to manually specify complex part. + * + * Or for example, if both CPU and Codec can be clock provider, + * but because of its quality, user want to specify it manually. + * + * Ignore already configured format if exist + */ + if (!(configured_fmt & SND_SOC_DAIFMT_FORMAT_MASK)) + mask |= SND_SOC_DAIFMT_FORMAT_MASK; + if (!(configured_fmt & SND_SOC_DAIFMT_CLOCK_MASK)) + mask |= SND_SOC_DAIFMT_CLOCK_MASK; + if (!(configured_fmt & SND_SOC_DAIFMT_INV_MASK)) + mask |= SND_SOC_DAIFMT_INV_MASK; + if (!(configured_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK)) + mask |= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; + + return configured_fmt | (fmt & mask); +} + +unsigned int snd_soc_dai_auto_select_format(const struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai_link *dai_link = rtd->dai_link; + u64 possible_fmt = 0; - if (ops && ops->auto_selectable_formats) - for (i = 0; i < until; i++) - fmt |= ops->auto_selectable_formats[i]; + soc_dai_auto_select_format(~0, rtd, 0, &possible_fmt); - return fmt; + return soc_dai_convert_possiblefmt_to_daifmt(possible_fmt, dai_link->dai_fmt); } /** -- cgit v1.2.3 From 442cfd58e71260dcd983e393f750e36fe7ab34d0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 9 Jun 2026 00:23:41 +0000 Subject: ASoC: audio-graph-card2: recommend to use auto select DAI format "Simple Audio Card", "Audio Graph Card", "Audio Graph Card2" are possible to set DAI format via DT. OTOH, ASoC is supporting .auto_selectable_formats to select DAI format automatically. Let's recommend to use it on "Audio Graph Card2". One note is that it keeps supporting DAI format setting via DT. Signed-off-by: Kuninori Morimoto Link: https://patch.msgid.link/87ik7s36k2.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/generic/audio-graph-card2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 0202ed0ee78e..6894bb936cfd 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -778,6 +778,18 @@ static void graph_link_init(struct simple_util_priv *priv, graph_parse_daifmt(ports_cpu, &daifmt); graph_parse_daifmt(ports_codec, &daifmt); graph_parse_daifmt(lnk, &daifmt); + if (daifmt) { + struct device *dev = simple_priv_to_dev(priv); + + /* + * Recommend to use Auto Select by using .auto_selectable_formats. + * linux/sound/soc/renesas/rcar/core.c can be good sample for it. + * + * One note is that Audio Graph Card2 still keeps compatible to set + * DAI format via DT. + */ + dev_warn_once(dev, "use .auto_selectable_formats on each corresponding CPU/Codec driver"); + } graph_util_parse_link_direction(lnk, &playback_only, &capture_only); graph_util_parse_link_direction(ports_cpu, &playback_only, &capture_only); -- cgit v1.2.3