aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-12-21 12:40:59 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-12-22 06:00:21 -0500
commit5a5049637cf08c4c17805be679c19544bb27fb92 (patch)
tree3519d679c700f79bdfddc8d2779801415ea83b18
parent82150101df27c0f3d315b597081b9fa0e23cd002 (diff)
ASoC: Allow DAI links to be specified using device tree nodes
DAI link endpoints and platform (DMA) devices are currently specified by name. When instantiating sound cards from device tree, it may be more convenient to refer to these devices by phandle in the device tree, and for code to describe DAI links using the "struct device_node *" ("of_node") those phandles map to. This change adds new fields to snd_soc_dai_link which can "name" devices using of_node, enhances soc_bind_dai_link() to allow binding based on of_node, and enhances snd_soc_register_card() to ensure that illegal combinations of name and of_node are not used. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--include/sound/soc.h4
-rw-r--r--sound/soc/soc-core.c64
2 files changed, 61 insertions, 7 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index db8acd299043..8391b0ec217e 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -231,6 +231,7 @@ enum snd_soc_bias_level {
231 SND_SOC_BIAS_ON = 3, 231 SND_SOC_BIAS_ON = 3,
232}; 232};
233 233
234struct device_node;
234struct snd_jack; 235struct snd_jack;
235struct snd_soc_card; 236struct snd_soc_card;
236struct snd_soc_pcm_stream; 237struct snd_soc_pcm_stream;
@@ -703,8 +704,11 @@ struct snd_soc_dai_link {
703 const char *name; /* Codec name */ 704 const char *name; /* Codec name */
704 const char *stream_name; /* Stream name */ 705 const char *stream_name; /* Stream name */
705 const char *codec_name; /* for multi-codec */ 706 const char *codec_name; /* for multi-codec */
707 const struct device_node *codec_of_node;
706 const char *platform_name; /* for multi-platform */ 708 const char *platform_name; /* for multi-platform */
709 const struct device_node *platform_of_node;
707 const char *cpu_dai_name; 710 const char *cpu_dai_name;
711 const struct device_node *cpu_dai_of_node;
708 const char *codec_dai_name; 712 const char *codec_dai_name;
709 713
710 unsigned int dai_fmt; /* format to set on init */ 714 unsigned int dai_fmt; /* format to set on init */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 42ad2db8f082..a4592cbee49b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -764,8 +764,13 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
764 } 764 }
765 /* no, then find CPU DAI from registered DAIs*/ 765 /* no, then find CPU DAI from registered DAIs*/
766 list_for_each_entry(cpu_dai, &dai_list, list) { 766 list_for_each_entry(cpu_dai, &dai_list, list) {
767 if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) 767 if (dai_link->cpu_dai_of_node) {
768 continue; 768 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node)
769 continue;
770 } else {
771 if (strcmp(cpu_dai->name, dai_link->cpu_dai_name))
772 continue;
773 }
769 774
770 rtd->cpu_dai = cpu_dai; 775 rtd->cpu_dai = cpu_dai;
771 goto find_codec; 776 goto find_codec;
@@ -781,8 +786,13 @@ find_codec:
781 786
782 /* no, then find CODEC from registered CODECs*/ 787 /* no, then find CODEC from registered CODECs*/
783 list_for_each_entry(codec, &codec_list, list) { 788 list_for_each_entry(codec, &codec_list, list) {
784 if (strcmp(codec->name, dai_link->codec_name)) 789 if (dai_link->codec_of_node) {
785 continue; 790 if (codec->dev->of_node != dai_link->codec_of_node)
791 continue;
792 } else {
793 if (strcmp(codec->name, dai_link->codec_name))
794 continue;
795 }
786 796
787 rtd->codec = codec; 797 rtd->codec = codec;
788 798
@@ -814,13 +824,19 @@ find_platform:
814 824
815 /* if there's no platform we match on the empty platform */ 825 /* if there's no platform we match on the empty platform */
816 platform_name = dai_link->platform_name; 826 platform_name = dai_link->platform_name;
817 if (!platform_name) 827 if (!platform_name && !dai_link->platform_of_node)
818 platform_name = "snd-soc-dummy"; 828 platform_name = "snd-soc-dummy";
819 829
820 /* no, then find one from the set of registered platforms */ 830 /* no, then find one from the set of registered platforms */
821 list_for_each_entry(platform, &platform_list, list) { 831 list_for_each_entry(platform, &platform_list, list) {
822 if (strcmp(platform->name, platform_name)) 832 if (dai_link->platform_of_node) {
823 continue; 833 if (platform->dev->of_node !=
834 dai_link->platform_of_node)
835 continue;
836 } else {
837 if (strcmp(platform->name, platform_name))
838 continue;
839 }
824 840
825 rtd->platform = platform; 841 rtd->platform = platform;
826 goto out; 842 goto out;
@@ -2831,6 +2847,40 @@ int snd_soc_register_card(struct snd_soc_card *card)
2831 if (!card->name || !card->dev) 2847 if (!card->name || !card->dev)
2832 return -EINVAL; 2848 return -EINVAL;
2833 2849
2850 for (i = 0; i < card->num_links; i++) {
2851 struct snd_soc_dai_link *link = &card->dai_link[i];
2852
2853 /*
2854 * Codec must be specified by 1 of name or OF node,
2855 * not both or neither.
2856 */
2857 if (!!link->codec_name == !!link->codec_of_node) {
2858 dev_err(card->dev,
2859 "Neither/both codec name/of_node are set\n");
2860 return -EINVAL;
2861 }
2862
2863 /*
2864 * Platform may be specified by either name or OF node, but
2865 * can be left unspecified, and a dummy platform will be used.
2866 */
2867 if (link->platform_name && link->platform_of_node) {
2868 dev_err(card->dev,
2869 "Both platform name/of_node are set\n");
2870 return -EINVAL;
2871 }
2872
2873 /*
2874 * CPU DAI must be specified by 1 of name or OF node,
2875 * not both or neither.
2876 */
2877 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) {
2878 dev_err(card->dev,
2879 "Neither/both cpu_dai name/of_node are set\n");
2880 return -EINVAL;
2881 }
2882 }
2883
2834 dev_set_drvdata(card->dev, card); 2884 dev_set_drvdata(card->dev, card);
2835 2885
2836 snd_soc_initialize_card_lists(card); 2886 snd_soc_initialize_card_lists(card);