aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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),