Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8589e2a authored by Benoit Cousson's avatar Benoit Cousson Committed by Samuel Ortiz
Browse files

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: default avatarBenoit Cousson <b-cousson@ti.com>
Acked-by: default avatarFelipe Balbi <balbi@ti.com>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 2d9dd99b
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
twl4030 GPIO controller bindings

Required properties:
- compatible:
  - "ti,twl4030-gpio" for twl4030 GPIO controller
- #gpio-cells : Should be two.
  - first cell is the pin number
  - second cell is used to specify optional parameters (unused)
- gpio-controller : Marks the device node as a GPIO controller.
- #interrupt-cells : Should be 2.
- interrupt-controller: Mark the device node as an interrupt controller
  The first cell is the GPIO number.
  The second cell is not used.

Example:

twl_gpio: gpio {
    compatible = "ti,twl4030-gpio";
    #gpio-cells = <2>;
    gpio-controller;
    #interrupt-cells = <2>;
    interrupt-controller;
};
+50 −29
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/irqdomain.h>

#include <linux/i2c/twl.h>

@@ -256,6 +258,7 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
		 * and vMMC2 power supplies based on card presence.
		 */
		pdata = chip->dev->platform_data;
		if (pdata)
			value |= pdata->mmc_cd & 0x03;

		status = gpio_twl4030_write(REG_GPIO_CTRL, value);
@@ -395,6 +398,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev);
static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
{
	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
	struct device_node *node = pdev->dev.of_node;
	int ret, irq_base;

	/* maybe setup IRQs */
@@ -409,6 +413,9 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
		return irq_base;
	}

	irq_domain_add_legacy(node, TWL4030_GPIO_MAX, irq_base, 0,
			      &irq_domain_simple_ops, NULL);

	ret = twl4030_sih_setup(&pdev->dev, TWL4030_MODULE_GPIO, irq_base);
	if (ret < 0)
		return ret;
@@ -416,6 +423,13 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
	twl4030_gpio_irq_base = irq_base;

no_irqs:
	twl_gpiochip.base = -1;
	twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
	twl_gpiochip.dev = &pdev->dev;

	if (pdata) {
		twl_gpiochip.base = pdata->gpio_base;

		/*
		 * NOTE:  boards may waste power if they don't set pullups
		 * and pulldowns correctly ... default for non-ULPI pins is
@@ -434,22 +448,20 @@ no_irqs:
					pdata->debounce, pdata->mmc_cd,
					ret);

	twl_gpiochip.base = pdata->gpio_base;
	twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
	twl_gpiochip.dev = &pdev->dev;

	/* NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
		/*
		 * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE,
		 * is (still) clear if use_leds is set.
		 */
		if (pdata->use_leds)
			twl_gpiochip.ngpio += 2;
	}

	ret = gpiochip_add(&twl_gpiochip);
	if (ret < 0) {
		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
		twl_gpiochip.ngpio = 0;
		gpio_twl4030_remove(pdev);
	} else if (pdata->setup) {
	} else if (pdata && pdata->setup) {
		int status;

		status = pdata->setup(&pdev->dev,
@@ -467,7 +479,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
	struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data;
	int status;

	if (pdata->teardown) {
	if (pdata && pdata->teardown) {
		status = pdata->teardown(&pdev->dev,
				pdata->gpio_base, TWL4030_GPIO_MAX);
		if (status) {
@@ -488,12 +500,21 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
	return -EIO;
}

static const struct of_device_id twl_gpio_match[] = {
	{ .compatible = "ti,twl4030-gpio", },
	{ },
};
MODULE_DEVICE_TABLE(of, twl_gpio_match);

/* Note:  this hardware lives inside an I2C-based multi-function device. */
MODULE_ALIAS("platform:twl4030_gpio");

static struct platform_driver gpio_twl4030_driver = {
	.driver.name	= "twl4030_gpio",
	.driver.owner	= THIS_MODULE,
	.driver = {
		.name	= "twl4030_gpio",
		.owner	= THIS_MODULE,
		.of_match_table = of_match_ptr(twl_gpio_match),
	},
	.probe		= gpio_twl4030_probe,
	.remove		= gpio_twl4030_remove,
};