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