diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 21:41:17 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 21:41:17 +0200 |
commit | 3e701cdfe601306817604ca7f79f1d1c1088007c (patch) | |
tree | 1b0a4088a091f035d8be06758a604ca449223fc0 /drivers/gpio | |
parent | Merge branch 'linux-next' of git://cavan.codon.org.uk/platform-drivers-x86 (diff) | |
parent | mfd: Ensure AB8500 platform data is passed through db8500-prcmu to MFD Core (diff) | |
download | linux-3e701cdfe601306817604ca7f79f1d1c1088007c.tar.xz linux-3e701cdfe601306817604ca7f79f1d1c1088007c.zip |
Merge tag 'mfd-3.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFD bits from Samuel Ortiz:
"We have support for a few new drivers:
- Samsung s2mps11
- Wolfson Microelectronics wm5102 and wm5110
- Marvell 88PM800 and 88PM805
- TI twl6041
We also have our regular driver improvements:
- Device tree and IRQ domain support for STE AB8500
- Regmap and devm_* API conversion for TI tps6586x
- Device tree support for Samsung max77686
- devm_* API conversion for STE AB3100
Besides that, quite a lot of fixing and cleanup for mc13xxx, tps65910,
tps65090, da9052 and twl-core."
Fix up mostly trivial conflicts, with the exception of
drivers/usb/host/ehci-omap.c in particular, which had some
re-organization of the reset sequence (commit 1a49e2ac9651: "EHCI:
centralize controller initialization") that clashed with commit
2761a6394516 ("mfd: USB: Fix the omap-usb EHCI ULPI PHY reset fix
issues").
In particular, commit 2761a6394516 moved the usb_add_hcd() to the
*middle* of the reset sequence, which clashes fairly badly with the
reset sequence re-organization (although it could have been done inside
the new omap_ehci_init() function).
I left that part of commit 2761a6394516 just undone.
* tag 'mfd-3.6-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (110 commits)
mfd: Ensure AB8500 platform data is passed through db8500-prcmu to MFD Core
mfd: Arizone core should select MFD_CORE
mfd: Fix arizona-irq.c build by selecting REGMAP_IRQ
mfd: Add debug trace on entering and leaving arizone runtime suspend
mfd: Correct tps65090 cell names
mfd: Remove gpio support from tps6586x core driver
ARM: tegra: defconfig: Enable tps6586x gpio
gpio: tps6586x: Add gpio support through platform driver
mfd: Cache tps6586x register through regmap
mfd: Use regmap for tps6586x register access.
mfd: Use devm managed resources for tps6586x
input: Add onkey support for 88PM80X PMIC
mfd: Add support for twl6041
mfd: Fix twl6040 revision information
mfd: Matches should be NULL when populate anatop child devices
input: ab8500-ponkey: Create AB8500 domain IRQ mapping
mfd: Add missing out of memory check for pcf50633
Documentation: Describe the AB8500 Device Tree bindings
mfd: Add tps65910 32-kHz-crystal-input init
mfd: Drop modifying mc13xxx driver's id_table in probe
...
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 7 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-tps6586x.c | 158 |
3 files changed, 166 insertions, 0 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 502b5ea43f4f..b16c8a72a2e2 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -597,6 +597,13 @@ config GPIO_AB8500 help Select this to enable the AB8500 IC GPIO driver +config GPIO_TPS6586X + bool "TPS6586X GPIO" + depends on MFD_TPS6586X + help + Select this option to enable GPIO driver for the TPS6586X + chip family. + config GPIO_TPS65910 bool "TPS65910 GPIO" depends on MFD_TPS65910 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index d37048105a87..153caceeb053 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o +obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c new file mode 100644 index 000000000000..2526b3bb0fae --- /dev/null +++ b/drivers/gpio/gpio-tps6586x.c @@ -0,0 +1,158 @@ +/* + * TI TPS6586x GPIO driver + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * Author: Laxman dewangan <ldewangan@nvidia.com> + * + * Based on tps6586x.c + * Copyright (c) 2010 CompuLab Ltd. + * Mike Rapoport <mike@compulab.co.il> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/errno.h> +#include <linux/gpio.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/mfd/tps6586x.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> + +/* GPIO control registers */ +#define TPS6586X_GPIOSET1 0x5d +#define TPS6586X_GPIOSET2 0x5e + +struct tps6586x_gpio { + struct gpio_chip gpio_chip; + struct device *parent; +}; + +static inline struct tps6586x_gpio *to_tps6586x_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct tps6586x_gpio, gpio_chip); +} + +static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); + uint8_t val; + int ret; + + ret = tps6586x_read(tps6586x_gpio->parent, TPS6586X_GPIOSET2, &val); + if (ret) + return ret; + + return !!(val & (1 << offset)); +} + +static void tps6586x_gpio_set(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); + + tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET2, + value << offset, 1 << offset); +} + +static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); + uint8_t val, mask; + + tps6586x_gpio_set(gc, offset, value); + + val = 0x1 << (offset * 2); + mask = 0x3 << (offset * 2); + + return tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET1, + val, mask); +} + +static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) +{ + struct tps6586x_platform_data *pdata; + struct tps6586x_gpio *tps6586x_gpio; + int ret; + + pdata = dev_get_platdata(pdev->dev.parent); + tps6586x_gpio = devm_kzalloc(&pdev->dev, + sizeof(*tps6586x_gpio), GFP_KERNEL); + if (!tps6586x_gpio) { + dev_err(&pdev->dev, "Could not allocate tps6586x_gpio\n"); + return -ENOMEM; + } + + tps6586x_gpio->parent = pdev->dev.parent; + + tps6586x_gpio->gpio_chip.owner = THIS_MODULE; + tps6586x_gpio->gpio_chip.label = pdev->name; + tps6586x_gpio->gpio_chip.dev = &pdev->dev; + tps6586x_gpio->gpio_chip.ngpio = 4; + tps6586x_gpio->gpio_chip.can_sleep = 1; + + /* FIXME: add handling of GPIOs as dedicated inputs */ + tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output; + tps6586x_gpio->gpio_chip.set = tps6586x_gpio_set; + tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; + +#ifdef CONFIG_OF_GPIO + tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; +#endif + if (pdata && pdata->gpio_base) + tps6586x_gpio->gpio_chip.base = pdata->gpio_base; + else + tps6586x_gpio->gpio_chip.base = -1; + + ret = gpiochip_add(&tps6586x_gpio->gpio_chip); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, tps6586x_gpio); + + return ret; +} + +static int __devexit tps6586x_gpio_remove(struct platform_device *pdev) +{ + struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); + + return gpiochip_remove(&tps6586x_gpio->gpio_chip); +} + +static struct platform_driver tps6586x_gpio_driver = { + .driver.name = "tps6586x-gpio", + .driver.owner = THIS_MODULE, + .probe = tps6586x_gpio_probe, + .remove = __devexit_p(tps6586x_gpio_remove), +}; + +static int __init tps6586x_gpio_init(void) +{ + return platform_driver_register(&tps6586x_gpio_driver); +} +subsys_initcall(tps6586x_gpio_init); + +static void __exit tps6586x_gpio_exit(void) +{ + platform_driver_unregister(&tps6586x_gpio_driver); +} +module_exit(tps6586x_gpio_exit); + +MODULE_ALIAS("platform:tps6586x-gpio"); +MODULE_DESCRIPTION("GPIO interface for TPS6586X PMIC"); +MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); +MODULE_LICENSE("GPL"); |