1/* 2 * gpiolib support for Wolfson WM831x PMICs 3 * 4 * Copyright 2009 Wolfson Microelectronics PLC. 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 15#include <linux/kernel.h> 16#include <linux/slab.h> 17#include <linux/module.h> 18#include <linux/gpio.h> 19#include <linux/mfd/core.h> 20#include <linux/platform_device.h> 21#include <linux/seq_file.h> 22 23#include <linux/mfd/wm831x/core.h> 24#include <linux/mfd/wm831x/pdata.h> 25#include <linux/mfd/wm831x/gpio.h> 26#include <linux/mfd/wm831x/irq.h> 27 28struct wm831x_gpio { 29 struct wm831x *wm831x; 30 struct gpio_chip gpio_chip; 31}; 32 33static inline struct wm831x_gpio *to_wm831x_gpio(struct gpio_chip *chip) 34{ 35 return container_of(chip, struct wm831x_gpio, gpio_chip); 36} 37 38static int wm831x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) 39{ 40 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 41 struct wm831x *wm831x = wm831x_gpio->wm831x; 42 int val = WM831X_GPN_DIR; 43 44 if (wm831x->has_gpio_ena) 45 val |= WM831X_GPN_TRI; 46 47 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, 48 WM831X_GPN_DIR | WM831X_GPN_TRI | 49 WM831X_GPN_FN_MASK, val); 50} 51 52static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) 53{ 54 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 55 struct wm831x *wm831x = wm831x_gpio->wm831x; 56 int ret; 57 58 ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); 59 if (ret < 0) 60 return ret; 61 62 if (ret & 1 << offset) 63 return 1; 64 else 65 return 0; 66} 67 68static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 69{ 70 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 71 struct wm831x *wm831x = wm831x_gpio->wm831x; 72 73 wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, 74 value << offset); 75} 76 77static int wm831x_gpio_direction_out(struct gpio_chip *chip, 78 unsigned offset, int value) 79{ 80 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 81 struct wm831x *wm831x = wm831x_gpio->wm831x; 82 int val = 0; 83 int ret; 84 85 if (wm831x->has_gpio_ena) 86 val |= WM831X_GPN_TRI; 87 88 ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, 89 WM831X_GPN_DIR | WM831X_GPN_TRI | 90 WM831X_GPN_FN_MASK, val); 91 if (ret < 0) 92 return ret; 93 94 /* Can only set GPIO state once it's in output mode */ 95 wm831x_gpio_set(chip, offset, value); 96 97 return 0; 98} 99 100static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 101{ 102 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 103 struct wm831x *wm831x = wm831x_gpio->wm831x; 104 105 return irq_create_mapping(wm831x->irq_domain, 106 WM831X_IRQ_GPIO_1 + offset); 107} 108 109static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, 110 unsigned debounce) 111{ 112 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 113 struct wm831x *wm831x = wm831x_gpio->wm831x; 114 int reg = WM831X_GPIO1_CONTROL + offset; 115 int ret, fn; 116 117 ret = wm831x_reg_read(wm831x, reg); 118 if (ret < 0) 119 return ret; 120 121 switch (ret & WM831X_GPN_FN_MASK) { 122 case 0: 123 case 1: 124 break; 125 default: 126 /* Not in GPIO mode */ 127 return -EBUSY; 128 } 129 130 if (debounce >= 32 && debounce <= 64) 131 fn = 0; 132 else if (debounce >= 4000 && debounce <= 8000) 133 fn = 1; 134 else 135 return -EINVAL; 136 137 return wm831x_set_bits(wm831x, reg, WM831X_GPN_FN_MASK, fn); 138} 139 140#ifdef CONFIG_DEBUG_FS 141static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 142{ 143 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 144 struct wm831x *wm831x = wm831x_gpio->wm831x; 145 int i, tristated; 146 147 for (i = 0; i < chip->ngpio; i++) { 148 int gpio = i + chip->base; 149 int reg; 150 const char *label, *pull, *powerdomain; 151 152 /* We report the GPIO even if it's not requested since 153 * we're also reporting things like alternate 154 * functions which apply even when the GPIO is not in 155 * use as a GPIO. 156 */ 157 label = gpiochip_is_requested(chip, i); 158 if (!label) 159 label = "Unrequested"; 160 161 seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label); 162 163 reg = wm831x_reg_read(wm831x, WM831X_GPIO1_CONTROL + i); 164 if (reg < 0) { 165 dev_err(wm831x->dev, 166 "GPIO control %d read failed: %d\n", 167 gpio, reg); 168 seq_printf(s, "\n"); 169 continue; 170 } 171 172 switch (reg & WM831X_GPN_PULL_MASK) { 173 case WM831X_GPIO_PULL_NONE: 174 pull = "nopull"; 175 break; 176 case WM831X_GPIO_PULL_DOWN: 177 pull = "pulldown"; 178 break; 179 case WM831X_GPIO_PULL_UP: 180 pull = "pullup"; 181 break; 182 default: 183 pull = "INVALID PULL"; 184 break; 185 } 186 187 switch (i + 1) { 188 case 1 ... 3: 189 case 7 ... 9: 190 if (reg & WM831X_GPN_PWR_DOM) 191 powerdomain = "VPMIC"; 192 else 193 powerdomain = "DBVDD"; 194 break; 195 196 case 4 ... 6: 197 case 10 ... 12: 198 if (reg & WM831X_GPN_PWR_DOM) 199 powerdomain = "SYSVDD"; 200 else 201 powerdomain = "DBVDD"; 202 break; 203 204 case 13 ... 16: 205 powerdomain = "TPVDD"; 206 break; 207 208 default: 209 BUG(); 210 break; 211 } 212 213 tristated = reg & WM831X_GPN_TRI; 214 if (wm831x->has_gpio_ena) 215 tristated = !tristated; 216 217 seq_printf(s, " %s %s %s %s%s\n" 218 " %s%s (0x%4x)\n", 219 reg & WM831X_GPN_DIR ? "in" : "out", 220 wm831x_gpio_get(chip, i) ? "high" : "low", 221 pull, 222 powerdomain, 223 reg & WM831X_GPN_POL ? "" : " inverted", 224 reg & WM831X_GPN_OD ? "open-drain" : "CMOS", 225 tristated ? " tristated" : "", 226 reg); 227 } 228} 229#else 230#define wm831x_gpio_dbg_show NULL 231#endif 232 233static struct gpio_chip template_chip = { 234 .label = "wm831x", 235 .owner = THIS_MODULE, 236 .direction_input = wm831x_gpio_direction_in, 237 .get = wm831x_gpio_get, 238 .direction_output = wm831x_gpio_direction_out, 239 .set = wm831x_gpio_set, 240 .to_irq = wm831x_gpio_to_irq, 241 .set_debounce = wm831x_gpio_set_debounce, 242 .dbg_show = wm831x_gpio_dbg_show, 243 .can_sleep = true, 244}; 245 246static int wm831x_gpio_probe(struct platform_device *pdev) 247{ 248 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 249 struct wm831x_pdata *pdata = dev_get_platdata(wm831x->dev); 250 struct wm831x_gpio *wm831x_gpio; 251 int ret; 252 253 wm831x_gpio = devm_kzalloc(&pdev->dev, sizeof(*wm831x_gpio), 254 GFP_KERNEL); 255 if (wm831x_gpio == NULL) 256 return -ENOMEM; 257 258 wm831x_gpio->wm831x = wm831x; 259 wm831x_gpio->gpio_chip = template_chip; 260 wm831x_gpio->gpio_chip.ngpio = wm831x->num_gpio; 261 wm831x_gpio->gpio_chip.dev = &pdev->dev; 262 if (pdata && pdata->gpio_base) 263 wm831x_gpio->gpio_chip.base = pdata->gpio_base; 264 else 265 wm831x_gpio->gpio_chip.base = -1; 266 267 ret = gpiochip_add(&wm831x_gpio->gpio_chip); 268 if (ret < 0) { 269 dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); 270 return ret; 271 } 272 273 platform_set_drvdata(pdev, wm831x_gpio); 274 275 return ret; 276} 277 278static int wm831x_gpio_remove(struct platform_device *pdev) 279{ 280 struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev); 281 282 gpiochip_remove(&wm831x_gpio->gpio_chip); 283 return 0; 284} 285 286static struct platform_driver wm831x_gpio_driver = { 287 .driver.name = "wm831x-gpio", 288 .driver.owner = THIS_MODULE, 289 .probe = wm831x_gpio_probe, 290 .remove = wm831x_gpio_remove, 291}; 292 293static int __init wm831x_gpio_init(void) 294{ 295 return platform_driver_register(&wm831x_gpio_driver); 296} 297subsys_initcall(wm831x_gpio_init); 298 299static void __exit wm831x_gpio_exit(void) 300{ 301 platform_driver_unregister(&wm831x_gpio_driver); 302} 303module_exit(wm831x_gpio_exit); 304 305MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 306MODULE_DESCRIPTION("GPIO interface for WM831x PMICs"); 307MODULE_LICENSE("GPL"); 308MODULE_ALIAS("platform:wm831x-gpio"); 309