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
24 diff --git a/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
26 index 0000000..e6b61ff
28 +++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
30 +* Texas Instruments SoC audio setups with TLV320AIC3X Codec
33 +- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
34 +- ti,model : The user-visible name of this sound complex.
35 +- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
36 +- ti,mcasp-controller : The phandle of the McASP controller
37 +- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec
38 +- ti,audio-routing : A list of the connections between audio components.
39 + Each entry is a pair of strings, the first being the connection's sink,
40 + the second being the connection's source. Valid names for sources and
41 + sinks are the codec's pins, and the jacks on the board:
70 + compatible = "ti,da830-evm-audio";
71 + ti,model = "DA830 EVM";
72 + ti,audio-codec = <&tlv320aic3x>;
73 + ti,mcasp-controller = <&mcasp1>;
74 + ti,codec-clock-rate = <12000000>;
76 + "Headphone Jack", "HPLOUT",
77 + "Headphone Jack", "HPROUT",
78 + "Line Out", "LLOUT",
79 + "Line Out", "RLOUT",
80 + "MIC3L", "Mic Bias 2V",
81 + "MIC3R", "Mic Bias 2V",
82 + "Mic Bias 2V", "Mic Jack",
83 + "LINE1L", "Line In",
84 + "LINE2L", "Line In",
85 + "LINE1R", "Line In",
86 + "LINE2R", "Line In";
88 diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
89 index 2f8161c..340a68d 100644
90 --- a/sound/soc/davinci/davinci-evm.c
91 +++ b/sound/soc/davinci/davinci-evm.c
93 #include <linux/platform_device.h>
94 #include <linux/platform_data/edma.h>
95 #include <linux/i2c.h>
96 +#include <linux/of_platform.h>
97 #include <sound/core.h>
98 #include <sound/pcm.h>
99 #include <sound/soc.h>
102 #include <asm/mach-types.h>
104 +#include <linux/edma.h>
106 #include "davinci-pcm.h"
107 #include "davinci-i2s.h"
108 #include "davinci-mcasp.h"
109 @@ -121,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
111 struct snd_soc_codec *codec = rtd->codec;
112 struct snd_soc_dapm_context *dapm = &codec->dapm;
113 + struct device_node *np = codec->card->dev->of_node;
116 /* Add davinci-evm specific widgets */
117 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
118 ARRAY_SIZE(aic3x_dapm_widgets));
120 - /* Set up davinci-evm specific audio path audio_map */
121 - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
123 + ret = snd_soc_of_parse_audio_routing(codec->card,
124 + "ti,audio-routing");
128 + /* Set up davinci-evm specific audio path audio_map */
129 + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
133 snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
134 @@ -312,6 +324,98 @@ static struct snd_soc_card da850_snd_soc_card = {
135 .drvdata = &da850_snd_soc_card_drvdata,
138 +#if defined(CONFIG_OF)
141 + * The struct is used as place holder. It will be completely
142 + * filled with data from dt node.
144 +static struct snd_soc_dai_link evm_dai_tlv320aic3x = {
145 + .name = "TLV320AIC3X",
146 + .stream_name = "AIC3X",
147 + .codec_dai_name = "tlv320aic3x-hifi",
149 + .init = evm_aic3x_init,
152 +static const struct of_device_id davinci_evm_dt_ids[] = {
154 + .compatible = "ti,da830-evm-audio",
155 + .data = (void *) &evm_dai_tlv320aic3x,
159 +MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids);
161 +/* davinci evm audio machine driver */
162 +static struct snd_soc_card evm_soc_card = {
163 + .owner = THIS_MODULE,
167 +static int davinci_evm_probe(struct platform_device *pdev)
169 + struct device_node *np = pdev->dev.of_node;
170 + const struct of_device_id *match =
171 + of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
172 + struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
173 + struct snd_soc_card_drvdata_davinci *drvdata = NULL;
176 + evm_soc_card.dai_link = dai;
178 + dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
179 + if (!dai->codec_of_node)
182 + dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
183 + if (!dai->cpu_of_node)
186 + dai->platform_of_node = dai->cpu_of_node;
188 + evm_soc_card.dev = &pdev->dev;
189 + ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
193 + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
197 + ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
201 + snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
202 + ret = snd_soc_register_card(&evm_soc_card);
205 + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
210 +static int davinci_evm_remove(struct platform_device *pdev)
212 + struct snd_soc_card *card = platform_get_drvdata(pdev);
214 + snd_soc_unregister_card(card);
219 +static struct platform_driver davinci_evm_driver = {
220 + .probe = davinci_evm_probe,
221 + .remove = davinci_evm_remove,
223 + .name = "davinci_evm",
224 + .owner = THIS_MODULE,
225 + .of_match_table = of_match_ptr(davinci_evm_dt_ids),
230 static struct platform_device *evm_snd_device;
232 static int __init evm_init(void)
233 @@ -320,6 +424,13 @@ static int __init evm_init(void)
238 + * If dtb is there, the devices will be created dynamically.
239 + * Only register platfrom driver structure.
241 + if (of_have_populated_dt())
242 + return platform_driver_register(&davinci_evm_driver);
244 if (machine_is_davinci_evm()) {
245 evm_snd_dev_data = &dm6446_snd_soc_card_evm;
247 @@ -355,6 +466,11 @@ static int __init evm_init(void)
249 static void __exit evm_exit(void)
251 + if (of_have_populated_dt()) {
252 + platform_driver_unregister(&davinci_evm_driver);
256 platform_device_unregister(evm_snd_device);