|
28 | 28 | #include <linux/kernel.h>
|
29 | 29 | #include <linux/fs.h>
|
30 | 30 | #include <linux/platform_device.h>
|
| 31 | +#include <linux/of.h> |
| 32 | +#include <linux/of_platform.h> |
31 | 33 | #include <linux/i2c/twl.h>
|
32 | 34 | #include <linux/mfd/core.h>
|
33 | 35 | #include <linux/mfd/twl4030-audio.h>
|
@@ -156,15 +158,42 @@ unsigned int twl4030_audio_get_mclk(void)
|
156 | 158 | }
|
157 | 159 | EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
|
158 | 160 |
|
| 161 | +static 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 | + |
| 173 | +static 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 | + |
159 | 187 | static int __devinit twl4030_audio_probe(struct platform_device *pdev)
|
160 | 188 | {
|
161 | 189 | struct twl4030_audio *audio;
|
162 | 190 | struct twl4030_audio_data *pdata = pdev->dev.platform_data;
|
| 191 | + struct device_node *node = pdev->dev.of_node; |
163 | 192 | struct mfd_cell *cell = NULL;
|
164 | 193 | int ret, childs = 0;
|
165 | 194 | u8 val;
|
166 | 195 |
|
167 |
| - if (!pdata) { |
| 196 | + if (!pdata && !node) { |
168 | 197 | dev_err(&pdev->dev, "Platform data is missing\n");
|
169 | 198 | return -EINVAL;
|
170 | 199 | }
|
@@ -202,18 +231,22 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
|
202 | 231 | audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
|
203 | 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 | 235 | cell = &audio->cells[childs];
|
207 | 236 | cell->name = "twl4030-codec";
|
208 |
| - cell->platform_data = pdata->codec; |
209 |
| - cell->pdata_size = sizeof(*pdata->codec); |
| 237 | + if (pdata) { |
| 238 | + cell->platform_data = pdata->codec; |
| 239 | + cell->pdata_size = sizeof(*pdata->codec); |
| 240 | + } |
210 | 241 | childs++;
|
211 | 242 | }
|
212 |
| - if (pdata->vibra) { |
| 243 | + if (twl4030_audio_has_vibra(pdata, node)) { |
213 | 244 | cell = &audio->cells[childs];
|
214 | 245 | cell->name = "twl4030-vibra";
|
215 |
| - cell->platform_data = pdata->vibra; |
216 |
| - cell->pdata_size = sizeof(*pdata->vibra); |
| 246 | + if (pdata) { |
| 247 | + cell->platform_data = pdata->vibra; |
| 248 | + cell->pdata_size = sizeof(*pdata->vibra); |
| 249 | + } |
217 | 250 | childs++;
|
218 | 251 | }
|
219 | 252 |
|
@@ -245,10 +278,17 @@ static int __devexit twl4030_audio_remove(struct platform_device *pdev)
|
245 | 278 | return 0;
|
246 | 279 | }
|
247 | 280 |
|
| 281 | +static const struct of_device_id twl4030_audio_of_match[] = { |
| 282 | + {.compatible = "ti,twl4030-audio", }, |
| 283 | + { }, |
| 284 | +}; |
| 285 | +MODULE_DEVICE_TABLE(of, twl4030_audio_of_match); |
| 286 | + |
248 | 287 | static struct platform_driver twl4030_audio_driver = {
|
249 | 288 | .driver = {
|
250 | 289 | .owner = THIS_MODULE,
|
251 | 290 | .name = "twl4030-audio",
|
| 291 | + .of_match_table = twl4030_audio_of_match, |
252 | 292 | },
|
253 | 293 | .probe = twl4030_audio_probe,
|
254 | 294 | .remove = __devexit_p(twl4030_audio_remove),
|
|
0 commit comments