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