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/init.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 36 struct tps6586x_gpio { 37 struct gpio_chip gpio_chip; 38 struct device *parent; 39 }; 40 41 static int tps6586x_gpio_get(struct gpio_chip *gc, unsigned offset) 42 { 43 struct tps6586x_gpio *tps6586x_gpio = gpiochip_get_data(gc); 44 uint8_t val; 45 int ret; 46 47 ret = tps6586x_read(tps6586x_gpio->parent, TPS6586X_GPIOSET2, &val); 48 if (ret) 49 return ret; 50 51 return !!(val & (1 << offset)); 52 } 53 54 static void tps6586x_gpio_set(struct gpio_chip *gc, unsigned offset, 55 int value) 56 { 57 struct tps6586x_gpio *tps6586x_gpio = gpiochip_get_data(gc); 58 59 tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET2, 60 value << offset, 1 << offset); 61 } 62 63 static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset, 64 int value) 65 { 66 struct tps6586x_gpio *tps6586x_gpio = gpiochip_get_data(gc); 67 uint8_t val, mask; 68 69 tps6586x_gpio_set(gc, offset, value); 70 71 val = 0x1 << (offset * 2); 72 mask = 0x3 << (offset * 2); 73 74 return tps6586x_update(tps6586x_gpio->parent, TPS6586X_GPIOSET1, 75 val, mask); 76 } 77 78 static int tps6586x_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 79 { 80 struct tps6586x_gpio *tps6586x_gpio = gpiochip_get_data(gc); 81 82 return tps6586x_irq_get_virq(tps6586x_gpio->parent, 83 TPS6586X_INT_PLDO_0 + offset); 84 } 85 86 static int tps6586x_gpio_probe(struct platform_device *pdev) 87 { 88 struct tps6586x_platform_data *pdata; 89 struct tps6586x_gpio *tps6586x_gpio; 90 int ret; 91 92 pdata = dev_get_platdata(pdev->dev.parent); 93 tps6586x_gpio = devm_kzalloc(&pdev->dev, 94 sizeof(*tps6586x_gpio), GFP_KERNEL); 95 if (!tps6586x_gpio) 96 return -ENOMEM; 97 98 tps6586x_gpio->parent = pdev->dev.parent; 99 100 tps6586x_gpio->gpio_chip.owner = THIS_MODULE; 101 tps6586x_gpio->gpio_chip.label = pdev->name; 102 tps6586x_gpio->gpio_chip.parent = &pdev->dev; 103 tps6586x_gpio->gpio_chip.ngpio = 4; 104 tps6586x_gpio->gpio_chip.can_sleep = true; 105 106 /* FIXME: add handling of GPIOs as dedicated inputs */ 107 tps6586x_gpio->gpio_chip.direction_output = tps6586x_gpio_output; 108 tps6586x_gpio->gpio_chip.set = tps6586x_gpio_set; 109 tps6586x_gpio->gpio_chip.get = tps6586x_gpio_get; 110 tps6586x_gpio->gpio_chip.to_irq = tps6586x_gpio_to_irq; 111 112 #ifdef CONFIG_OF_GPIO 113 tps6586x_gpio->gpio_chip.of_node = pdev->dev.parent->of_node; 114 #endif 115 if (pdata && pdata->gpio_base) 116 tps6586x_gpio->gpio_chip.base = pdata->gpio_base; 117 else 118 tps6586x_gpio->gpio_chip.base = -1; 119 120 ret = devm_gpiochip_add_data(&pdev->dev, &tps6586x_gpio->gpio_chip, 121 tps6586x_gpio); 122 if (ret < 0) { 123 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 124 return ret; 125 } 126 127 platform_set_drvdata(pdev, tps6586x_gpio); 128 129 return ret; 130 } 131 132 static struct platform_driver tps6586x_gpio_driver = { 133 .driver.name = "tps6586x-gpio", 134 .probe = tps6586x_gpio_probe, 135 }; 136 137 static int __init tps6586x_gpio_init(void) 138 { 139 return platform_driver_register(&tps6586x_gpio_driver); 140 } 141 subsys_initcall(tps6586x_gpio_init); 142