cns3xxx: support isolated PCI interrupts on newer Laguna PCBs
[openwrt/openwrt.git] / target / linux / omap / patches-3.12 / 401-ASoC-davinci-evm-Add-device-tree-binding.patch
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
5
6 Device tree support for Davinci Machine driver
7
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.
14
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>
18 ---
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
23
24 --- /dev/null
25 +++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
26 @@ -0,0 +1,58 @@
27 +* Texas Instruments SoC audio setups with TLV320AIC3X Codec
28 +
29 +Required properties:
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:
39 +
40 + TLV320AIC3X pins:
41 +
42 + * LLOUT
43 + * RLOUT
44 + * MONO_LOUT
45 + * HPLOUT
46 + * HPROUT
47 + * HPLCOM
48 + * HPRCOM
49 + * MIC3L
50 + * MIC3R
51 + * LINE1L
52 + * LINE2L
53 + * LINE1R
54 + * LINE2R
55 +
56 + Board connectors:
57 +
58 + * Headphone Jack
59 + * Line Out
60 + * Mic Jack
61 + * Line In
62 +
63 +
64 +Example:
65 +
66 +sound {
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>;
72 + ti,audio-routing =
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";
84 +};
85 --- a/sound/soc/davinci/davinci-evm.c
86 +++ b/sound/soc/davinci/davinci-evm.c
87 @@ -16,6 +16,7 @@
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>
95 @@ -23,6 +24,8 @@
96 #include <asm/dma.h>
97 #include <asm/mach-types.h>
98
99 +#include <linux/edma.h>
100 +
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
105 {
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;
109 + int ret;
110
111 /* Add davinci-evm specific widgets */
112 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
113 ARRAY_SIZE(aic3x_dapm_widgets));
114
115 - /* Set up davinci-evm specific audio path audio_map */
116 - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
117 + if (np) {
118 + ret = snd_soc_of_parse_audio_routing(codec->card,
119 + "ti,audio-routing");
120 + if (ret)
121 + return ret;
122 + } else {
123 + /* Set up davinci-evm specific audio path audio_map */
124 + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
125 + }
126
127 /* not connected */
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,
131 };
132
133 +#if defined(CONFIG_OF)
134 +
135 +/*
136 + * The struct is used as place holder. It will be completely
137 + * filled with data from dt node.
138 + */
139 +static struct snd_soc_dai_link evm_dai_tlv320aic3x = {
140 + .name = "TLV320AIC3X",
141 + .stream_name = "AIC3X",
142 + .codec_dai_name = "tlv320aic3x-hifi",
143 + .ops = &evm_ops,
144 + .init = evm_aic3x_init,
145 +};
146 +
147 +static const struct of_device_id davinci_evm_dt_ids[] = {
148 + {
149 + .compatible = "ti,da830-evm-audio",
150 + .data = (void *) &evm_dai_tlv320aic3x,
151 + },
152 + { /* sentinel */ }
153 +};
154 +MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids);
155 +
156 +/* davinci evm audio machine driver */
157 +static struct snd_soc_card evm_soc_card = {
158 + .owner = THIS_MODULE,
159 + .num_links = 1,
160 +};
161 +
162 +static int davinci_evm_probe(struct platform_device *pdev)
163 +{
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;
169 + int ret = 0;
170 +
171 + evm_soc_card.dai_link = dai;
172 +
173 + dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
174 + if (!dai->codec_of_node)
175 + return -EINVAL;
176 +
177 + dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
178 + if (!dai->cpu_of_node)
179 + return -EINVAL;
180 +
181 + dai->platform_of_node = dai->cpu_of_node;
182 +
183 + evm_soc_card.dev = &pdev->dev;
184 + ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
185 + if (ret)
186 + return ret;
187 +
188 + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
189 + if (!drvdata)
190 + return -ENOMEM;
191 +
192 + ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
193 + if (ret < 0)
194 + return -EINVAL;
195 +
196 + snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
197 + ret = snd_soc_register_card(&evm_soc_card);
198 +
199 + if (ret)
200 + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
201 +
202 + return ret;
203 +}
204 +
205 +static int davinci_evm_remove(struct platform_device *pdev)
206 +{
207 + struct snd_soc_card *card = platform_get_drvdata(pdev);
208 +
209 + snd_soc_unregister_card(card);
210 +
211 + return 0;
212 +}
213 +
214 +static struct platform_driver davinci_evm_driver = {
215 + .probe = davinci_evm_probe,
216 + .remove = davinci_evm_remove,
217 + .driver = {
218 + .name = "davinci_evm",
219 + .owner = THIS_MODULE,
220 + .of_match_table = of_match_ptr(davinci_evm_dt_ids),
221 + },
222 +};
223 +#endif
224 +
225 static struct platform_device *evm_snd_device;
226
227 static int __init evm_init(void)
228 @@ -320,6 +424,13 @@ static int __init evm_init(void)
229 int index;
230 int ret;
231
232 + /*
233 + * If dtb is there, the devices will be created dynamically.
234 + * Only register platfrom driver structure.
235 + */
236 + if (of_have_populated_dt())
237 + return platform_driver_register(&davinci_evm_driver);
238 +
239 if (machine_is_davinci_evm()) {
240 evm_snd_dev_data = &dm6446_snd_soc_card_evm;
241 index = 0;
242 @@ -355,6 +466,11 @@ static int __init evm_init(void)
243
244 static void __exit evm_exit(void)
245 {
246 + if (of_have_populated_dt()) {
247 + platform_driver_unregister(&davinci_evm_driver);
248 + return;
249 + }
250 +
251 platform_device_unregister(evm_snd_device);
252 }
253