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 each struct snd_soc_cpu/codec_driver, and snd_soc_of_get_cpu/codec_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 --- v6 -> v7
- return int instead of char* - for_each from cpu/codec list - used sound-dai and #sound-dai-cells
include/sound/soc.h | 14 ++++++++++++++ sound/soc/soc-core.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+)
diff --git a/include/sound/soc.h b/include/sound/soc.h index faffc9c..343a7c5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -13,6 +13,7 @@ #ifndef __LINUX_SND_SOC_H #define __LINUX_SND_SOC_H
+#include <linux/of.h> #include <linux/platform_device.h> #include <linux/types.h> #include <linux/notifier.h> @@ -770,6 +771,11 @@ struct snd_soc_codec_driver { /* codec stream completion event */ int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
+ /* DT */ + int (*of_xlate_dai_name)(struct snd_soc_codec *codec, + struct of_phandle_args *args, + const char **dai_name); + bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */
/* probe ordering - for components with runtime dependencies */ @@ -846,6 +852,10 @@ struct snd_soc_platform { };
struct snd_soc_cpu_driver { + /* DT */ + int (*of_xlate_dai_name)(struct snd_soc_cpu *codec, + const struct of_phandle_args *args, + const char **dai_name); };
struct snd_soc_cpu { @@ -1190,6 +1200,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); +int snd_soc_of_get_codec_dai_name(struct device_node *of_node, + const char **dai_name); +int snd_soc_of_get_cpu_dai_name(struct device_node *of_node, + const char **dai_name);
#include <sound/soc-dai.h>
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 14976ff..da9a93d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4361,6 +4361,46 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+#define SND_SOC_OF_GET_DAI_NAME(contents) \ +int snd_soc_of_get_ ## contents ## _dai_name(struct device_node *of_node,\ + const char **dai_name) \ +{ \ + struct snd_soc_ ## contents *pos; \ + struct of_phandle_args args; \ + int ret; \ + \ + ret = of_parse_phandle_with_args(of_node, "sound-dai", \ + "#sound-dai-cells", 0, &args); \ + if (ret) \ + return ret; \ + \ + ret = -EPROBE_DEFER; \ + \ + mutex_lock(&client_mutex); \ + list_for_each_entry(pos, &contents ## _list, list) { \ + if (pos->dev->of_node != args.np) \ + continue; \ + \ + if (!pos->driver->of_xlate_dai_name) { \ + ret = -EIO; \ + break; \ + } \ + \ + ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);\ + break; \ + } \ + mutex_unlock(&client_mutex); \ + \ + of_node_put(args.np); \ + \ + return ret; \ +} + +SND_SOC_OF_GET_DAI_NAME(codec) +SND_SOC_OF_GET_DAI_NAME(cpu) +EXPORT_SYMBOL_GPL(snd_soc_of_get_codec_dai_name); +EXPORT_SYMBOL_GPL(snd_soc_of_get_cpu_dai_name); + static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS