From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current struct snd_soc_dai_link is supporting multicodec, and it is supporting legacy style of codec_name codec_of_node code_dai_name This is handled as single entry of multicodec.
Now, only CPU is not yet supporting snd_soc_dai_link_component style. If we could support it for CPU, we can switch to new style for all CPU/Codec/Platform, and remove legacy code from ALSA SoC.
It is mainly used for Multi-CPU support, but no plan so far. I hope it will be support in the future. This patch is initial support for snd_soc_dai_link_component for CPU ahead of time
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 5 ++++ sound/soc/soc-core.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index abd3aca..213187e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -906,6 +906,10 @@ struct snd_soc_dai_link { * only, which only works well when that device exposes a single DAI. */ const char *cpu_dai_name; + + struct snd_soc_dai_link_component *cpus; + unsigned int num_cpus; + /* * You MUST specify the link's codec, either by device name, or by * DT/OF node, but not both. @@ -991,6 +995,7 @@ struct snd_soc_dai_link { * drivers should not modify this value. */ unsigned int legacy_platform:1; + unsigned int legacy_cpu:1;
struct list_head list; /* DAI link list of the soc card */ struct snd_soc_dobj dobj; /* For topology */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 07a5851..b782f19 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -871,7 +871,6 @@ static int soc_bind_dai_link(struct snd_soc_card *card, { struct snd_soc_pcm_runtime *rtd; struct snd_soc_dai_link_component *codecs; - struct snd_soc_dai_link_component cpu_dai_component; struct snd_soc_component *component; struct snd_soc_dai **codec_dais; int i; @@ -891,13 +890,11 @@ static int soc_bind_dai_link(struct snd_soc_card *card, if (!rtd) return -ENOMEM;
- cpu_dai_component.name = dai_link->cpu_name; - cpu_dai_component.of_node = dai_link->cpu_of_node; - cpu_dai_component.dai_name = dai_link->cpu_dai_name; - rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component); + /* FIXME: we need multi CPU support in the future */ + rtd->cpu_dai = snd_soc_find_dai(dai_link->cpus); if (!rtd->cpu_dai) { dev_info(card->dev, "ASoC: CPU DAI %s not registered\n", - dai_link->cpu_dai_name); + dai_link->cpus->dai_name); goto _err_defer; } snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component); @@ -1032,6 +1029,41 @@ static void soc_remove_dai_links(struct snd_soc_card *card) } }
+static int snd_soc_init_cpu(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link) +{ + struct snd_soc_dai_link_component *cpu = dai_link->cpus; + + /* + * FIXME + * + * this function should be removed in the future + */ + /* convert Legacy platform link */ + if (!cpu || dai_link->legacy_cpu) { + cpu = devm_kzalloc(card->dev, + sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!cpu) + return -ENOMEM; + + dai_link->cpus = cpu; + dai_link->num_cpus = 1; + dai_link->legacy_cpu = 1; + + cpu->name = dai_link->cpu_name; + cpu->of_node = dai_link->cpu_of_node; + cpu->dai_name = dai_link->cpu_dai_name; + } + + if (!dai_link->cpus) { + dev_err(card->dev, "ASoC: DAI link has no CPUs\n"); + return -EINVAL; + } + + return 0; +} + static int snd_soc_init_platform(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { @@ -1099,6 +1131,12 @@ static int soc_init_dai_link(struct snd_soc_card *card, int i, ret; struct snd_soc_dai_link_component *codec;
+ ret = snd_soc_init_cpu(card, link); + if (ret) { + dev_err(card->dev, "ASoC: failed to init cpu\n"); + return ret; + } + ret = snd_soc_init_platform(card, link); if (ret) { dev_err(card->dev, "ASoC: failed to init multiplatform\n"); @@ -1156,12 +1194,20 @@ static int soc_init_dai_link(struct snd_soc_card *card, if (!soc_find_component(link->platforms->of_node, link->platforms->name)) return -EPROBE_DEFER;
+ /* FIXME */ + if (link->num_cpus > 1) { + dev_err(card->dev, + "ASoC: multi cpu is not yet supported %s\n", + link->name); + return -EINVAL; + } + /* * CPU device may be specified by either name or OF node, but * can be left unspecified, and will be matched based on DAI * name alone.. */ - if (link->cpu_name && link->cpu_of_node) { + if (link->cpus->name && link->cpus->of_node) { dev_err(card->dev, "ASoC: Neither/both cpu name/of_node are set for %s\n", link->name); @@ -1172,15 +1218,15 @@ static int soc_init_dai_link(struct snd_soc_card *card, * Defer card registartion if cpu dai component is not added to * component list. */ - if (!soc_find_component(link->cpu_of_node, link->cpu_name)) + if (!soc_find_component(link->cpus->of_node, link->cpus->name)) return -EPROBE_DEFER;
/* * At least one of CPU DAI name or CPU device name/node must be * specified */ - if (!link->cpu_dai_name && - !(link->cpu_name || link->cpu_of_node)) { + if (!link->cpus->dai_name && + !(link->cpus->name || link->cpus->of_node)) { dev_err(card->dev, "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n", link->name);