diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2012-05-16 13:11:58 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-05-20 17:27:12 +0200 |
commit | 37e13cecaa141eccce705843f5d2f7509e29bd3a (patch) | |
tree | 6f0b138f14c86ac5851b97fc3acd59c7a736ca5e /drivers | |
parent | mfd: Register the twl6040 child for the ASoC codec unconditionally (diff) | |
download | linux-37e13cecaa141eccce705843f5d2f7509e29bd3a.tar.xz linux-37e13cecaa141eccce705843f5d2f7509e29bd3a.zip |
mfd: Add support for Device Tree to twl6040
Device tree based probing support for the core twl6040 driver. Child
devices will be created as MFD devices:
- ASoC codec is always created
- Vibra child is only created if the vibra section present in the DT blob.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mfd/twl6040-core.c | 27 | ||||
-rw-r--r-- | drivers/mfd/twl6040-irq.c | 6 |
2 files changed, 25 insertions, 8 deletions
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index 9765dc2b0ca3..450a28fe8fc2 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c @@ -29,6 +29,10 @@ #include <linux/kernel.h> #include <linux/err.h> #include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_gpio.h> +#include <linux/of_platform.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/i2c.h> @@ -505,11 +509,12 @@ static int __devinit twl6040_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct twl6040_platform_data *pdata = client->dev.platform_data; + struct device_node *node = client->dev.of_node; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int irq, ret, children = 0; - if (!pdata) { + if (!pdata && !node) { dev_err(&client->dev, "Platform data is missing\n"); return -EINVAL; } @@ -560,9 +565,13 @@ static int __devinit twl6040_probe(struct i2c_client *client, twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); /* ERRATA: Automatic power-up is not possible in ES1.0 */ - if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) - twl6040->audpwron = pdata->audpwron_gpio; - else + if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) { + if (pdata) + twl6040->audpwron = pdata->audpwron_gpio; + else + twl6040->audpwron = of_get_named_gpio(node, + "ti,audpwron-gpio", 0); + } else twl6040->audpwron = -EINVAL; if (gpio_is_valid(twl6040->audpwron)) { @@ -602,13 +611,13 @@ static int __devinit twl6040_probe(struct i2c_client *client, twl6040_codec_rsrc[0].end = irq; cell->resources = twl6040_codec_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); - if (pdata->codec) { + if (pdata && pdata->codec) { cell->platform_data = pdata->codec; cell->pdata_size = sizeof(*pdata->codec); } children++; - if (pdata->vibra) { + if ((pdata && pdata->vibra) || of_find_node_by_name(node, "vibra")) { irq = twl6040->irq_base + TWL6040_IRQ_VIB; cell = &twl6040->cells[children]; @@ -618,8 +627,10 @@ static int __devinit twl6040_probe(struct i2c_client *client, cell->resources = twl6040_vibra_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); - cell->platform_data = pdata->vibra; - cell->pdata_size = sizeof(*pdata->vibra); + if (pdata && pdata->vibra) { + cell->platform_data = pdata->vibra; + cell->pdata_size = sizeof(*pdata->vibra); + } children++; } diff --git a/drivers/mfd/twl6040-irq.c b/drivers/mfd/twl6040-irq.c index 914978e1b62e..4b42543da228 100644 --- a/drivers/mfd/twl6040-irq.c +++ b/drivers/mfd/twl6040-irq.c @@ -25,6 +25,8 @@ #include <linux/module.h> #include <linux/err.h> #include <linux/irq.h> +#include <linux/of.h> +#include <linux/irqdomain.h> #include <linux/interrupt.h> #include <linux/mfd/core.h> #include <linux/mfd/twl6040.h> @@ -139,6 +141,7 @@ static irqreturn_t twl6040_irq_thread(int irq, void *data) int twl6040_irq_init(struct twl6040 *twl6040) { + struct device_node *node = twl6040->dev->of_node; int i, nr_irqs, irq_base, ret; u8 val; @@ -158,6 +161,9 @@ int twl6040_irq_init(struct twl6040 *twl6040) } twl6040->irq_base = irq_base; + irq_domain_add_legacy(node, ARRAY_SIZE(twl6040_irqs), irq_base, 0, + &irq_domain_simple_ops, NULL); + /* Register them with genirq */ for (i = irq_base; i < irq_base + nr_irqs; i++) { irq_set_chip_data(i, twl6040); |