1 /* 2 * TI Palma series PMIC's GPIO driver. 3 * 4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 5 * 6 * Author: Laxman Dewangan <ldewangan@nvidia.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include <linux/gpio.h> 22 #include <linux/kernel.h> 23 #include <linux/init.h> 24 #include <linux/mfd/palmas.h> 25 #include <linux/of.h> 26 #include <linux/of_device.h> 27 #include <linux/platform_device.h> 28 29 struct palmas_gpio { 30 struct gpio_chip gpio_chip; 31 struct palmas *palmas; 32 }; 33 34 struct palmas_device_data { 35 int ngpio; 36 }; 37 38 static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset) 39 { 40 struct palmas_gpio *pg = gpiochip_get_data(gc); 41 struct palmas *palmas = pg->palmas; 42 unsigned int val; 43 int ret; 44 unsigned int reg; 45 int gpio16 = (offset/8); 46 47 offset %= 8; 48 reg = (gpio16) ? PALMAS_GPIO_DATA_DIR2 : PALMAS_GPIO_DATA_DIR; 49 50 ret = palmas_read(palmas, PALMAS_GPIO_BASE, reg, &val); 51 if (ret < 0) { 52 dev_err(gc->parent, "Reg 0x%02x read failed, %d\n", reg, ret); 53 return ret; 54 } 55 56 if (val & BIT(offset)) 57 reg = (gpio16) ? PALMAS_GPIO_DATA_OUT2 : PALMAS_GPIO_DATA_OUT; 58 else 59 reg = (gpio16) ? PALMAS_GPIO_DATA_IN2 : PALMAS_GPIO_DATA_IN; 60 61 ret = palmas_read(palmas, PALMAS_GPIO_BASE, reg, &val); 62 if (ret < 0) { 63 dev_err(gc->parent, "Reg 0x%02x read failed, %d\n", reg, ret); 64 return ret; 65 } 66 return !!(val & BIT(offset)); 67 } 68 69 static void palmas_gpio_set(struct gpio_chip *gc, unsigned offset, 70 int value) 71 { 72 struct palmas_gpio *pg = gpiochip_get_data(gc); 73 struct palmas *palmas = pg->palmas; 74 int ret; 75 unsigned int reg; 76 int gpio16 = (offset/8); 77 78 offset %= 8; 79 if (gpio16) 80 reg = (value) ? 81 PALMAS_GPIO_SET_DATA_OUT2 : PALMAS_GPIO_CLEAR_DATA_OUT2; 82 else 83 reg = (value) ? 84 PALMAS_GPIO_SET_DATA_OUT : PALMAS_GPIO_CLEAR_DATA_OUT; 85 86 ret = palmas_write(palmas, PALMAS_GPIO_BASE, reg, BIT(offset)); 87 if (ret < 0) 88 dev_err(gc->parent, "Reg 0x%02x write failed, %d\n", reg, ret); 89 } 90 91 static int palmas_gpio_output(struct gpio_chip *gc, unsigned offset, 92 int value) 93 { 94 struct palmas_gpio *pg = gpiochip_get_data(gc); 95 struct palmas *palmas = pg->palmas; 96 int ret; 97 unsigned int reg; 98 int gpio16 = (offset/8); 99 100 offset %= 8; 101 reg = (gpio16) ? PALMAS_GPIO_DATA_DIR2 : PALMAS_GPIO_DATA_DIR; 102 103 /* Set the initial value */ 104 palmas_gpio_set(gc, offset, value); 105 106 ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE, reg, 107 BIT(offset), BIT(offset)); 108 if (ret < 0) 109 dev_err(gc->parent, "Reg 0x%02x update failed, %d\n", reg, 110 ret); 111 return ret; 112 } 113 114 static int palmas_gpio_input(struct gpio_chip *gc, unsigned offset) 115 { 116 struct palmas_gpio *pg = gpiochip_get_data(gc); 117 struct palmas *palmas = pg->palmas; 118 int ret; 119 unsigned int reg; 120 int gpio16 = (offset/8); 121 122 offset %= 8; 123 reg = (gpio16) ? PALMAS_GPIO_DATA_DIR2 : PALMAS_GPIO_DATA_DIR; 124 125 ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE, reg, BIT(offset), 0); 126 if (ret < 0) 127 dev_err(gc->parent, "Reg 0x%02x update failed, %d\n", reg, 128 ret); 129 return ret; 130 } 131 132 static int palmas_gpio_to_irq(struct gpio_chip *gc, unsigned offset) 133 { 134 struct palmas_gpio *pg = gpiochip_get_data(gc); 135 struct palmas *palmas = pg->palmas; 136 137 return palmas_irq_get_virq(palmas, PALMAS_GPIO_0_IRQ + offset); 138 } 139 140 static const struct palmas_device_data palmas_dev_data = { 141 .ngpio = 8, 142 }; 143 144 static const struct palmas_device_data tps80036_dev_data = { 145 .ngpio = 16, 146 }; 147 148 static const struct of_device_id of_palmas_gpio_match[] = { 149 { .compatible = "ti,palmas-gpio", .data = &palmas_dev_data,}, 150 { .compatible = "ti,tps65913-gpio", .data = &palmas_dev_data,}, 151 { .compatible = "ti,tps65914-gpio", .data = &palmas_dev_data,}, 152 { .compatible = "ti,tps80036-gpio", .data = &tps80036_dev_data,}, 153 { }, 154 }; 155 MODULE_DEVICE_TABLE(of, of_palmas_gpio_match); 156 157 static int palmas_gpio_probe(struct platform_device *pdev) 158 { 159 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); 160 struct palmas_platform_data *palmas_pdata; 161 struct palmas_gpio *palmas_gpio; 162 int ret; 163 const struct of_device_id *match; 164 const struct palmas_device_data *dev_data; 165 166 match = of_match_device(of_palmas_gpio_match, &pdev->dev); 167 if (!match) 168 return -ENODEV; 169 dev_data = match->data; 170 if (!dev_data) 171 dev_data = &palmas_dev_data; 172 173 palmas_gpio = devm_kzalloc(&pdev->dev, 174 sizeof(*palmas_gpio), GFP_KERNEL); 175 if (!palmas_gpio) 176 return -ENOMEM; 177 178 palmas_gpio->palmas = palmas; 179 palmas_gpio->gpio_chip.owner = THIS_MODULE; 180 palmas_gpio->gpio_chip.label = dev_name(&pdev->dev); 181 palmas_gpio->gpio_chip.ngpio = dev_data->ngpio; 182 palmas_gpio->gpio_chip.can_sleep = true; 183 palmas_gpio->gpio_chip.direction_input = palmas_gpio_input; 184 palmas_gpio->gpio_chip.direction_output = palmas_gpio_output; 185 palmas_gpio->gpio_chip.to_irq = palmas_gpio_to_irq; 186 palmas_gpio->gpio_chip.set = palmas_gpio_set; 187 palmas_gpio->gpio_chip.get = palmas_gpio_get; 188 palmas_gpio->gpio_chip.parent = &pdev->dev; 189 #ifdef CONFIG_OF_GPIO 190 palmas_gpio->gpio_chip.of_node = pdev->dev.of_node; 191 #endif 192 palmas_pdata = dev_get_platdata(palmas->dev); 193 if (palmas_pdata && palmas_pdata->gpio_base) 194 palmas_gpio->gpio_chip.base = palmas_pdata->gpio_base; 195 else 196 palmas_gpio->gpio_chip.base = -1; 197 198 ret = devm_gpiochip_add_data(&pdev->dev, &palmas_gpio->gpio_chip, 199 palmas_gpio); 200 if (ret < 0) { 201 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 202 return ret; 203 } 204 205 platform_set_drvdata(pdev, palmas_gpio); 206 return ret; 207 } 208 209 static struct platform_driver palmas_gpio_driver = { 210 .driver.name = "palmas-gpio", 211 .driver.of_match_table = of_palmas_gpio_match, 212 .probe = palmas_gpio_probe, 213 }; 214 215 static int __init palmas_gpio_init(void) 216 { 217 return platform_driver_register(&palmas_gpio_driver); 218 } 219 subsys_initcall(palmas_gpio_init); 220