aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2012-09-10 06:46:25 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-09-22 11:15:04 -0400
commit7bf7ff6f57dcb30c80ad1b65cebdebf4feb3c666 (patch)
tree52714d1f45e70ec9a767d62bd436949e5281eeb2
parent5382a0171f2069ed259d7a86f19822a1af2488d4 (diff)
mfd: twl4030-audio: Add DT support
Support for loading the twl4030 audio module via devicetree. Sub devices for codec and vibra will be created as mfd devices once the core MFD driver is loaded when the kernel is booted with a DT blob. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--Documentation/devicetree/bindings/mfd/twl4030-audio.txt46
-rw-r--r--drivers/mfd/twl4030-audio.c54
2 files changed, 93 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
new file mode 100644
index 000000000000..414d2ae0adf6
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
@@ -0,0 +1,46 @@
1Texas Instruments TWL family (twl4030) audio module
2
3The audio module inside the TWL family consist of an audio codec and a vibra
4driver.
5
6Required properties:
7- compatible : must be "ti,twl4030-audio"
8
9Optional properties, nodes:
10
11Audio functionality:
12- codec { }: Need to be present if the audio functionality is used. Within this
13 section the following options can be used:
14- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts
15 from the start of the recorded sample (in ms)
16-ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise
17-ti,hs_extmute: Use external mute for HS pop reduction
18-ti,hs_extmute_gpio: Use external GPIO to control the external mute
19-ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the
20 valid values.
21
22Vibra functionality
23- ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if
24 missing or it is 0, the vibra functionality is disabled.
25
26Example:
27&i2c1 {
28 clock-frequency = <2600000>;
29
30 twl: twl@48 {
31 reg = <0x48>;
32 interrupts = <7>; /* SYS_NIRQ cascaded to intc */
33 interrupt-parent = <&intc>;
34
35 twl_audio: audio {
36 compatible = "ti,twl4030-audio";
37
38 ti,enable-vibra = <1>;
39
40 codec {
41 ti,ramp_delay_value = <3>;
42 };
43
44 };
45 };
46};
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index a48bf3af1240..58e6c228653b 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -28,6 +28,8 @@
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/of.h>
32#include <linux/of_platform.h>
31#include <linux/i2c/twl.h> 33#include <linux/i2c/twl.h>
32#include <linux/mfd/core.h> 34#include <linux/mfd/core.h>
33#include <linux/mfd/twl4030-audio.h> 35#include <linux/mfd/twl4030-audio.h>
@@ -156,15 +158,42 @@ unsigned int twl4030_audio_get_mclk(void)
156} 158}
157EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); 159EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
158 160
161static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
162 struct device_node *node)
163{
164 if (pdata && pdata->codec)
165 return true;
166
167 if (of_find_node_by_name(node, "codec"))
168 return true;
169
170 return false;
171}
172
173static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
174 struct device_node *node)
175{
176 int vibra;
177
178 if (pdata && pdata->vibra)
179 return true;
180
181 if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra)
182 return true;
183
184 return false;
185}
186
159static int __devinit twl4030_audio_probe(struct platform_device *pdev) 187static int __devinit twl4030_audio_probe(struct platform_device *pdev)
160{ 188{
161 struct twl4030_audio *audio; 189 struct twl4030_audio *audio;
162 struct twl4030_audio_data *pdata = pdev->dev.platform_data; 190 struct twl4030_audio_data *pdata = pdev->dev.platform_data;
191 struct device_node *node = pdev->dev.of_node;
163 struct mfd_cell *cell = NULL; 192 struct mfd_cell *cell = NULL;
164 int ret, childs = 0; 193 int ret, childs = 0;
165 u8 val; 194 u8 val;
166 195
167 if (!pdata) { 196 if (!pdata && !node) {
168 dev_err(&pdev->dev, "Platform data is missing\n"); 197 dev_err(&pdev->dev, "Platform data is missing\n");
169 return -EINVAL; 198 return -EINVAL;
170 } 199 }
@@ -202,18 +231,22 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
202 audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL; 231 audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
203 audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN; 232 audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;
204 233
205 if (pdata->codec) { 234 if (twl4030_audio_has_codec(pdata, node)) {
206 cell = &audio->cells[childs]; 235 cell = &audio->cells[childs];
207 cell->name = "twl4030-codec"; 236 cell->name = "twl4030-codec";
208 cell->platform_data = pdata->codec; 237 if (pdata) {
209 cell->pdata_size = sizeof(*pdata->codec); 238 cell->platform_data = pdata->codec;
239 cell->pdata_size = sizeof(*pdata->codec);
240 }
210 childs++; 241 childs++;
211 } 242 }
212 if (pdata->vibra) { 243 if (twl4030_audio_has_vibra(pdata, node)) {
213 cell = &audio->cells[childs]; 244 cell = &audio->cells[childs];
214 cell->name = "twl4030-vibra"; 245 cell->name = "twl4030-vibra";
215 cell->platform_data = pdata->vibra; 246 if (pdata) {
216 cell->pdata_size = sizeof(*pdata->vibra); 247 cell->platform_data = pdata->vibra;
248 cell->pdata_size = sizeof(*pdata->vibra);
249 }
217 childs++; 250 childs++;
218 } 251 }
219 252
@@ -245,10 +278,17 @@ static int __devexit twl4030_audio_remove(struct platform_device *pdev)
245 return 0; 278 return 0;
246} 279}
247 280
281static const struct of_device_id twl4030_audio_of_match[] = {
282 {.compatible = "ti,twl4030-audio", },
283 { },
284};
285MODULE_DEVICE_TABLE(of, twl4030_audio_of_match);
286
248static struct platform_driver twl4030_audio_driver = { 287static struct platform_driver twl4030_audio_driver = {
249 .driver = { 288 .driver = {
250 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
251 .name = "twl4030-audio", 290 .name = "twl4030-audio",
291 .of_match_table = twl4030_audio_of_match,
252 }, 292 },
253 .probe = twl4030_audio_probe, 293 .probe = twl4030_audio_probe,
254 .remove = __devexit_p(twl4030_audio_remove), 294 .remove = __devexit_p(twl4030_audio_remove),