ASoC sound driver requires CPU/CODEC drivers for probing, and each CPU/CODEC has some DAI on it. Then, "dai name matching" have been used to identify CPU-CODEC DAI pair on ASoC.
But, the "dai port number matching" is now required from DeviceTree. The solution of this issue is to replace the dai port number into dai name, and it needs some kind of .of_xlate function on each driver.
This patch adds .of_xlate_dai_name callback interface on struct snd_soc_dai_driver, very basic/common snd_soc_common_of_xlate_dai_name() which replace the dai port number into dai name, and snd_soc_of_get_port_dai_name() which is using .of_xlate_dai_name.
Then, #sound-dai-cells which enables DAI specifier is required on CPU/CODEC device tree properties.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- v5 -> v6
- adds of_xlate_dai_name()
include/sound/soc-dai.h | 4 ++++ include/sound/soc.h | 5 +++++ sound/soc/soc-core.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 4dbd3e7..0b5a02f 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -15,6 +15,7 @@
#include <linux/list.h> +#include <linux/of.h>
struct snd_pcm_substream; struct snd_soc_dapm_widget; @@ -206,6 +207,9 @@ struct snd_soc_dai_driver { int (*remove)(struct snd_soc_dai *dai); int (*suspend)(struct snd_soc_dai *dai); int (*resume)(struct snd_soc_dai *dai); + const char* (*of_xlate_dai_name)(struct snd_soc_dai *dai, + const struct of_phandle_args *args); + /* compress dai */ bool compress_dai;
diff --git a/include/sound/soc.h b/include/sound/soc.h index e227880..26a1ba6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -21,6 +21,7 @@ #include <linux/kernel.h> #include <linux/regmap.h> #include <linux/log2.h> +#include <linux/of.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/compress_driver.h> @@ -1171,6 +1172,10 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, const char *propname); unsigned int snd_soc_of_parse_daifmt(struct device_node *np, const char *prefix); +const char *snd_soc_common_of_xlate_dai_name(struct snd_soc_dai *dai, + const struct of_phandle_args *args); +const char *snd_soc_of_get_port_dai_name(struct device_node *nf_node, + const char *prop);
#include <sound/soc-dai.h>
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 689eb04..e80fd27 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4286,6 +4286,46 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+const char *snd_soc_common_of_xlate_dai_name(struct snd_soc_dai *dai, + const struct of_phandle_args *args) +{ + if (dai->id != args->args[0]) + return NULL; + + return dai->driver->name; +} +EXPORT_SYMBOL_GPL(snd_soc_common_of_xlate_dai_name); + +const char *snd_soc_of_get_port_dai_name(struct device_node *of_node, + const char *prop) +{ + struct snd_soc_dai *dai; + struct of_phandle_args args; + const char *name; + int ret; + + ret = of_parse_phandle_with_args(of_node, prop, + "#sound-dai-cells", 0, &args); + if (ret) + return NULL; + + of_node_put(args.np); + + list_for_each_entry(dai, &dai_list, list) { + if (dai->dev->of_node != args.np) + continue; + + if (dai->driver->of_xlate_dai_name) { + name = dai->driver->of_xlate_dai_name(dai, &args); + if (name) + return name; + } + } + + return NULL; +} +EXPORT_SYMBOL_GPL(snd_soc_of_get_port_dai_name); + static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS