Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Margarita Olaya and committed by
Samuel Ortiz
668a6cc7 d49a0f3f

+164
+6
drivers/gpio/Kconfig
··· 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
+1
drivers/gpio/Makefile
··· 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
+156
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");
+1
include/linux/mfd/tps65912.h
··· 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