Commit 668a6cc710ee054af2b059d27bbec746ead0fbca

Authored by Margarita Olaya
Committed by Samuel Ortiz
1 parent d49a0f3f14

tps65912: gpio: add gpio driver

TPS65912 has five GPIOs that can be configured for different
purposes.

Signed-off-by: Margarita Olaya Cabrera <magi@slimlogic.co.uk>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 4 changed files with 164 additions and 0 deletions Side-by-side Diff

drivers/gpio/Kconfig
... ... @@ -280,6 +280,12 @@
280 280 This enables support for the GPIOs found on the TC3589X
281 281 I/O Expander.
282 282  
  283 +config GPIO_TPS65912
  284 + tristate "TI TPS65912 GPIO"
  285 + depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
  286 + help
  287 + This driver supports TPS65912 gpio chip
  288 +
283 289 config GPIO_TWL4030
284 290 tristate "TWL4030, TWL5030, and TPS659x0 GPIOs"
285 291 depends on TWL4030_CORE
drivers/gpio/Makefile
... ... @@ -48,6 +48,7 @@
48 48 obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o
49 49 obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o
50 50 obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
  51 +obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
51 52 obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
52 53 obj-$(CONFIG_MACH_U300) += gpio-u300.o
53 54 obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
drivers/gpio/gpio-tps65912.c
  1 +/*
  2 + * Copyright 2011 Texas Instruments Inc.
  3 + *
  4 + * Author: Margarita Olaya <magi@slimlogic.co.uk>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of the GNU General Public License as published by the
  8 + * Free Software Foundation; either version 2 of the License, or (at your
  9 + * option) any later version.
  10 + *
  11 + * This driver is based on wm8350 implementation.
  12 + */
  13 +
  14 +#include <linux/kernel.h>
  15 +#include <linux/module.h>
  16 +#include <linux/errno.h>
  17 +#include <linux/gpio.h>
  18 +#include <linux/mfd/core.h>
  19 +#include <linux/platform_device.h>
  20 +#include <linux/seq_file.h>
  21 +#include <linux/slab.h>
  22 +#include <linux/mfd/tps65912.h>
  23 +
  24 +struct tps65912_gpio_data {
  25 + struct tps65912 *tps65912;
  26 + struct gpio_chip gpio_chip;
  27 +};
  28 +
  29 +static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset)
  30 +{
  31 + struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio);
  32 + int val;
  33 +
  34 + val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset);
  35 +
  36 + if (val & GPIO_STS_MASK)
  37 + return 1;
  38 +
  39 + return 0;
  40 +}
  41 +
  42 +static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset,
  43 + int value)
  44 +{
  45 + struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio);
  46 +
  47 + if (value)
  48 + tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset,
  49 + GPIO_SET_MASK);
  50 + else
  51 + tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset,
  52 + GPIO_SET_MASK);
  53 +}
  54 +
  55 +static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset,
  56 + int value)
  57 +{
  58 + struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio);
  59 +
  60 + /* Set the initial value */
  61 + tps65912_gpio_set(gc, offset, value);
  62 +
  63 + return tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset,
  64 + GPIO_CFG_MASK);
  65 +}
  66 +
  67 +static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset)
  68 +{
  69 + struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio);
  70 +
  71 + return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset,
  72 + GPIO_CFG_MASK);
  73 +
  74 +}
  75 +
  76 +static struct gpio_chip template_chip = {
  77 + .label = "tps65912",
  78 + .owner = THIS_MODULE,
  79 + .direction_input = tps65912_gpio_input,
  80 + .direction_output = tps65912_gpio_output,
  81 + .get = tps65912_gpio_get,
  82 + .set = tps65912_gpio_set,
  83 + .can_sleep = 1,
  84 + .ngpio = 5,
  85 + .base = -1,
  86 +};
  87 +
  88 +static int __devinit tps65912_gpio_probe(struct platform_device *pdev)
  89 +{
  90 + struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent);
  91 + struct tps65912_board *pdata = tps65912->dev->platform_data;
  92 + struct tps65912_gpio_data *tps65912_gpio;
  93 + int ret;
  94 +
  95 + tps65912_gpio = kzalloc(sizeof(*tps65912_gpio), GFP_KERNEL);
  96 + if (tps65912_gpio == NULL)
  97 + return -ENOMEM;
  98 +
  99 + tps65912_gpio->tps65912 = tps65912;
  100 + tps65912_gpio->gpio_chip = template_chip;
  101 + tps65912_gpio->gpio_chip.dev = &pdev->dev;
  102 + if (pdata && pdata->gpio_base)
  103 + tps65912_gpio->gpio_chip.base = pdata->gpio_base;
  104 +
  105 + ret = gpiochip_add(&tps65912_gpio->gpio_chip);
  106 + if (ret < 0) {
  107 + dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret);
  108 + goto err;
  109 + }
  110 +
  111 + platform_set_drvdata(pdev, tps65912_gpio);
  112 +
  113 + return ret;
  114 +
  115 +err:
  116 + kfree(tps65912_gpio);
  117 + return ret;
  118 +}
  119 +
  120 +static int __devexit tps65912_gpio_remove(struct platform_device *pdev)
  121 +{
  122 + struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev);
  123 + int ret;
  124 +
  125 + ret = gpiochip_remove(&tps65912_gpio->gpio_chip);
  126 + if (ret == 0)
  127 + kfree(tps65912_gpio);
  128 +
  129 + return ret;
  130 +}
  131 +
  132 +static struct platform_driver tps65912_gpio_driver = {
  133 + .driver = {
  134 + .name = "tps65912-gpio",
  135 + .owner = THIS_MODULE,
  136 + },
  137 + .probe = tps65912_gpio_probe,
  138 + .remove = __devexit_p(tps65912_gpio_remove),
  139 +};
  140 +
  141 +static int __init tps65912_gpio_init(void)
  142 +{
  143 + return platform_driver_register(&tps65912_gpio_driver);
  144 +}
  145 +subsys_initcall(tps65912_gpio_init);
  146 +
  147 +static void __exit tps65912_gpio_exit(void)
  148 +{
  149 + platform_driver_unregister(&tps65912_gpio_driver);
  150 +}
  151 +module_exit(tps65912_gpio_exit);
  152 +
  153 +MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>");
  154 +MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs");
  155 +MODULE_LICENSE("GPL v2");
  156 +MODULE_ALIAS("platform:tps65912-gpio");
include/linux/mfd/tps65912.h
... ... @@ -275,6 +275,7 @@
275 275 int is_dcdc4_avs;
276 276 int irq;
277 277 int irq_base;
  278 + int gpio_base;
278 279 struct regulator_init_data *tps65912_pmic_init_data;
279 280 };
280 281