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

Configure Feed

Select the types of activity you want to include in your feed.

at v3.6 158 lines 4.4 kB view raw
1/* 2 * TI TPS6586x GPIO driver 3 * 4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 5 * Author: Laxman dewangan <ldewangan@nvidia.com> 6 * 7 * Based on tps6586x.c 8 * Copyright (c) 2010 CompuLab Ltd. 9 * Mike Rapoport <mike@compulab.co.il> 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms and conditions of the GNU General Public License, 13 * version 2, as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24#include <linux/errno.h> 25#include <linux/gpio.h> 26#include <linux/kernel.h> 27#include <linux/module.h> 28#include <linux/mfd/tps6586x.h> 29#include <linux/of_device.h> 30#include <linux/platform_device.h> 31 32/* GPIO control registers */ 33#define TPS6586X_GPIOSET1 0x5d 34#define TPS6586X_GPIOSET2 0x5e 35 36struct tps6586x_gpio { 37 struct gpio_chip gpio_chip; 38 struct device *parent; 39}; 40 41static inline struct tps6586x_gpio *to_tps6586x_gpio(struct gpio_chip *chip) 42{ 43 return container_of(chip, struct tps6586x_gpio, gpio_chip); 44} 45 46static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) 47{ 48 struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); 49 uint8_t val; 50 int ret; 51 52 ret = tps6586x_read(tps6586x_gpio->parent, TPS6586X_GPIOSET2, &val); 53 if (ret) 54 return ret; 55 56 return !!(val & (1 << offset)); 57} 58 59static void tps6586x_gpio_set(struct gpio_chip *gc, unsigned offset, 60 int value) 61{ 62 struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); 63 64 tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET2, 65 value << offset, 1 << offset); 66} 67 68static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, 69 int value) 70{ 71 struct tps6586x_gpio *tps6586x_gpio = to_tps6586x_gpio(gc); 72 uint8_t val, mask; 73 74 tps6586x_gpio_set(gc, offset, value); 75 76 val = 0x1 << (offset * 2); 77 mask = 0x3 << (offset * 2); 78 79 return tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET1, 80 val, mask); 81} 82 83static int __devinit tps6586x_gpio_probe(struct platform_device *pdev) 84{ 85 struct tps6586x_platform_data *pdata; 86 struct tps6586x_gpio *tps6586x_gpio; 87 int ret; 88 89 pdata = dev_get_platdata(pdev->dev.parent); 90 tps6586x_gpio = devm_kzalloc(&pdev->dev, 91 sizeof(*tps6586x_gpio), GFP_KERNEL); 92 if (!tps6586x_gpio) { 93 dev_err(&pdev->dev, "Could not allocate tps6586x_gpio\n"); 94 return -ENOMEM; 95 } 96 97 tps6586x_gpio->parent = pdev->dev.parent; 98 99 tps6586x_gpio->gpio_chip.owner = THIS_MODULE; 100 tps6586x_gpio->gpio_chip.label = pdev->name; 101 tps6586x_gpio->gpio_chip.dev = &pdev->dev; 102 tps6586x_gpio->gpio_chip.ngpio = 4; 103 tps6586x_gpio->gpio_chip.can_sleep = 1; 104 105 /* FIXME: add handling of GPIOs as dedicated inputs */ 106 tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output; 107 tps6586x_gpio->gpio_chip.set = tps6586x_gpio_set; 108 tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; 109 110#ifdef CONFIG_OF_GPIO 111 tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; 112#endif 113 if (pdata && pdata->gpio_base) 114 tps6586x_gpio->gpio_chip.base = pdata->gpio_base; 115 else 116 tps6586x_gpio->gpio_chip.base = -1; 117 118 ret = gpiochip_add(&tps6586x_gpio->gpio_chip); 119 if (ret < 0) { 120 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 121 return ret; 122 } 123 124 platform_set_drvdata(pdev, tps6586x_gpio); 125 126 return ret; 127} 128 129static int __devexit tps6586x_gpio_remove(struct platform_device *pdev) 130{ 131 struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev); 132 133 return gpiochip_remove(&tps6586x_gpio->gpio_chip); 134} 135 136static struct platform_driver tps6586x_gpio_driver = { 137 .driver.name = "tps6586x-gpio", 138 .driver.owner = THIS_MODULE, 139 .probe = tps6586x_gpio_probe, 140 .remove = __devexit_p(tps6586x_gpio_remove), 141}; 142 143static int __init tps6586x_gpio_init(void) 144{ 145 return platform_driver_register(&tps6586x_gpio_driver); 146} 147subsys_initcall(tps6586x_gpio_init); 148 149static void __exit tps6586x_gpio_exit(void) 150{ 151 platform_driver_unregister(&tps6586x_gpio_driver); 152} 153module_exit(tps6586x_gpio_exit); 154 155MODULE_ALIAS("platform:tps6586x-gpio"); 156MODULE_DESCRIPTION("GPIO interface for TPS6586X PMIC"); 157MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); 158MODULE_LICENSE("GPL");