1 From af9ef849e8700327b807361344427a43c38e823a Mon Sep 17 00:00:00 2001
2 From: "Hebbar, Gururaja" <gururaja.hebbar@ti.com>
3 Date: Tue, 31 Jul 2012 21:25:38 +0530
4 Subject: [PATCH 212/752] ASoC: davinci-evm: Add device tree binding
6 Device tree support for Davinci Machine driver
8 When the board boots with device tree, the driver will receive card,
9 codec, dai interface details (like the card name, DAPM routing map,
10 phandle for the audio components described in the dts file, codec mclk
11 speed). The card will be set up based on this information. Since the
12 routing is provided via DT we can mark the card fully routed so core
13 can take care of disconnecting the unused pins.
15 Signed-off-by: Hebbar, Gururaja <gururaja.hebbar@ti.com>
16 Signed-off-by: Darren Etheridge <detheridge@ti.com>
17 Signed-off-by: Jyri Sarha <jsarha@ti.com>
19 .../bindings/sound/davinci-evm-audio.txt | 58 ++++++++++
20 sound/soc/davinci/davinci-evm.c | 120 +++++++++++++++++++-
21 2 files changed, 176 insertions(+), 2 deletions(-)
22 create mode 100644 Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
25 +++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
27 +* Texas Instruments SoC audio setups with TLV320AIC3X Codec
30 +- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
31 +- ti,model : The user-visible name of this sound complex.
32 +- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
33 +- ti,mcasp-controller : The phandle of the McASP controller
34 +- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec
35 +- ti,audio-routing : A list of the connections between audio components.
36 + Each entry is a pair of strings, the first being the connection's sink,
37 + the second being the connection's source. Valid names for sources and
38 + sinks are the codec's pins, and the jacks on the board:
67 + compatible = "ti,da830-evm-audio";
68 + ti,model = "DA830 EVM";
69 + ti,audio-codec = <&tlv320aic3x>;
70 + ti,mcasp-controller = <&mcasp1>;
71 + ti,codec-clock-rate = <12000000>;
73 + "Headphone Jack", "HPLOUT",
74 + "Headphone Jack", "HPROUT",
75 + "Line Out", "LLOUT",
76 + "Line Out", "RLOUT",
77 + "MIC3L", "Mic Bias 2V",
78 + "MIC3R", "Mic Bias 2V",
79 + "Mic Bias 2V", "Mic Jack",
80 + "LINE1L", "Line In",
81 + "LINE2L", "Line In",
82 + "LINE1R", "Line In",
83 + "LINE2R", "Line In";
85 --- a/sound/soc/davinci/davinci-evm.c
86 +++ b/sound/soc/davinci/davinci-evm.c
88 #include <linux/platform_device.h>
89 #include <linux/platform_data/edma.h>
90 #include <linux/i2c.h>
91 +#include <linux/of_platform.h>
92 #include <sound/core.h>
93 #include <sound/pcm.h>
94 #include <sound/soc.h>
97 #include <asm/mach-types.h>
99 +#include <linux/edma.h>
101 #include "davinci-pcm.h"
102 #include "davinci-i2s.h"
103 #include "davinci-mcasp.h"
104 @@ -121,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc
106 struct snd_soc_codec *codec = rtd->codec;
107 struct snd_soc_dapm_context *dapm = &codec->dapm;
108 + struct device_node *np = codec->card->dev->of_node;
111 /* Add davinci-evm specific widgets */
112 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
113 ARRAY_SIZE(aic3x_dapm_widgets));
115 - /* Set up davinci-evm specific audio path audio_map */
116 - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
118 + ret = snd_soc_of_parse_audio_routing(codec->card,
119 + "ti,audio-routing");
123 + /* Set up davinci-evm specific audio path audio_map */
124 + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
128 snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
129 @@ -312,6 +324,98 @@ static struct snd_soc_card da850_snd_soc
130 .drvdata = &da850_snd_soc_card_drvdata,
133 +#if defined(CONFIG_OF)
136 + * The struct is used as place holder. It will be completely
137 + * filled with data from dt node.
139 +static struct snd_soc_dai_link evm_dai_tlv320aic3x = {
140 + .name = "TLV320AIC3X",
141 + .stream_name = "AIC3X",
142 + .codec_dai_name = "tlv320aic3x-hifi",
144 + .init = evm_aic3x_init,
147 +static const struct of_device_id davinci_evm_dt_ids[] = {
149 + .compatible = "ti,da830-evm-audio",
150 + .data = (void *) &evm_dai_tlv320aic3x,
154 +MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids);
156 +/* davinci evm audio machine driver */
157 +static struct snd_soc_card evm_soc_card = {
158 + .owner = THIS_MODULE,
162 +static int davinci_evm_probe(struct platform_device *pdev)
164 + struct device_node *np = pdev->dev.of_node;
165 + const struct of_device_id *match =
166 + of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
167 + struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
168 + struct snd_soc_card_drvdata_davinci *drvdata = NULL;
171 + evm_soc_card.dai_link = dai;
173 + dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
174 + if (!dai->codec_of_node)
177 + dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
178 + if (!dai->cpu_of_node)
181 + dai->platform_of_node = dai->cpu_of_node;
183 + evm_soc_card.dev = &pdev->dev;
184 + ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
188 + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
192 + ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
196 + snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
197 + ret = snd_soc_register_card(&evm_soc_card);
200 + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
205 +static int davinci_evm_remove(struct platform_device *pdev)
207 + struct snd_soc_card *card = platform_get_drvdata(pdev);
209 + snd_soc_unregister_card(card);
214 +static struct platform_driver davinci_evm_driver = {
215 + .probe = davinci_evm_probe,
216 + .remove = davinci_evm_remove,
218 + .name = "davinci_evm",
219 + .owner = THIS_MODULE,
220 + .of_match_table = of_match_ptr(davinci_evm_dt_ids),
225 static struct platform_device *evm_snd_device;
227 static int __init evm_init(void)
228 @@ -320,6 +424,13 @@ static int __init evm_init(void)
233 + * If dtb is there, the devices will be created dynamically.
234 + * Only register platfrom driver structure.
236 + if (of_have_populated_dt())
237 + return platform_driver_register(&davinci_evm_driver);
239 if (machine_is_davinci_evm()) {
240 evm_snd_dev_data = &dm6446_snd_soc_card_evm;
242 @@ -355,6 +466,11 @@ static int __init evm_init(void)
244 static void __exit evm_exit(void)
246 + if (of_have_populated_dt()) {
247 + platform_driver_unregister(&davinci_evm_driver);
251 platform_device_unregister(evm_snd_device);