aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-twl4030.c
diff options
context:
space:
mode:
authorBenoit Cousson <b-cousson@ti.com>2012-02-29 16:51:32 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-03-22 08:05:55 -0400
commitb8589e2a8065b8e7773742b60ae96b63b757bb69 (patch)
treead20ba6cc9205cbaf0e99c444cfca22e1e44db17 /drivers/gpio/gpio-twl4030.c
parent2d9dd99b4470a2ef05509435465e055f50456330 (diff)
gpio/twl: Add DT support to gpio-twl4030 driver
Add the DT support for the I2C GPIO expander inside the twl4030. Note: The pdata parameters still have to be properly adapted using dedicated bindings. Signed-off-by: Benoit Cousson <b-cousson@ti.com> Acked-by: Felipe Balbi <balbi@ti.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/gpio/gpio-twl4030.c')
-rw-r--r--drivers/gpio/gpio-twl4030.c79
1 files changed, 50 insertions, 29 deletions
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 49e5c6eb403a..94256fe7bf36 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -32,6 +32,8 @@
32#include <linux/irq.h> 32#include <linux/irq.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/of.h>
36#include <linux/irqdomain.h>
35 37
36#include <linux/i2c/twl.h> 38#include <linux/i2c/twl.h>
37 39
@@ -256,7 +258,8 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
256 * and vMMC2 power supplies based on card presence. 258 * and vMMC2 power supplies based on card presence.
257 */ 259 */
258 pdata = chip->dev->platform_data; 260 pdata = chip->dev->platform_data;
259 value |= pdata->mmc_cd & 0x03; 261 if (pdata)
262 value |= pdata->mmc_cd & 0x03;
260 263
261 status = gpio_twl4030_write(REG_GPIO_CTRL, value); 264 status = gpio_twl4030_write(REG_GPIO_CTRL, value);
262 } 265 }
@@ -395,6 +398,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
395static int __devinit gpio_twl4030_probe(struct platform_device *pdev) 398static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
396{ 399{
397 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; 400 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
401 struct device_node *node = pdev->dev.of_node;
398 int ret, irq_base; 402 int ret, irq_base;
399 403
400 /* maybe setup IRQs */ 404 /* maybe setup IRQs */
@@ -409,6 +413,9 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
409 return irq_base; 413 return irq_base;
410 } 414 }
411 415
416 irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
417 &irq_domain_simple_ops, NULL);
418
412 ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base); 419 ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
413 if (ret < 0) 420 if (ret < 0)
414 return ret; 421 return ret;
@@ -416,40 +423,45 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
416 twl4030_gpio_irq_base = irq_base; 423 twl4030_gpio_irq_base = irq_base;
417 424
418no_irqs: 425no_irqs:
419 /* 426 twl_gpiochip.base = -1;
420 * NOTE: boards may waste power if they don't set pullups
421 * and pulldowns correctly ... default for non-ULPI pins is
422 * pulldown, and some other pins may have external pullups
423 * or pulldowns. Careful!
424 */
425 ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
426 if (ret)
427 dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
428 pdata->pullups, pdata->pulldowns,
429 ret);
430
431 ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
432 if (ret)
433 dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
434 pdata->debounce, pdata->mmc_cd,
435 ret);
436
437 twl_gpiochip.base = pdata->gpio_base;
438 twl_gpiochip.ngpio = TWL4030_GPIO_MAX; 427 twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
439 twl_gpiochip.dev = &pdev->dev; 428 twl_gpiochip.dev = &pdev->dev;
440 429
441 /* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE, 430 if (pdata) {
442 * is (still) clear if use_leds is set. 431 twl_gpiochip.base = pdata->gpio_base;
443 */ 432
444 if (pdata->use_leds) 433 /*
445 twl_gpiochip.ngpio += 2; 434 * NOTE: boards may waste power if they don't set pullups
435 * and pulldowns correctly ... default for non-ULPI pins is
436 * pulldown, and some other pins may have external pullups
437 * or pulldowns. Careful!
438 */
439 ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
440 if (ret)
441 dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
442 pdata->pullups, pdata->pulldowns,
443 ret);
444
445 ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
446 if (ret)
447 dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
448 pdata->debounce, pdata->mmc_cd,
449 ret);
450
451 /*
452 * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
453 * is (still) clear if use_leds is set.
454 */
455 if (pdata->use_leds)
456 twl_gpiochip.ngpio += 2;
457 }
446 458
447 ret = gpiochip_add(&twl_gpiochip); 459 ret = gpiochip_add(&twl_gpiochip);
448 if (ret < 0) { 460 if (ret < 0) {
449 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); 461 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
450 twl_gpiochip.ngpio = 0; 462 twl_gpiochip.ngpio = 0;
451 gpio_twl4030_remove(pdev); 463 gpio_twl4030_remove(pdev);
452 } else if (pdata->setup) { 464 } else if (pdata && pdata->setup) {
453 int status; 465 int status;
454 466
455 status = pdata->setup(&pdev->dev, 467 status = pdata->setup(&pdev->dev,
@@ -467,7 +479,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
467 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; 479 struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
468 int status; 480 int status;
469 481
470 if (pdata->teardown) { 482 if (pdata && pdata->teardown) {
471 status = pdata->teardown(&pdev->dev, 483 status = pdata->teardown(&pdev->dev,
472 pdata->gpio_base, TWL4030_GPIO_MAX); 484 pdata->gpio_base, TWL4030_GPIO_MAX);
473 if (status) { 485 if (status) {
@@ -488,12 +500,21 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
488 return -EIO; 500 return -EIO;
489} 501}
490 502
503static const struct of_device_id twl_gpio_match[] = {
504 { .compatible = "ti,twl4030-gpio", },
505 { },
506};
507MODULE_DEVICE_TABLE(of, twl_gpio_match);
508
491/* Note: this hardware lives inside an I2C-based multi-function device. */ 509/* Note: this hardware lives inside an I2C-based multi-function device. */
492MODULE_ALIAS("platform:twl4030_gpio"); 510MODULE_ALIAS("platform:twl4030_gpio");
493 511
494static struct platform_driver gpio_twl4030_driver = { 512static struct platform_driver gpio_twl4030_driver = {
495 .driver.name = "twl4030_gpio", 513 .driver = {
496 .driver.owner = THIS_MODULE, 514 .name = "twl4030_gpio",
515 .owner = THIS_MODULE,
516 .of_match_table = of_match_ptr(twl_gpio_match),
517 },
497 .probe = gpio_twl4030_probe, 518 .probe = gpio_twl4030_probe,
498 .remove = gpio_twl4030_remove, 519 .remove = gpio_twl4030_remove,
499}; 520};