1 /* $NetBSD: exynos_gpio.c,v 1.23 2015/12/31 03:50:34 marty Exp $ */ 2 3 /*- 4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Reinoud Zandijk 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include "opt_exynos.h" 33 #include "opt_arm_debug.h" 34 #include "gpio.h" 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.23 2015/12/31 03:50:34 marty Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/bus.h> 41 #include <sys/device.h> 42 #include <sys/intr.h> 43 #include <sys/systm.h> 44 #include <sys/kmem.h> 45 #include <sys/gpio.h> 46 47 #include <dev/gpio/gpiovar.h> 48 49 #include <arm/samsung/exynos_reg.h> 50 #include <arm/samsung/exynos_var.h> 51 #include <arm/samsung/exynos_intr.h> 52 #include <arm/samsung/exynos_pinctrl.h> 53 54 #include <dev/fdt/fdtvar.h> 55 56 struct exynos_gpio_bank { 57 const char bank_name[6]; 58 device_t bank_dev; 59 struct gpio_chipset_tag bank_gc; 60 struct exynos_gpio_softc *bank_sc; 61 gpio_pin_t bank_pins[8]; 62 63 const bus_addr_t bank_core_offset; 64 const uint8_t bank_bits; 65 66 uint8_t bank_pin_mask; 67 uint8_t bank_pin_inuse_mask; 68 bus_space_handle_t bank_bsh; 69 struct exynos_gpio_pin_cfg bank_cfg; 70 struct exynos_gpio_bank * bank_next; 71 }; 72 73 struct exynos_gpio_pin { 74 struct exynos_gpio_softc *pin_sc; 75 int pin_no; 76 u_int pin_flags; 77 int pin_actlo; 78 const struct exynos_gpio_bank *pin_bank; 79 }; 80 81 82 //#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o)) 83 #define GPIO_REG(v,s,o) ((o)) 84 #define GPIO_GRP(v, s, o, n, b) \ 85 { \ 86 .bank_name = #n, \ 87 .bank_core_offset = GPIO_REG(v,s,o), \ 88 .bank_bits = b, \ 89 } 90 91 static struct exynos_gpio_bank exynos5_banks[] = { 92 GPIO_GRP(5, MUXA, 0x0000, gpy7, 8), 93 GPIO_GRP(5, MUXA, 0x0C00, gpx0, 8), 94 GPIO_GRP(5, MUXA, 0x0C20, gpx1, 8), 95 GPIO_GRP(5, MUXA, 0x0C40, gpx2, 8), 96 GPIO_GRP(5, MUXA, 0x0C60, gpx3, 8), 97 98 GPIO_GRP(5, MUXB, 0x0000, gpc0, 8), 99 GPIO_GRP(5, MUXB, 0x0020, gpc1, 8), 100 GPIO_GRP(5, MUXB, 0x0040, gpc2, 7), 101 GPIO_GRP(5, MUXB, 0x0060, gpc3, 4), 102 GPIO_GRP(5, MUXB, 0x0080, gpc4, 2), 103 GPIO_GRP(5, MUXB, 0x00A0, gpd1, 8), 104 GPIO_GRP(5, MUXB, 0x00C0, gpy0, 6), 105 GPIO_GRP(5, MUXB, 0x00E0, gpy1, 4), 106 GPIO_GRP(5, MUXB, 0x0100, gpy2, 6), 107 GPIO_GRP(5, MUXB, 0x0120, gpy3, 8), 108 GPIO_GRP(5, MUXB, 0x0140, gpy4, 8), 109 GPIO_GRP(5, MUXB, 0x0160, gpy5, 8), 110 GPIO_GRP(5, MUXB, 0x0180, gpy6, 8), 111 112 GPIO_GRP(5, MUXC, 0x0000, gpe0, 8), 113 GPIO_GRP(5, MUXC, 0x0020, gpe1, 2), 114 GPIO_GRP(5, MUXC, 0x0040, gpf0, 6), 115 GPIO_GRP(5, MUXC, 0x0060, gpf1, 8), 116 GPIO_GRP(5, MUXC, 0x0080, gpg0, 8), 117 GPIO_GRP(5, MUXC, 0x00A0, gpg1, 8), 118 GPIO_GRP(5, MUXC, 0x00C0, gpg2, 2), 119 GPIO_GRP(5, MUXC, 0x00E0, gpj4, 4), 120 121 GPIO_GRP(5, MUXD, 0x0000, gpa0, 8), 122 GPIO_GRP(5, MUXD, 0x0020, gpa1, 6), 123 GPIO_GRP(5, MUXD, 0x0040, gpa2, 8), 124 GPIO_GRP(5, MUXD, 0x0060, gpb0, 5), 125 GPIO_GRP(5, MUXD, 0x0080, gpb1, 5), 126 GPIO_GRP(5, MUXD, 0x00A0, gpb2, 4), 127 GPIO_GRP(5, MUXD, 0x00C0, gpb3, 8), 128 GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2), 129 GPIO_GRP(5, MUXD, 0x0100, gph0, 4), 130 131 GPIO_GRP(5, MUXE, 0x0000, gpz, 7), 132 133 }; 134 135 struct exynos_gpio_bank *exynos_gpio_banks = exynos5_banks; 136 137 static int exynos_gpio_pin_read(void *, int); 138 static void exynos_gpio_pin_write(void *, int, int); 139 static void exynos_gpio_pin_ctl(void *, int, int); 140 static void *exynos_gpio_fdt_acquire(device_t, const void *, 141 size_t, int); 142 static void exynos_gpio_fdt_release(device_t, void *); 143 144 static int exynos_gpio_fdt_read(device_t, void *, bool); 145 static void exynos_gpio_fdt_write(device_t, void *, int, bool); 146 static int exynos_gpio_cfprint(void *, const char *); 147 148 struct fdtbus_gpio_controller_func exynos_gpio_funcs = { 149 .acquire = exynos_gpio_fdt_acquire, 150 .release = exynos_gpio_fdt_release, 151 .read = exynos_gpio_fdt_read, 152 .write = exynos_gpio_fdt_write 153 }; 154 #define GPIO_WRITE(bank, reg, val) \ 155 bus_space_write_4((bank)->bank_sc->sc_bst, \ 156 (bank)->bank_sc->sc_bsh, \ 157 (bank)->bank_core_offset + (reg), (val)) 158 #define GPIO_READ(bank, reg) \ 159 bus_space_read_4((bank)->bank_sc->sc_bst, \ 160 (bank)->bank_sc->sc_bsh, \ 161 (bank)->bank_core_offset + (reg)) 162 163 static int 164 exynos_gpio_cfprint(void *priv, const char *pnp) 165 { 166 struct gpiobus_attach_args *gba = priv; 167 struct exynos_gpio_bank *bank = gba->gba_gc->gp_cookie; 168 const char *bankname = bank->bank_name; 169 170 if (pnp) 171 aprint_normal("gpiobus at %s", pnp); 172 173 aprint_normal(" (%s)", bankname); 174 175 return UNCONF; 176 } 177 178 static void 179 exynos_gpio_update_cfg_regs(struct exynos_gpio_bank *bank, 180 const struct exynos_gpio_pin_cfg *ncfg) 181 { 182 if (bank->bank_cfg.cfg != ncfg->cfg) { 183 GPIO_WRITE(bank, EXYNOS_GPIO_CON, ncfg->cfg); 184 bank->bank_cfg.cfg = ncfg->cfg; 185 } 186 if (bank->bank_cfg.pud != ncfg->pud) { 187 GPIO_WRITE(bank, EXYNOS_GPIO_PUD, ncfg->pud); 188 bank->bank_cfg.pud = ncfg->pud; 189 } 190 191 if (bank->bank_cfg.drv != ncfg->drv) { 192 GPIO_WRITE(bank, EXYNOS_GPIO_DRV, ncfg->drv); 193 bank->bank_cfg.drv = ncfg->drv; 194 } 195 if (bank->bank_cfg.conpwd != ncfg->conpwd) { 196 GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, ncfg->conpwd); 197 bank->bank_cfg.conpwd = ncfg->conpwd; 198 } 199 if (bank->bank_cfg.pudpwd != ncfg->pudpwd) { 200 GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, ncfg->pudpwd); 201 bank->bank_cfg.pudpwd = ncfg->pudpwd; 202 } 203 } 204 205 static int 206 exynos_gpio_pin_read(void *cookie, int pin) 207 { 208 struct exynos_gpio_bank * const bank = cookie; 209 210 KASSERT(pin < bank->bank_bits); 211 return (bus_space_read_1(bank->bank_sc->sc_bst, 212 bank->bank_sc->sc_bsh, 213 EXYNOS_GPIO_DAT) >> pin) & 1; 214 } 215 216 static void 217 exynos_gpio_pin_write(void *cookie, int pin, int value) 218 { 219 struct exynos_gpio_bank * const bank = cookie; 220 int val; 221 222 KASSERT(pin < bank->bank_bits); 223 val = bus_space_read_1(bank->bank_sc->sc_bst, 224 bank->bank_sc->sc_bsh, 225 EXYNOS_GPIO_DAT); 226 val &= ~__BIT(pin); 227 if (value) 228 val |= __BIT(pin); 229 bus_space_write_1(bank->bank_sc->sc_bst, 230 bank->bank_sc->sc_bsh, 231 EXYNOS_GPIO_DAT, val); 232 } 233 234 static void 235 exynos_gpio_pin_ctl(void *cookie, int pin, int flags) 236 { 237 struct exynos_gpio_bank * const bank = cookie; 238 struct exynos_gpio_pin_cfg ncfg = bank->bank_cfg; 239 u_int shift; 240 int pull; 241 242 /* honour pullup requests */ 243 pull = EXYNOS_GPIO_PIN_FLOAT; 244 if (flags & GPIO_PIN_PULLUP) 245 pull = EXYNOS_GPIO_PIN_PULL_UP; 246 if (flags & GPIO_PIN_PULLDOWN) 247 pull = EXYNOS_GPIO_PIN_PULL_DOWN; 248 shift = (pin & 7) << 1; 249 ncfg.pud &= ~(0x3 << shift); 250 ncfg.pud |= pull << shift; 251 252 /* honour i/o */ 253 if (flags & GPIO_PIN_INPUT) { 254 ncfg.cfg &= ~(0x0f << shift); 255 ncfg.cfg |= EXYNOS_GPIO_FUNC_INPUT << shift; 256 } else if (flags & GPIO_PIN_OUTPUT) { 257 ncfg.cfg &= ~(0x0f << shift); 258 ncfg.cfg |= EXYNOS_GPIO_FUNC_OUTPUT << shift; 259 } 260 261 /* update any config registers that changed */ 262 exynos_gpio_update_cfg_regs(bank, &ncfg); 263 } 264 265 void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *bank, 266 struct exynos_gpio_pin_cfg *cfg) 267 { 268 cfg->cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); 269 cfg->pud = GPIO_READ(bank, EXYNOS_GPIO_PUD); 270 cfg->drv = GPIO_READ(bank, EXYNOS_GPIO_DRV); 271 cfg->conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); 272 cfg->pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); 273 } 274 275 void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *bank, 276 const struct exynos_gpio_pin_cfg *cfg) 277 { 278 GPIO_WRITE(bank, EXYNOS_GPIO_CON, cfg->cfg); 279 GPIO_WRITE(bank, EXYNOS_GPIO_PUD, cfg->pud); 280 GPIO_WRITE(bank, EXYNOS_GPIO_DRV, cfg->drv); 281 GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, cfg->conpwd); 282 GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, cfg->pudpwd); 283 } 284 285 struct exynos_gpio_softc * 286 exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent, 287 const struct fdt_attach_args *faa, int node) 288 { 289 struct exynos_gpio_bank *bank = kmem_zalloc(sizeof(*bank), KM_SLEEP); 290 struct exynos_gpio_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 291 struct gpiobus_attach_args gba; 292 struct gpio_chipset_tag *gc_tag; 293 char result[64]; 294 295 OF_getprop(node, "name", result, sizeof(result)); 296 bank = exynos_gpio_bank_lookup(result); 297 if (bank == NULL) { 298 aprint_error_dev(parent->sc_dev, "no bank found for %s\n", 299 result); 300 return NULL; 301 } 302 303 sc->sc_dev = parent->sc_dev; 304 sc->sc_bst = &armv7_generic_bs_tag; 305 sc->sc_bsh = parent->sc_bsh; 306 sc->sc_bank = bank; 307 308 gc_tag = &bank->bank_gc; 309 gc_tag->gp_cookie = bank; 310 gc_tag->gp_pin_read = exynos_gpio_pin_read; 311 gc_tag->gp_pin_write = exynos_gpio_pin_write; 312 gc_tag->gp_pin_ctl = exynos_gpio_pin_ctl; 313 memset(&gba, 0, sizeof(gba)); 314 gba.gba_gc = &bank->bank_gc; 315 gba.gba_pins = bank->bank_pins; 316 gba.gba_npins = bank->bank_bits; 317 bank->bank_sc = sc; 318 bank->bank_dev = config_found_ia(parent->sc_dev, "gpiobus", &gba, 319 exynos_gpio_cfprint); 320 321 bank->bank_pin_mask = __BIT(bank->bank_bits) - 1; 322 bank->bank_pin_inuse_mask = 0; 323 324 325 /* read in our initial settings */ 326 bank->bank_cfg.cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); 327 bank->bank_cfg.pud = GPIO_READ(bank, EXYNOS_GPIO_PUD); 328 bank->bank_cfg.drv = GPIO_READ(bank, EXYNOS_GPIO_DRV); 329 bank->bank_cfg.conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); 330 bank->bank_cfg.pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); 331 332 fdtbus_register_gpio_controller(bank->bank_dev, node, 333 &exynos_gpio_funcs); 334 return sc; 335 } 336 337 /* 338 * This function is a bit funky. Given a string that may look like 339 * 'gpAN' or 'gpAN-P' it is meant to find a match to the part before 340 * the '-', or the four character string if the dash is not present. 341 */ 342 struct exynos_gpio_bank * 343 exynos_gpio_bank_lookup(const char *name) 344 { 345 struct exynos_gpio_bank *bank; 346 347 for (u_int n = 0; n < __arraycount(exynos5_banks); n++) { 348 bank = &exynos_gpio_banks[n]; 349 if (!strncmp(bank->bank_name, name, 350 strlen(bank->bank_name))) { 351 return bank; 352 } 353 } 354 355 return NULL; 356 } 357 358 #if notyet 359 static int 360 exynos_gpio_pin_lookup(const char *name) 361 { 362 char *p; 363 364 p = strchr(name, '-'); 365 if (p == NULL || p[1] < '0' || p[1] > '9') 366 return -1; 367 368 return p[1] - '0'; 369 } 370 #endif 371 372 static void * 373 exynos_gpio_fdt_acquire(device_t dev, const void *data, size_t len, int flags) 374 { 375 const u_int *cells = data; 376 struct exynos_gpio_bank *bank = NULL; 377 struct exynos_gpio_pin *gpin; 378 int n; 379 380 if (len != 12) 381 return NULL; 382 383 const int pin = be32toh(cells[1]) & 0x0f; 384 const int actlo = be32toh(cells[2]) & 0x01; 385 386 for (n = 0; n < __arraycount(exynos5_banks); n++) { 387 if (exynos_gpio_banks[n].bank_dev == dev) { 388 bank = &exynos_gpio_banks[n]; 389 break; 390 } 391 } 392 if (bank == NULL) 393 return NULL; 394 395 gpin = kmem_alloc(sizeof(*gpin), KM_SLEEP); 396 gpin->pin_sc = bank->bank_sc; 397 gpin->pin_bank = bank; 398 gpin->pin_no = pin; 399 gpin->pin_flags = flags; 400 gpin->pin_actlo = actlo; 401 402 exynos_gpio_pin_ctl(bank, gpin->pin_no, gpin->pin_flags); 403 404 return gpin; 405 } 406 407 static void 408 exynos_gpio_fdt_release(device_t dev, void *priv) 409 { 410 struct exynos_gpio_pin *gpin = priv; 411 412 kmem_free(gpin, sizeof(*gpin)); 413 } 414 415 static int 416 exynos_gpio_fdt_read(device_t dev, void *priv, bool raw) 417 { 418 struct exynos_gpio_pin *gpin = priv; 419 int val; 420 421 val = (bus_space_read_1(gpin->pin_sc->sc_bst, 422 gpin->pin_sc->sc_bsh, 423 EXYNOS_GPIO_DAT) >> gpin->pin_no) & 1; 424 425 if (!raw && gpin->pin_actlo) 426 val = !val; 427 428 return val; 429 } 430 431 static void 432 exynos_gpio_fdt_write(device_t dev, void *priv, int val, bool raw) 433 { 434 struct exynos_gpio_pin *gpin = priv; 435 436 if (!raw && gpin->pin_actlo) 437 val = !val; 438 439 val = bus_space_read_1(gpin->pin_sc->sc_bst, 440 gpin->pin_sc->sc_bsh, 441 EXYNOS_GPIO_DAT); 442 val &= ~__BIT(gpin->pin_no); 443 if (val) 444 val |= __BIT(gpin->pin_no); 445 bus_space_write_1(gpin->pin_sc->sc_bst, 446 gpin->pin_sc->sc_bsh, 447 EXYNOS_GPIO_DAT, val); 448 449 } 450