[alsa-devel] [PATCH v3][RFC] ASoC: modern style CPU
Hi Mark, Pierre-Louis
Sorry for my random posting. These are v3 of RFC of modern style CPU support. I brush-uped macro by using __VA_ARGS__.
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
Thank you for your help !! Best regards --- Kuninori Morimoto
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 23463ba..da6c386 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1043,6 +1043,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_CPU("cpu_dai")), + * DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC("codec", "codec_dai")), + * DAILINK_COMPONENT_ARRAY(COMPONENT_PLATFORM("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_CPU("cpu_dai1"), + * COMPONENT_CPU("cpu_dai2")), + * DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC("codec1", "codec_dai1"), + * COMPONENT_CODEC("codec2", "codec_dai2"))); + * + * struct snd_soc_dai_link link = { + * ... + * SND_SOC_DAILINK_REG(test), + * }; + * + * Sample3. Define each CPU/Codec/Platform manually + * + * SND_SOC_DAILINK_DEF(test_cpu, + * DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("cpu_dai1"), + * COMPONENT_CPU("cpu_dai2"))); + * SND_SOC_DAILINK_DEF(test_codec, + * DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC("codec1", "codec_dai1"), + * COMPONENT_CODEC("codec2", "codec_dai2"))); + * SND_SOC_DAILINK_DEF(test_platform, + * DAILINK_COMPONENT_ARRAY(COMPONENT_PLATFORM("platform"))); + * + * struct snd_soc_dai_link link = { + * ... + * SND_SOC_DAILINK_REG(test_cpu, + * test_codec, + * test_platform), + * }; + * + * Sample4. 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_REG_FUNC(_1, _2, _3, func, ...) func +#define SND_SOC_DAILINK_REG(...) \ + SND_SOC_DAILINK_REG_FUNC(__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_CPU(_dai) { .dai_name = _dai, } +#define COMPONENT_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, } +#define COMPONENT_PLATFORM(_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 4c1fdad..8cb7b10 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.
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..d393361 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_CPU("DL1")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(capture, + DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("VUL")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(hdmi_pcm, + DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("HDMI")), + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(codec, + DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("I2S")), + DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC(NULL, "rt5645-aif1"), + COMPONENT_CODEC(NULL, "rt5677-aif1")), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(hdmi_be, + DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("HDMIO")), + DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC(NULL, "i2s-hifi")), + DAILINK_COMPONENT_ARRAY(COMPONENT_EMPTY())); + +SND_SOC_DAILINK_DEFS(intercodec, + DAILINK_COMPONENT_ARRAY(COMPONENT_DUMMY()), + DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC(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;
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/smdk_wm8580.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 6e4dfa7..8188589 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -147,27 +147,31 @@ enum { #define SMDK_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ SND_SOC_DAIFMT_CBM_CFM)
+SND_SOC_DAILINK_DEFS(paif_rx, + DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("samsung-i2s.2")), + DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC("wm8580.0-001b", "wm8580-hifi-playback")), + DAILINK_COMPONENT_ARRAY(COMPONENT_PLATFORM("samsung-i2s.0"))); + +SND_SOC_DAILINK_DEFS(paif_tx, + DAILINK_COMPONENT_ARRAY(COMPONENT_CPU("samsung-i2s.2")), + DAILINK_COMPONENT_ARRAY(COMPONENT_CODEC("wm8580.0-001b", "wm8580-hifi-capture")), + DAILINK_COMPONENT_ARRAY(COMPONENT_PLATFORM("samsung-i2s.0"))); + static struct snd_soc_dai_link smdk_dai[] = { [PRI_PLAYBACK] = { /* Primary Playback i/f */ .name = "WM8580 PAIF RX", .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-i2s.0", - .codec_name = "wm8580.0-001b", .dai_fmt = SMDK_DAI_FMT, .ops = &smdk_ops, + SND_SOC_DAILINK_REG(paif_rx), }, [PRI_CAPTURE] = { /* Primary Capture i/f */ .name = "WM8580 PAIF TX", .stream_name = "Capture", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "samsung-i2s.0", - .codec_name = "wm8580.0-001b", .dai_fmt = SMDK_DAI_FMT, .init = smdk_wm8580_init_paiftx, .ops = &smdk_ops, + SND_SOC_DAILINK_REG(paif_tx), }, };
participants (1)
-
Kuninori Morimoto