[alsa-devel] [PATCH v4][RFC] ASoC: modern style CPU
Hi Mark, Pierre-Louis
I posted v3 refactoring modern style macro 2 weeks ago, and there is no response yet. I repost it, then, fixup a little bit. These are v4 of RFC of modern style CPU support.
v3 -> v4 - rename xxx_CPU to xxx_FE rename xxx_Codec to xxx_BE rename xxx_PLATFORM to xxx_DMA
v2 -> v3 - use __VA_ARGS__ We can use same macro for both With / Without Platform
v1 -> v2 - Macro naming fixup - no more _CC, _CCP - has manual CPU/Codec/Platform setup
Modern style dai_link requests CPU/Codec/Platform component pointer array and its size, but it will be very verbose code. To avoid such scene, this patch adds dai_link connection macro.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/soc-core.c | 6 ++++ 2 files changed, 94 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h index e9771cb..f7779ce 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1048,6 +1048,94 @@ struct snd_soc_dai_link { ((i) < link->num_codecs) && ((codec) = &link->codecs[i]); \ (i)++)
+/* + * Sample 1 : Single CPU/Codec/Platform + * + * SND_SOC_DAILINK_DEFS(test, + * DAILINK_COMPONENT_ARRAY(COMPONENT_FE("cpu_dai")), + * DAILINK_COMPONENT_ARRAY(COMPONENT_BE("codec", "codec_dai")), + * DAILINK_COMPONENT_ARRAY(COMPONENT_DMA("platform"))); + * + * struct snd_soc_dai_link link = { + * ... + * SND_SOC_DAILINK_REG(test), + * }; + * + * Sample 2 : Multi CPU/Codec, no Platform + * + * SND_SOC_DAILINK_DEFS(test, + * DAILINK_COMPONENT_ARRAY(COMPONENT_FE("cpu_dai1"), + * COMPONENT_FE("cpu_dai2")), + * DAILINK_COMPONENT_ARRAY(COMPONENT_BE("codec1", "codec_dai1"), + * COMPONENT_BE("codec2", "codec_dai2"))); + * + * struct snd_soc_dai_link link = { + * ... + * SND_SOC_DAILINK_REG(test), + * }; + * + * Sample 3 : Define each CPU/Codec/Platform manually + * + * SND_SOC_DAILINK_DEF(test_cpu, + * DAILINK_COMPONENT_ARRAY(COMPONENT_FE("cpu_dai1"), + * COMPONENT_FE("cpu_dai2"))); + * SND_SOC_DAILINK_DEF(test_codec, + * DAILINK_COMPONENT_ARRAY(COMPONENT_BE("codec1", "codec_dai1"), + * COMPONENT_BE("codec2", "codec_dai2"))); + * SND_SOC_DAILINK_DEF(test_platform, + * DAILINK_COMPONENT_ARRAY(COMPONENT_DMA("platform"))); + * + * struct snd_soc_dai_link link = { + * ... + * SND_SOC_DAILINK_REG(test_cpu, + * test_codec, + * test_platform), + * }; + * + * Sample 4 : Sample3 without platform + * + * struct snd_soc_dai_link link = { + * ... + * SND_SOC_DAILINK_REG(test_cpu, + * test_codec); + * }; + */ + +#define SND_SOC_DAILINK_REG1(name) SND_SOC_DAILINK_REG3(name##_cpus, name##_codecs, name##_platforms) +#define SND_SOC_DAILINK_REG2(cpu, codec) SND_SOC_DAILINK_REG3(cpu, codec, null_dailink_component) +#define SND_SOC_DAILINK_REG3(cpu, codec, platform) \ + .cpus = cpu, \ + .num_cpus = ARRAY_SIZE(cpu), \ + .codecs = codec, \ + .num_codecs = ARRAY_SIZE(codec), \ + .platforms = platform, \ + .num_platforms = ARRAY_SIZE(platform) + +#define SND_SOC_DAILINK_REGx(_1, _2, _3, func, ...) func +#define SND_SOC_DAILINK_REG(...) \ + SND_SOC_DAILINK_REGx(__VA_ARGS__, \ + SND_SOC_DAILINK_REG3, \ + SND_SOC_DAILINK_REG2, \ + SND_SOC_DAILINK_REG1)(__VA_ARGS__) + +#define SND_SOC_DAILINK_DEF(name, def...) \ + static struct snd_soc_dai_link_component name[] = { def } + +#define SND_SOC_DAILINK_DEFS(name, cpu, codec, platform...) \ + SND_SOC_DAILINK_DEF(name##_cpus, cpu); \ + SND_SOC_DAILINK_DEF(name##_codecs, codec); \ + SND_SOC_DAILINK_DEF(name##_platforms, platform) + +#define DAILINK_COMPONENT_ARRAY(param...) param +#define COMPONENT_EMPTY() { } +#define COMPONENT_FE(_dai) { .dai_name = _dai, } +#define COMPONENT_BE(_name, _dai) { .name = _name, .dai_name = _dai, } +#define COMPONENT_DMA(_name) { .name = _name } +#define COMPONENT_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", } + +extern struct snd_soc_dai_link_component null_dailink_component[0]; + + struct snd_soc_codec_conf { /* * specify device either by device name, or by diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f6765b0..dd0c625 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -58,6 +58,12 @@ static LIST_HEAD(unbind_card_list); list_for_each_entry(component, &component_list, list)
/* + * This is used if driver don't need to have CPU/Codec/Platform + * dai_link. see soc.h + */ +struct snd_soc_dai_link_component null_dailink_component[0]; + +/* * This is a timeout to do a DAPM powerdown after a stream is closed(). * It can be used to eliminate pops between different playback streams, e.g. * between two audio tracks.
Sorry about the delays in reviewing.
the syntax looks fine, but the _FE/_BE/_DMA suffix is a bit misleading. The _FE in the examples is actually a DPCM BE, and the _BE is really a codec which isn't related to DPCM at all, and platform has typically nothing to do with DMA?
Why not keep the initial conventions and use e.g. COMPONENT_CPU, COMPONENT_CODEC, COMPONENT_PLATFORM to avoid introducing new concepts? If it's starting to be too many letters, then we can use the COMP acronym e.g DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai"))
Thanks -Pierre
Hi Pierre-Louis
Thank you for your feedback
Thanks. Yeah, I notice it was not good naming. Thank you for pointing it !
rollback to CPU/CODEC/PLATFORM is better idea, and COMP_xxx is perfect idea !
Thanks, I will start to use it.
Thank you for your help !! Best regards --- Kuninori Morimoto
ASoC is now supporting modern style dai_link (= snd_soc_dai_link_component) for CPU/Codec/Platform. This patch switches to use it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/samsung/speyside.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 15465c8..770a667 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -189,39 +189,45 @@ static const struct snd_soc_pcm_stream dsp_codec_params = { .channels_max = 2, };
+SND_SOC_DAILINK_DEFS(cpu_dsp, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("samsung-i2s.0")), + DAILINK_COMPONENT_ARRAY(COMPONENT_BE("spi0.0", "wm0010-sdi1")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DMA("samsung-i2s.0"))); + +SND_SOC_DAILINK_DEFS(dsp_codec, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("wm0010-sdi2")), + DAILINK_COMPONENT_ARRAY(COMPONENT_BE("wm8996.1-001a", "wm8996-aif1"))); + +SND_SOC_DAILINK_DEFS(baseband, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("wm8996-aif2")), + DAILINK_COMPONENT_ARRAY(COMPONENT_BE("wm1250-ev1.1-0027", "wm1250-ev1"))); + static struct snd_soc_dai_link speyside_dai[] = { { .name = "CPU-DSP", .stream_name = "CPU-DSP", - .cpu_dai_name = "samsung-i2s.0", - .codec_dai_name = "wm0010-sdi1", - .platform_name = "samsung-i2s.0", - .codec_name = "spi0.0", .init = speyside_wm0010_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAILINK_REG(cpu_dsp), }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", - .cpu_dai_name = "wm0010-sdi2", - .codec_dai_name = "wm8996-aif1", - .codec_name = "wm8996.1-001a", .init = speyside_wm8996_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, .params = &dsp_codec_params, .ignore_suspend = 1, + SND_SOC_DAILINK_REG(dsp_codec), }, { .name = "Baseband", .stream_name = "Baseband", - .cpu_dai_name = "wm8996-aif2", - .codec_dai_name = "wm1250-ev1", - .codec_name = "wm1250-ev1.1-0027", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, .ignore_suspend = 1, + SND_SOC_DAILINK_REG(baseband), }, };
ASoC is now supporting modern style dai_link (= snd_soc_dai_link_component) for CPU/Codec/Platform. This patch switches to use it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 85 +++++++++++++----------- 1 file changed, 48 insertions(+), 37 deletions(-)
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index d83cd03..f88c97a 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c @@ -111,14 +111,6 @@ static int mt8173_rt5650_rt5676_init(struct snd_soc_pcm_runtime *runtime) &mt8173_rt5650_rt5676_jack); }
-static struct snd_soc_dai_link_component mt8173_rt5650_rt5676_codecs[] = { - { - .dai_name = "rt5645-aif1", - }, - { - .dai_name = "rt5677-aif1", - }, -};
enum { DAI_LINK_PLAYBACK, @@ -129,47 +121,69 @@ enum { DAI_LINK_INTERCODEC };
+SND_SOC_DAILINK_DEFS(playback, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("DL1")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(capture, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("VUL")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(hdmi_pcm, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("HDMI")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(codec, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("I2S")), + DAILINK_COMPONENT_ARRAY(COMPONENT_BE(NULL, "rt5645-aif1"), + COMPONENT_BE(NULL, "rt5677-aif1")), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(hdmi_be, + DAILINK_COMPONENT_ARRAY(COMPONENT_FE("HDMIO")), + DAILINK_COMPONENT_ARRAY(COMPONENT_BE(NULL, "i2s-hifi")), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(intercodec, + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_BE(NULL, "rt5677-aif2")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY())); + /* Digital audio interface glue - connects codec <---> CPU */ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { /* Front End DAI links */ [DAI_LINK_PLAYBACK] = { .name = "rt5650_rt5676 Playback", .stream_name = "rt5650_rt5676 Playback", - .cpu_dai_name = "DL1", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dynamic = 1, .dpcm_playback = 1, + SND_SOC_DAILINK_REG(playback), }, [DAI_LINK_CAPTURE] = { .name = "rt5650_rt5676 Capture", .stream_name = "rt5650_rt5676 Capture", - .cpu_dai_name = "VUL", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dynamic = 1, .dpcm_capture = 1, + SND_SOC_DAILINK_REG(capture), }, [DAI_LINK_HDMI] = { .name = "HDMI", .stream_name = "HDMI PCM", - .cpu_dai_name = "HDMI", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dynamic = 1, .dpcm_playback = 1, + SND_SOC_DAILINK_REG(hdmi_pcm), },
/* Back End DAI links */ [DAI_LINK_CODEC_I2S] = { .name = "Codec", - .cpu_dai_name = "I2S", .no_pcm = 1, - .codecs = mt8173_rt5650_rt5676_codecs, - .num_codecs = 2, .init = mt8173_rt5650_rt5676_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, @@ -177,26 +191,23 @@ static struct snd_soc_dai_link mt8173_rt5650_rt5676_dais[] = { .ignore_pmdown_time = 1, .dpcm_playback = 1, .dpcm_capture = 1, + SND_SOC_DAILINK_REG(codec), }, [DAI_LINK_HDMI_I2S] = { .name = "HDMI BE", - .cpu_dai_name = "HDMIO", .no_pcm = 1, - .codec_dai_name = "i2s-hifi", .dpcm_playback = 1, + SND_SOC_DAILINK_REG(hdmi_be), }, /* rt5676 <-> rt5650 intercodec link: Sets rt5676 I2S2 as master */ [DAI_LINK_INTERCODEC] = { .name = "rt5650_rt5676 intercodec", .stream_name = "rt5650_rt5676 intercodec", - .cpu_dai_name = "snd-soc-dummy-dai", - .platform_name = "snd-soc-dummy", .no_pcm = 1, - .codec_dai_name = "rt5677-aif2", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, + SND_SOC_DAILINK_REG(intercodec), }, - };
static struct snd_soc_codec_conf mt8173_rt5650_rt5676_codec_conf[] = { @@ -235,34 +246,34 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) }
for_each_card_prelinks(card, i, dai_link) { - if (dai_link->platform_name) + if (dai_link->platforms->name) continue; - dai_link->platform_of_node = platform_node; + dai_link->platforms->of_node = platform_node; }
- mt8173_rt5650_rt5676_codecs[0].of_node = + mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 0); - if (!mt8173_rt5650_rt5676_codecs[0].of_node) { + if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); return -EINVAL; } - mt8173_rt5650_rt5676_codecs[1].of_node = + mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1); - if (!mt8173_rt5650_rt5676_codecs[1].of_node) { + if (!mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); return -EINVAL; } mt8173_rt5650_rt5676_codec_conf[0].of_node = - mt8173_rt5650_rt5676_codecs[1].of_node; + mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
- mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codec_of_node = - mt8173_rt5650_rt5676_codecs[1].of_node; + mt8173_rt5650_rt5676_dais[DAI_LINK_INTERCODEC].codecs->of_node = + mt8173_rt5650_rt5676_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
- mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codec_of_node = + mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 2); - if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codec_of_node) { + if (!mt8173_rt5650_rt5676_dais[DAI_LINK_HDMI_I2S].codecs->of_node) { dev_err(&pdev->dev, "Property 'audio-codec' missing or invalid\n"); return -EINVAL;
participants (2)
-
Kuninori Morimoto
-
Pierre-Louis Bossart