rk30xx_gpio.c revision 266152
1/*- 2 * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> 3 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> 4 * Copyright (c) 2012 Luiz Otavio O Souza. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: stable/10/sys/arm/rockchip/rk30xx_gpio.c 266152 2014-05-15 16:11:06Z ian $"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35 36#include <sys/kernel.h> 37#include <sys/module.h> 38#include <sys/rman.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41#include <sys/gpio.h> 42 43#include <machine/bus.h> 44#include <machine/cpu.h> 45#include <machine/cpufunc.h> 46#include <machine/resource.h> 47#include <machine/fdt.h> 48#include <machine/intr.h> 49 50#include <dev/fdt/fdt_common.h> 51#include <dev/ofw/ofw_bus.h> 52#include <dev/ofw/ofw_bus_subr.h> 53 54#include "gpio_if.h" 55 56#include "rk30xx_grf.h" 57#include "rk30xx_pmu.h" 58 59/* 60 * RK3188 has 4 banks of gpio. 61 * 32 pins per bank 62 * PA0 - PA7 | PB0 - PB7 63 * PC0 - PC7 | PD0 - PD7 64 */ 65 66#define RK30_GPIO_PINS 128 67#define RK30_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ 68 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) 69 70#define RK30_GPIO_NONE 0 71#define RK30_GPIO_PULLUP 1 72#define RK30_GPIO_PULLDOWN 2 73 74#define RK30_GPIO_INPUT 0 75#define RK30_GPIO_OUTPUT 1 76 77struct rk30_gpio_softc { 78 device_t sc_dev; 79 struct mtx sc_mtx; 80 struct resource * sc_mem_res; 81 struct resource * sc_irq_res; 82 bus_space_tag_t sc_bst; 83 bus_space_handle_t sc_bsh; 84 void * sc_intrhand; 85 int sc_gpio_npins; 86 struct gpio_pin sc_gpio_pins[RK30_GPIO_PINS]; 87}; 88 89#define RK30_GPIO_LOCK(_sc) mtx_lock(&_sc->sc_mtx) 90#define RK30_GPIO_UNLOCK(_sc) mtx_unlock(&_sc->sc_mtx) 91#define RK30_GPIO_LOCK_ASSERT(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED) 92 93#define RK30_GPIO_SWPORT_DR 0x00 94#define RK30_GPIO_SWPORT_DDR 0x04 95#define RK30_GPIO_INTEN 0x30 96#define RK30_GPIO_INTMASK 0x34 97#define RK30_GPIO_INTTYPE_LEVEL 0x38 98#define RK30_GPIO_INT_POLARITY 0x3c 99#define RK30_GPIO_INT_STATUS 0x40 100#define RK30_GPIO_INT_RAWSTATUS 0x44 101#define RK30_GPIO_DEBOUNCE 0x48 102#define RK30_GPIO_PORTS_EOI 0x4c 103#define RK30_GPIO_EXT_PORT 0x50 104#define RK30_GPIO_LS_SYNC 0x60 105 106#define RK30_GPIO_WRITE(_sc, _off, _val) \ 107 bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) 108#define RK30_GPIO_READ(_sc, _off) \ 109 bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off) 110 111static uint32_t 112rk30_gpio_get_function(struct rk30_gpio_softc *sc, uint32_t pin) 113{ 114 uint32_t bank, func, offset; 115 116 bank = pin / 32; 117 pin = pin % 32; 118 offset = 1 << pin; 119 120 func = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 121 func &= offset; 122 123 return (func); 124} 125 126static uint32_t 127rk30_gpio_func_flag(uint32_t nfunc) 128{ 129 130 switch (nfunc) { 131 case RK30_GPIO_INPUT: 132 return (GPIO_PIN_INPUT); 133 case RK30_GPIO_OUTPUT: 134 return (GPIO_PIN_OUTPUT); 135 } 136 return (0); 137} 138 139static void 140rk30_gpio_set_function(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t f) 141{ 142 uint32_t bank, data, offset; 143 144 /* Must be called with lock held. */ 145 RK30_GPIO_LOCK_ASSERT(sc); 146 147 bank = pin / 32; 148 pin = pin % 32; 149 offset = 1 << pin; 150 151 data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 152 if (f) 153 data |= offset; 154 else 155 data &= ~offset; 156 RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); 157} 158 159static void 160rk30_gpio_set_pud(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t state) 161{ 162 uint32_t bank; 163 164 bank = pin / 32; 165 166 /* Must be called with lock held. */ 167 RK30_GPIO_LOCK_ASSERT(sc); 168 169 if (bank == 0 && pin < 12) 170 rk30_pmu_gpio_pud(pin, state); 171 else 172 rk30_grf_gpio_pud(bank, pin, state); 173} 174 175static void 176rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin, 177 unsigned int flags) 178{ 179 180 RK30_GPIO_LOCK(sc); 181 182 /* 183 * Manage input/output. 184 */ 185 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 186 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 187 if (flags & GPIO_PIN_OUTPUT) { 188 pin->gp_flags |= GPIO_PIN_OUTPUT; 189 rk30_gpio_set_function(sc, pin->gp_pin, 190 RK30_GPIO_OUTPUT); 191 } else { 192 pin->gp_flags |= GPIO_PIN_INPUT; 193 rk30_gpio_set_function(sc, pin->gp_pin, 194 RK30_GPIO_INPUT); 195 } 196 } 197 198 /* Manage Pull-up/pull-down. */ 199 pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN); 200 if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) { 201 if (flags & GPIO_PIN_PULLUP) { 202 pin->gp_flags |= GPIO_PIN_PULLUP; 203 rk30_gpio_set_pud(sc, pin->gp_pin, 204 RK30_GPIO_PULLUP); 205 } else { 206 pin->gp_flags |= GPIO_PIN_PULLDOWN; 207 rk30_gpio_set_pud(sc, pin->gp_pin, 208 RK30_GPIO_PULLDOWN); 209 } 210 } else 211 rk30_gpio_set_pud(sc, pin->gp_pin, RK30_GPIO_NONE); 212 213 RK30_GPIO_UNLOCK(sc); 214} 215 216static int 217rk30_gpio_pin_max(device_t dev, int *maxpin) 218{ 219 220 *maxpin = RK30_GPIO_PINS - 1; 221 return (0); 222} 223 224static int 225rk30_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 226{ 227 struct rk30_gpio_softc *sc = device_get_softc(dev); 228 int i; 229 230 for (i = 0; i < sc->sc_gpio_npins; i++) { 231 if (sc->sc_gpio_pins[i].gp_pin == pin) 232 break; 233 } 234 235 if (i >= sc->sc_gpio_npins) 236 return (EINVAL); 237 238 RK30_GPIO_LOCK(sc); 239 *caps = sc->sc_gpio_pins[i].gp_caps; 240 RK30_GPIO_UNLOCK(sc); 241 242 return (0); 243} 244 245static int 246rk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 247{ 248 struct rk30_gpio_softc *sc = device_get_softc(dev); 249 int i; 250 251 for (i = 0; i < sc->sc_gpio_npins; i++) { 252 if (sc->sc_gpio_pins[i].gp_pin == pin) 253 break; 254 } 255 256 if (i >= sc->sc_gpio_npins) 257 return (EINVAL); 258 259 RK30_GPIO_LOCK(sc); 260 *flags = sc->sc_gpio_pins[i].gp_flags; 261 RK30_GPIO_UNLOCK(sc); 262 263 return (0); 264} 265 266static int 267rk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 268{ 269 struct rk30_gpio_softc *sc = device_get_softc(dev); 270 int i; 271 272 for (i = 0; i < sc->sc_gpio_npins; i++) { 273 if (sc->sc_gpio_pins[i].gp_pin == pin) 274 break; 275 } 276 277 if (i >= sc->sc_gpio_npins) 278 return (EINVAL); 279 280 RK30_GPIO_LOCK(sc); 281 memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME); 282 RK30_GPIO_UNLOCK(sc); 283 284 return (0); 285} 286 287static int 288rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 289{ 290 struct rk30_gpio_softc *sc = device_get_softc(dev); 291 int i; 292 293 for (i = 0; i < sc->sc_gpio_npins; i++) { 294 if (sc->sc_gpio_pins[i].gp_pin == pin) 295 break; 296 } 297 298 if (i >= sc->sc_gpio_npins) 299 return (EINVAL); 300 301 /* Check for unwanted flags. */ 302 if ((flags & sc->sc_gpio_pins[i].gp_caps) != flags) 303 return (EINVAL); 304 305 /* Can't mix input/output together. */ 306 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == 307 (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) 308 return (EINVAL); 309 310 /* Can't mix pull-up/pull-down together. */ 311 if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) == 312 (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) 313 return (EINVAL); 314 315 rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); 316 317 return (0); 318} 319 320static int 321rk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 322{ 323 struct rk30_gpio_softc *sc = device_get_softc(dev); 324 uint32_t bank, offset, data; 325 int i; 326 327 for (i = 0; i < sc->sc_gpio_npins; i++) { 328 if (sc->sc_gpio_pins[i].gp_pin == pin) 329 break; 330 } 331 332 if (i >= sc->sc_gpio_npins) 333 return (EINVAL); 334 335 bank = pin / 32; 336 pin = pin % 32; 337 offset = 1 << pin; 338 339 RK30_GPIO_LOCK(sc); 340 data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 341 data |= offset; 342 RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); 343 344 data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); 345 if (value) 346 data |= offset; 347 else 348 data &= ~offset; 349 RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); 350 RK30_GPIO_UNLOCK(sc); 351 352 return (0); 353} 354 355static int 356rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 357{ 358 struct rk30_gpio_softc *sc = device_get_softc(dev); 359 uint32_t bank, offset, reg_data; 360 int i; 361 362 for (i = 0; i < sc->sc_gpio_npins; i++) { 363 if (sc->sc_gpio_pins[i].gp_pin == pin) 364 break; 365 } 366 367 if (i >= sc->sc_gpio_npins) 368 return (EINVAL); 369 370 bank = pin / 32; 371 pin = pin % 32; 372 offset = 1 << pin; 373 374 RK30_GPIO_LOCK(sc); 375 reg_data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT); 376 RK30_GPIO_UNLOCK(sc); 377 *val = (reg_data & offset) ? 1 : 0; 378 379 return (0); 380} 381 382static int 383rk30_gpio_pin_toggle(device_t dev, uint32_t pin) 384{ 385 struct rk30_gpio_softc *sc = device_get_softc(dev); 386 uint32_t bank, data, offset; 387 int i; 388 389 for (i = 0; i < sc->sc_gpio_npins; i++) { 390 if (sc->sc_gpio_pins[i].gp_pin == pin) 391 break; 392 } 393 394 if (i >= sc->sc_gpio_npins) 395 return (EINVAL); 396 397 bank = pin / 32; 398 pin = pin % 32; 399 offset = 1 << pin; 400 401 RK30_GPIO_LOCK(sc); 402 data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 403 if (data & offset) 404 data &= ~offset; 405 else 406 data |= offset; 407 RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); 408 409 data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); 410 if (data & offset) 411 data &= ~offset; 412 else 413 data |= offset; 414 RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); 415 RK30_GPIO_UNLOCK(sc); 416 417 return (0); 418} 419 420static int 421rk30_gpio_probe(device_t dev) 422{ 423 424 if (!ofw_bus_status_okay(dev)) 425 return (ENXIO); 426 427 if (!ofw_bus_is_compatible(dev, "rockchip,rk30xx-gpio")) 428 return (ENXIO); 429 430 device_set_desc(dev, "Rockchip RK30XX GPIO controller"); 431 return (BUS_PROBE_DEFAULT); 432} 433 434static int 435rk30_gpio_attach(device_t dev) 436{ 437 struct rk30_gpio_softc *sc = device_get_softc(dev); 438 uint32_t func; 439 int i, rid; 440 phandle_t gpio; 441 442 sc->sc_dev = dev; 443 444 mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF); 445 446 rid = 0; 447 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 448 RF_ACTIVE); 449 if (!sc->sc_mem_res) { 450 device_printf(dev, "cannot allocate memory window\n"); 451 return (ENXIO); 452 } 453 454 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 455 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 456 457 rid = 0; 458 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 459 RF_ACTIVE); 460 if (!sc->sc_irq_res) { 461 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 462 device_printf(dev, "cannot allocate interrupt\n"); 463 return (ENXIO); 464 } 465 466 /* Find our node. */ 467 gpio = ofw_bus_get_node(sc->sc_dev); 468 469 if (!OF_hasprop(gpio, "gpio-controller")) 470 /* Node is not a GPIO controller. */ 471 goto fail; 472 473 /* Initialize the software controlled pins. */ 474 for (i = 0; i < RK30_GPIO_PINS; i++) { 475 snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, 476 "pin %d", i); 477 func = rk30_gpio_get_function(sc, i); 478 sc->sc_gpio_pins[i].gp_pin = i; 479 sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS; 480 sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func); 481 } 482 sc->sc_gpio_npins = i; 483 484 device_add_child(dev, "gpioc", device_get_unit(dev)); 485 device_add_child(dev, "gpiobus", device_get_unit(dev)); 486 return (bus_generic_attach(dev)); 487 488fail: 489 if (sc->sc_irq_res) 490 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 491 if (sc->sc_mem_res) 492 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 493 return (ENXIO); 494} 495 496static int 497rk30_gpio_detach(device_t dev) 498{ 499 500 return (EBUSY); 501} 502 503static device_method_t rk30_gpio_methods[] = { 504 /* Device interface */ 505 DEVMETHOD(device_probe, rk30_gpio_probe), 506 DEVMETHOD(device_attach, rk30_gpio_attach), 507 DEVMETHOD(device_detach, rk30_gpio_detach), 508 509 /* GPIO protocol */ 510 DEVMETHOD(gpio_pin_max, rk30_gpio_pin_max), 511 DEVMETHOD(gpio_pin_getname, rk30_gpio_pin_getname), 512 DEVMETHOD(gpio_pin_getflags, rk30_gpio_pin_getflags), 513 DEVMETHOD(gpio_pin_getcaps, rk30_gpio_pin_getcaps), 514 DEVMETHOD(gpio_pin_setflags, rk30_gpio_pin_setflags), 515 DEVMETHOD(gpio_pin_get, rk30_gpio_pin_get), 516 DEVMETHOD(gpio_pin_set, rk30_gpio_pin_set), 517 DEVMETHOD(gpio_pin_toggle, rk30_gpio_pin_toggle), 518 519 DEVMETHOD_END 520}; 521 522static devclass_t rk30_gpio_devclass; 523 524static driver_t rk30_gpio_driver = { 525 "gpio", 526 rk30_gpio_methods, 527 sizeof(struct rk30_gpio_softc), 528}; 529 530DRIVER_MODULE(rk30_gpio, simplebus, rk30_gpio_driver, rk30_gpio_devclass, 0, 0); 531