mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-19 16:14:13 +08:00
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>
This commit is contained in:
parent
2d9dd99b44
commit
b8589e2a80
23
Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
Normal file
23
Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
Normal file
@ -0,0 +1,23 @@
|
||||
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;
|
||||
};
|
@ -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,7 +258,8 @@ static int twl_request(struct gpio_chip *chip, unsigned offset)
|
||||
* and vMMC2 power supplies based on card presence.
|
||||
*/
|
||||
pdata = chip->dev->platform_data;
|
||||
value |= pdata->mmc_cd & 0x03;
|
||||
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,40 +423,45 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
|
||||
twl4030_gpio_irq_base = irq_base;
|
||||
|
||||
no_irqs:
|
||||
/*
|
||||
* NOTE: boards may waste power if they don't set pullups
|
||||
* and pulldowns correctly ... default for non-ULPI pins is
|
||||
* pulldown, and some other pins may have external pullups
|
||||
* or pulldowns. Careful!
|
||||
*/
|
||||
ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
|
||||
if (ret)
|
||||
dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
|
||||
pdata->pullups, pdata->pulldowns,
|
||||
ret);
|
||||
|
||||
ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
|
||||
if (ret)
|
||||
dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
|
||||
pdata->debounce, pdata->mmc_cd,
|
||||
ret);
|
||||
|
||||
twl_gpiochip.base = pdata->gpio_base;
|
||||
twl_gpiochip.base = -1;
|
||||
twl_gpiochip.ngpio = TWL4030_GPIO_MAX;
|
||||
twl_gpiochip.dev = &pdev->dev;
|
||||
|
||||
/* 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;
|
||||
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
|
||||
* pulldown, and some other pins may have external pullups
|
||||
* or pulldowns. Careful!
|
||||
*/
|
||||
ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns);
|
||||
if (ret)
|
||||
dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n",
|
||||
pdata->pullups, pdata->pulldowns,
|
||||
ret);
|
||||
|
||||
ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd);
|
||||
if (ret)
|
||||
dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n",
|
||||
pdata->debounce, pdata->mmc_cd,
|
||||
ret);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user