1256949Sganbold/*- 2266337Sian * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org> 3256949Sganbold * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> 4256949Sganbold * Copyright (c) 2012 Luiz Otavio O Souza. 5256949Sganbold * All rights reserved. 6256949Sganbold * 7256949Sganbold * Redistribution and use in source and binary forms, with or without 8256949Sganbold * modification, are permitted provided that the following conditions 9256949Sganbold * are met: 10256949Sganbold * 1. Redistributions of source code must retain the above copyright 11256949Sganbold * notice, this list of conditions and the following disclaimer. 12256949Sganbold * 2. Redistributions in binary form must reproduce the above copyright 13256949Sganbold * notice, this list of conditions and the following disclaimer in the 14256949Sganbold * documentation and/or other materials provided with the distribution. 15256949Sganbold * 16256949Sganbold * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17256949Sganbold * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18256949Sganbold * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19256949Sganbold * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20256949Sganbold * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21256949Sganbold * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22256949Sganbold * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23256949Sganbold * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24256949Sganbold * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25256949Sganbold * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26256949Sganbold * SUCH DAMAGE. 27256949Sganbold * 28256949Sganbold */ 29256949Sganbold#include <sys/cdefs.h> 30256949Sganbold__FBSDID("$FreeBSD: releng/10.2/sys/arm/rockchip/rk30xx_gpio.c 278786 2015-02-14 21:16:19Z loos $"); 31256949Sganbold 32256949Sganbold#include <sys/param.h> 33256949Sganbold#include <sys/systm.h> 34256949Sganbold#include <sys/bus.h> 35256949Sganbold 36256949Sganbold#include <sys/kernel.h> 37256949Sganbold#include <sys/module.h> 38256949Sganbold#include <sys/rman.h> 39256949Sganbold#include <sys/lock.h> 40256949Sganbold#include <sys/mutex.h> 41256949Sganbold#include <sys/gpio.h> 42256949Sganbold 43256949Sganbold#include <machine/bus.h> 44256949Sganbold#include <machine/cpu.h> 45256949Sganbold#include <machine/cpufunc.h> 46256949Sganbold#include <machine/resource.h> 47256949Sganbold#include <machine/fdt.h> 48256949Sganbold#include <machine/intr.h> 49256949Sganbold 50256949Sganbold#include <dev/fdt/fdt_common.h> 51256949Sganbold#include <dev/ofw/ofw_bus.h> 52256949Sganbold#include <dev/ofw/ofw_bus_subr.h> 53256949Sganbold 54256949Sganbold#include "gpio_if.h" 55256949Sganbold 56256949Sganbold#include "rk30xx_grf.h" 57256949Sganbold#include "rk30xx_pmu.h" 58256949Sganbold 59256949Sganbold/* 60256949Sganbold * RK3188 has 4 banks of gpio. 61256949Sganbold * 32 pins per bank 62256949Sganbold * PA0 - PA7 | PB0 - PB7 63256949Sganbold * PC0 - PC7 | PD0 - PD7 64256949Sganbold */ 65256949Sganbold 66256949Sganbold#define RK30_GPIO_PINS 128 67256949Sganbold#define RK30_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ 68256949Sganbold GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) 69256949Sganbold 70256949Sganbold#define RK30_GPIO_NONE 0 71256949Sganbold#define RK30_GPIO_PULLUP 1 72256949Sganbold#define RK30_GPIO_PULLDOWN 2 73256949Sganbold 74256949Sganbold#define RK30_GPIO_INPUT 0 75256949Sganbold#define RK30_GPIO_OUTPUT 1 76256949Sganbold 77256949Sganboldstruct rk30_gpio_softc { 78256949Sganbold device_t sc_dev; 79256949Sganbold struct mtx sc_mtx; 80256949Sganbold struct resource * sc_mem_res; 81256949Sganbold struct resource * sc_irq_res; 82256949Sganbold bus_space_tag_t sc_bst; 83256949Sganbold bus_space_handle_t sc_bsh; 84256949Sganbold void * sc_intrhand; 85256949Sganbold int sc_gpio_npins; 86256949Sganbold struct gpio_pin sc_gpio_pins[RK30_GPIO_PINS]; 87256949Sganbold}; 88256949Sganbold 89273650Sianstatic struct rk30_gpio_softc *rk30_gpio_sc = NULL; 90273650Sian 91273650Siantypedef int (*gpios_phandler_t)(phandle_t, pcell_t *, int); 92273650Sian 93273650Sianstruct gpio_ctrl_entry { 94273650Sian const char *compat; 95273650Sian gpios_phandler_t handler; 96273650Sian}; 97273650Sian 98273650Sianint rk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len); 99273650Sianstatic int rk30_gpio_init(void); 100273650Sian 101273650Sianstruct gpio_ctrl_entry gpio_controllers[] = { 102273650Sian { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle }, 103273650Sian { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle }, 104273650Sian { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle }, 105273650Sian { "rockchip,rk30xx-gpio", &rk30_gpios_prop_handle }, 106273650Sian { NULL, NULL } 107273650Sian}; 108273650Sian 109256949Sganbold#define RK30_GPIO_LOCK(_sc) mtx_lock(&_sc->sc_mtx) 110256949Sganbold#define RK30_GPIO_UNLOCK(_sc) mtx_unlock(&_sc->sc_mtx) 111256949Sganbold#define RK30_GPIO_LOCK_ASSERT(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED) 112256949Sganbold 113256949Sganbold#define RK30_GPIO_SWPORT_DR 0x00 114256949Sganbold#define RK30_GPIO_SWPORT_DDR 0x04 115256949Sganbold#define RK30_GPIO_INTEN 0x30 116256949Sganbold#define RK30_GPIO_INTMASK 0x34 117256949Sganbold#define RK30_GPIO_INTTYPE_LEVEL 0x38 118256949Sganbold#define RK30_GPIO_INT_POLARITY 0x3c 119256949Sganbold#define RK30_GPIO_INT_STATUS 0x40 120256949Sganbold#define RK30_GPIO_INT_RAWSTATUS 0x44 121256949Sganbold#define RK30_GPIO_DEBOUNCE 0x48 122256949Sganbold#define RK30_GPIO_PORTS_EOI 0x4c 123256949Sganbold#define RK30_GPIO_EXT_PORT 0x50 124256949Sganbold#define RK30_GPIO_LS_SYNC 0x60 125256949Sganbold 126256949Sganbold#define RK30_GPIO_WRITE(_sc, _off, _val) \ 127256949Sganbold bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) 128256949Sganbold#define RK30_GPIO_READ(_sc, _off) \ 129256949Sganbold bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off) 130256949Sganbold 131256949Sganboldstatic uint32_t 132256949Sganboldrk30_gpio_get_function(struct rk30_gpio_softc *sc, uint32_t pin) 133256949Sganbold{ 134256949Sganbold uint32_t bank, func, offset; 135256949Sganbold 136256949Sganbold bank = pin / 32; 137256949Sganbold pin = pin % 32; 138256949Sganbold offset = 1 << pin; 139256949Sganbold 140256949Sganbold func = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 141256949Sganbold func &= offset; 142256949Sganbold 143256949Sganbold return (func); 144256949Sganbold} 145256949Sganbold 146256949Sganboldstatic uint32_t 147256949Sganboldrk30_gpio_func_flag(uint32_t nfunc) 148256949Sganbold{ 149256949Sganbold 150256949Sganbold switch (nfunc) { 151256949Sganbold case RK30_GPIO_INPUT: 152256949Sganbold return (GPIO_PIN_INPUT); 153256949Sganbold case RK30_GPIO_OUTPUT: 154256949Sganbold return (GPIO_PIN_OUTPUT); 155256949Sganbold } 156256949Sganbold return (0); 157256949Sganbold} 158256949Sganbold 159256949Sganboldstatic void 160256949Sganboldrk30_gpio_set_function(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t f) 161256949Sganbold{ 162256949Sganbold uint32_t bank, data, offset; 163256949Sganbold 164256949Sganbold /* Must be called with lock held. */ 165256949Sganbold RK30_GPIO_LOCK_ASSERT(sc); 166256949Sganbold 167256949Sganbold bank = pin / 32; 168256949Sganbold pin = pin % 32; 169256949Sganbold offset = 1 << pin; 170256949Sganbold 171256949Sganbold data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 172256949Sganbold if (f) 173256949Sganbold data |= offset; 174256949Sganbold else 175256949Sganbold data &= ~offset; 176256949Sganbold RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); 177256949Sganbold} 178256949Sganbold 179256949Sganboldstatic void 180256949Sganboldrk30_gpio_set_pud(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t state) 181256949Sganbold{ 182256949Sganbold uint32_t bank; 183256949Sganbold 184256949Sganbold bank = pin / 32; 185256949Sganbold 186256949Sganbold /* Must be called with lock held. */ 187256949Sganbold RK30_GPIO_LOCK_ASSERT(sc); 188256949Sganbold 189256949Sganbold if (bank == 0 && pin < 12) 190256949Sganbold rk30_pmu_gpio_pud(pin, state); 191256949Sganbold else 192256949Sganbold rk30_grf_gpio_pud(bank, pin, state); 193256949Sganbold} 194256949Sganbold 195256949Sganboldstatic void 196256949Sganboldrk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin, 197256949Sganbold unsigned int flags) 198256949Sganbold{ 199256949Sganbold 200256949Sganbold RK30_GPIO_LOCK(sc); 201256949Sganbold 202256949Sganbold /* 203256949Sganbold * Manage input/output. 204256949Sganbold */ 205256949Sganbold if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 206256949Sganbold pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 207256949Sganbold if (flags & GPIO_PIN_OUTPUT) { 208256949Sganbold pin->gp_flags |= GPIO_PIN_OUTPUT; 209256949Sganbold rk30_gpio_set_function(sc, pin->gp_pin, 210256949Sganbold RK30_GPIO_OUTPUT); 211256949Sganbold } else { 212256949Sganbold pin->gp_flags |= GPIO_PIN_INPUT; 213256949Sganbold rk30_gpio_set_function(sc, pin->gp_pin, 214256949Sganbold RK30_GPIO_INPUT); 215256949Sganbold } 216256949Sganbold } 217256949Sganbold 218256949Sganbold /* Manage Pull-up/pull-down. */ 219256949Sganbold pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN); 220256949Sganbold if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) { 221256949Sganbold if (flags & GPIO_PIN_PULLUP) { 222256949Sganbold pin->gp_flags |= GPIO_PIN_PULLUP; 223256949Sganbold rk30_gpio_set_pud(sc, pin->gp_pin, 224256949Sganbold RK30_GPIO_PULLUP); 225256949Sganbold } else { 226256949Sganbold pin->gp_flags |= GPIO_PIN_PULLDOWN; 227256949Sganbold rk30_gpio_set_pud(sc, pin->gp_pin, 228256949Sganbold RK30_GPIO_PULLDOWN); 229256949Sganbold } 230256949Sganbold } else 231256949Sganbold rk30_gpio_set_pud(sc, pin->gp_pin, RK30_GPIO_NONE); 232256949Sganbold 233256949Sganbold RK30_GPIO_UNLOCK(sc); 234256949Sganbold} 235256949Sganbold 236256949Sganboldstatic int 237256949Sganboldrk30_gpio_pin_max(device_t dev, int *maxpin) 238256949Sganbold{ 239256949Sganbold 240256949Sganbold *maxpin = RK30_GPIO_PINS - 1; 241256949Sganbold return (0); 242256949Sganbold} 243256949Sganbold 244256949Sganboldstatic int 245256949Sganboldrk30_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 246256949Sganbold{ 247256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 248256949Sganbold int i; 249256949Sganbold 250256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 251256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 252256949Sganbold break; 253256949Sganbold } 254256949Sganbold 255256949Sganbold if (i >= sc->sc_gpio_npins) 256256949Sganbold return (EINVAL); 257256949Sganbold 258256949Sganbold RK30_GPIO_LOCK(sc); 259256949Sganbold *caps = sc->sc_gpio_pins[i].gp_caps; 260256949Sganbold RK30_GPIO_UNLOCK(sc); 261256949Sganbold 262256949Sganbold return (0); 263256949Sganbold} 264256949Sganbold 265256949Sganboldstatic int 266256949Sganboldrk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 267256949Sganbold{ 268256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 269256949Sganbold int i; 270256949Sganbold 271256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 272256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 273256949Sganbold break; 274256949Sganbold } 275256949Sganbold 276256949Sganbold if (i >= sc->sc_gpio_npins) 277256949Sganbold return (EINVAL); 278256949Sganbold 279256949Sganbold RK30_GPIO_LOCK(sc); 280256949Sganbold *flags = sc->sc_gpio_pins[i].gp_flags; 281256949Sganbold RK30_GPIO_UNLOCK(sc); 282256949Sganbold 283256949Sganbold return (0); 284256949Sganbold} 285256949Sganbold 286256949Sganboldstatic int 287256949Sganboldrk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 288256949Sganbold{ 289256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 290256949Sganbold int i; 291256949Sganbold 292256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 293256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 294256949Sganbold break; 295256949Sganbold } 296256949Sganbold 297256949Sganbold if (i >= sc->sc_gpio_npins) 298256949Sganbold return (EINVAL); 299256949Sganbold 300256949Sganbold RK30_GPIO_LOCK(sc); 301256949Sganbold memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME); 302256949Sganbold RK30_GPIO_UNLOCK(sc); 303256949Sganbold 304256949Sganbold return (0); 305256949Sganbold} 306256949Sganbold 307256949Sganboldstatic int 308256949Sganboldrk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 309256949Sganbold{ 310256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 311256949Sganbold int i; 312256949Sganbold 313256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 314256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 315256949Sganbold break; 316256949Sganbold } 317256949Sganbold 318256949Sganbold if (i >= sc->sc_gpio_npins) 319256949Sganbold return (EINVAL); 320256949Sganbold 321256949Sganbold rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); 322256949Sganbold 323256949Sganbold return (0); 324256949Sganbold} 325256949Sganbold 326256949Sganboldstatic int 327256949Sganboldrk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 328256949Sganbold{ 329256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 330256949Sganbold uint32_t bank, offset, data; 331256949Sganbold int i; 332256949Sganbold 333256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 334256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 335256949Sganbold break; 336256949Sganbold } 337256949Sganbold 338256949Sganbold if (i >= sc->sc_gpio_npins) 339256949Sganbold return (EINVAL); 340256949Sganbold 341256949Sganbold bank = pin / 32; 342256949Sganbold pin = pin % 32; 343256949Sganbold offset = 1 << pin; 344256949Sganbold 345256949Sganbold RK30_GPIO_LOCK(sc); 346256949Sganbold data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 347256949Sganbold data |= offset; 348256949Sganbold RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); 349256949Sganbold 350256949Sganbold data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); 351256949Sganbold if (value) 352256949Sganbold data |= offset; 353256949Sganbold else 354256949Sganbold data &= ~offset; 355256949Sganbold RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); 356256949Sganbold RK30_GPIO_UNLOCK(sc); 357256949Sganbold 358256949Sganbold return (0); 359256949Sganbold} 360256949Sganbold 361256949Sganboldstatic int 362256949Sganboldrk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 363256949Sganbold{ 364256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 365256949Sganbold uint32_t bank, offset, reg_data; 366256949Sganbold int i; 367256949Sganbold 368256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 369256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 370256949Sganbold break; 371256949Sganbold } 372256949Sganbold 373256949Sganbold if (i >= sc->sc_gpio_npins) 374256949Sganbold return (EINVAL); 375256949Sganbold 376256949Sganbold bank = pin / 32; 377256949Sganbold pin = pin % 32; 378256949Sganbold offset = 1 << pin; 379256949Sganbold 380256949Sganbold RK30_GPIO_LOCK(sc); 381256949Sganbold reg_data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT); 382256949Sganbold RK30_GPIO_UNLOCK(sc); 383256949Sganbold *val = (reg_data & offset) ? 1 : 0; 384256949Sganbold 385256949Sganbold return (0); 386256949Sganbold} 387256949Sganbold 388256949Sganboldstatic int 389256949Sganboldrk30_gpio_pin_toggle(device_t dev, uint32_t pin) 390256949Sganbold{ 391256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 392256949Sganbold uint32_t bank, data, offset; 393256949Sganbold int i; 394256949Sganbold 395256949Sganbold for (i = 0; i < sc->sc_gpio_npins; i++) { 396256949Sganbold if (sc->sc_gpio_pins[i].gp_pin == pin) 397256949Sganbold break; 398256949Sganbold } 399256949Sganbold 400256949Sganbold if (i >= sc->sc_gpio_npins) 401256949Sganbold return (EINVAL); 402256949Sganbold 403256949Sganbold bank = pin / 32; 404256949Sganbold pin = pin % 32; 405256949Sganbold offset = 1 << pin; 406256949Sganbold 407256949Sganbold RK30_GPIO_LOCK(sc); 408256949Sganbold data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); 409256949Sganbold if (data & offset) 410256949Sganbold data &= ~offset; 411256949Sganbold else 412256949Sganbold data |= offset; 413256949Sganbold RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); 414256949Sganbold 415256949Sganbold data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); 416256949Sganbold if (data & offset) 417256949Sganbold data &= ~offset; 418256949Sganbold else 419256949Sganbold data |= offset; 420256949Sganbold RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); 421256949Sganbold RK30_GPIO_UNLOCK(sc); 422256949Sganbold 423256949Sganbold return (0); 424256949Sganbold} 425256949Sganbold 426256949Sganboldstatic int 427256949Sganboldrk30_gpio_probe(device_t dev) 428256949Sganbold{ 429256949Sganbold 430266152Sian if (!ofw_bus_status_okay(dev)) 431266152Sian return (ENXIO); 432266152Sian 433256949Sganbold if (!ofw_bus_is_compatible(dev, "rockchip,rk30xx-gpio")) 434256949Sganbold return (ENXIO); 435256949Sganbold 436256949Sganbold device_set_desc(dev, "Rockchip RK30XX GPIO controller"); 437256949Sganbold return (BUS_PROBE_DEFAULT); 438256949Sganbold} 439256949Sganbold 440256949Sganboldstatic int 441256949Sganboldrk30_gpio_attach(device_t dev) 442256949Sganbold{ 443256949Sganbold struct rk30_gpio_softc *sc = device_get_softc(dev); 444256949Sganbold uint32_t func; 445256949Sganbold int i, rid; 446256949Sganbold phandle_t gpio; 447256949Sganbold 448273650Sian if (rk30_gpio_sc) 449273650Sian return (ENXIO); 450273650Sian 451256949Sganbold sc->sc_dev = dev; 452256949Sganbold 453256949Sganbold mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF); 454256949Sganbold 455256949Sganbold rid = 0; 456256949Sganbold sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 457256949Sganbold RF_ACTIVE); 458256949Sganbold if (!sc->sc_mem_res) { 459256949Sganbold device_printf(dev, "cannot allocate memory window\n"); 460256949Sganbold return (ENXIO); 461256949Sganbold } 462256949Sganbold 463256949Sganbold sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 464256949Sganbold sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 465256949Sganbold 466256949Sganbold rid = 0; 467256949Sganbold sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 468256949Sganbold RF_ACTIVE); 469256949Sganbold if (!sc->sc_irq_res) { 470256949Sganbold bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 471256949Sganbold device_printf(dev, "cannot allocate interrupt\n"); 472256949Sganbold return (ENXIO); 473256949Sganbold } 474256949Sganbold 475256949Sganbold /* Find our node. */ 476256949Sganbold gpio = ofw_bus_get_node(sc->sc_dev); 477256949Sganbold 478256949Sganbold if (!OF_hasprop(gpio, "gpio-controller")) 479256949Sganbold /* Node is not a GPIO controller. */ 480256949Sganbold goto fail; 481256949Sganbold 482256949Sganbold /* Initialize the software controlled pins. */ 483256949Sganbold for (i = 0; i < RK30_GPIO_PINS; i++) { 484256949Sganbold snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, 485256949Sganbold "pin %d", i); 486256949Sganbold func = rk30_gpio_get_function(sc, i); 487256949Sganbold sc->sc_gpio_pins[i].gp_pin = i; 488256949Sganbold sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS; 489256949Sganbold sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func); 490256949Sganbold } 491256949Sganbold sc->sc_gpio_npins = i; 492256949Sganbold 493278782Sloos device_add_child(dev, "gpioc", -1); 494278782Sloos device_add_child(dev, "gpiobus", -1); 495273650Sian 496273650Sian rk30_gpio_sc = sc; 497273650Sian 498273650Sian rk30_gpio_init(); 499273650Sian 500256949Sganbold return (bus_generic_attach(dev)); 501256949Sganbold 502256949Sganboldfail: 503256949Sganbold if (sc->sc_irq_res) 504256949Sganbold bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 505256949Sganbold if (sc->sc_mem_res) 506256949Sganbold bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 507256949Sganbold return (ENXIO); 508256949Sganbold} 509256949Sganbold 510256949Sganboldstatic int 511256949Sganboldrk30_gpio_detach(device_t dev) 512256949Sganbold{ 513256949Sganbold 514256949Sganbold return (EBUSY); 515256949Sganbold} 516256949Sganbold 517256949Sganboldstatic device_method_t rk30_gpio_methods[] = { 518256949Sganbold /* Device interface */ 519256949Sganbold DEVMETHOD(device_probe, rk30_gpio_probe), 520256949Sganbold DEVMETHOD(device_attach, rk30_gpio_attach), 521256949Sganbold DEVMETHOD(device_detach, rk30_gpio_detach), 522256949Sganbold 523256949Sganbold /* GPIO protocol */ 524256949Sganbold DEVMETHOD(gpio_pin_max, rk30_gpio_pin_max), 525256949Sganbold DEVMETHOD(gpio_pin_getname, rk30_gpio_pin_getname), 526256949Sganbold DEVMETHOD(gpio_pin_getflags, rk30_gpio_pin_getflags), 527256949Sganbold DEVMETHOD(gpio_pin_getcaps, rk30_gpio_pin_getcaps), 528256949Sganbold DEVMETHOD(gpio_pin_setflags, rk30_gpio_pin_setflags), 529256949Sganbold DEVMETHOD(gpio_pin_get, rk30_gpio_pin_get), 530256949Sganbold DEVMETHOD(gpio_pin_set, rk30_gpio_pin_set), 531256949Sganbold DEVMETHOD(gpio_pin_toggle, rk30_gpio_pin_toggle), 532256949Sganbold 533256949Sganbold DEVMETHOD_END 534256949Sganbold}; 535256949Sganbold 536256949Sganboldstatic devclass_t rk30_gpio_devclass; 537256949Sganbold 538256949Sganboldstatic driver_t rk30_gpio_driver = { 539256949Sganbold "gpio", 540256949Sganbold rk30_gpio_methods, 541256949Sganbold sizeof(struct rk30_gpio_softc), 542256949Sganbold}; 543256949Sganbold 544256949SganboldDRIVER_MODULE(rk30_gpio, simplebus, rk30_gpio_driver, rk30_gpio_devclass, 0, 0); 545273650Sian 546273650Sianint 547273650Sianrk30_gpios_prop_handle(phandle_t ctrl, pcell_t *gpios, int len) 548273650Sian{ 549273650Sian struct rk30_gpio_softc *sc; 550273650Sian pcell_t gpio_cells; 551273650Sian int inc, t, tuples, tuple_size; 552273650Sian int dir, flags, pin, i; 553273650Sian u_long gpio_ctrl, size; 554273650Sian 555273650Sian sc = rk30_gpio_sc; 556273650Sian if (sc == NULL) 557273650Sian return ENXIO; 558273650Sian 559273650Sian if (OF_getprop(ctrl, "#gpio-cells", &gpio_cells, sizeof(pcell_t)) < 0) 560273650Sian return (ENXIO); 561273650Sian 562273650Sian gpio_cells = fdt32_to_cpu(gpio_cells); 563273650Sian if (gpio_cells != 2) 564273650Sian return (ENXIO); 565273650Sian 566273650Sian tuple_size = gpio_cells * sizeof(pcell_t) + sizeof(phandle_t); 567273650Sian tuples = len / tuple_size; 568273650Sian 569273650Sian if (fdt_regsize(ctrl, &gpio_ctrl, &size)) 570273650Sian return (ENXIO); 571273650Sian 572273650Sian /* 573273650Sian * Skip controller reference, since controller's phandle is given 574273650Sian * explicitly (in a function argument). 575273650Sian */ 576273650Sian inc = sizeof(ihandle_t) / sizeof(pcell_t); 577273650Sian gpios += inc; 578273650Sian for (t = 0; t < tuples; t++) { 579273650Sian pin = fdt32_to_cpu(gpios[0]); 580273650Sian dir = fdt32_to_cpu(gpios[1]); 581273650Sian flags = fdt32_to_cpu(gpios[2]); 582273650Sian 583273650Sian for (i = 0; i < sc->sc_gpio_npins; i++) { 584273650Sian if (sc->sc_gpio_pins[i].gp_pin == pin) 585273650Sian break; 586273650Sian } 587273650Sian if (i >= sc->sc_gpio_npins) 588273650Sian return (EINVAL); 589273650Sian 590273650Sian rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); 591273650Sian 592273650Sian if (dir == 1) { 593273650Sian /* Input. */ 594273650Sian rk30_gpio_pin_set(sc->sc_dev, pin, RK30_GPIO_INPUT); 595273650Sian } else { 596273650Sian /* Output. */ 597273650Sian rk30_gpio_pin_set(sc->sc_dev, pin, RK30_GPIO_OUTPUT); 598273650Sian } 599273650Sian gpios += gpio_cells + inc; 600273650Sian } 601273650Sian 602273650Sian return (0); 603273650Sian} 604273650Sian 605273650Sian#define MAX_PINS_PER_NODE 5 606273650Sian#define GPIOS_PROP_CELLS 4 607273650Sian 608273650Sianstatic int 609273650Sianrk30_gpio_init(void) 610273650Sian{ 611273650Sian phandle_t child, parent, root, ctrl; 612273650Sian pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS]; 613273650Sian struct gpio_ctrl_entry *e; 614273650Sian int len, rv; 615273650Sian 616273650Sian root = OF_finddevice("/"); 617273650Sian len = 0; 618273650Sian parent = root; 619273650Sian 620273650Sian /* Traverse through entire tree to find nodes with 'gpios' prop */ 621273650Sian for (child = OF_child(parent); child != 0; child = OF_peer(child)) { 622273650Sian 623273650Sian /* Find a 'leaf'. Start the search from this node. */ 624273650Sian while (OF_child(child)) { 625273650Sian parent = child; 626273650Sian child = OF_child(child); 627273650Sian } 628273650Sian if ((len = OF_getproplen(child, "gpios")) > 0) { 629273650Sian 630273650Sian if (len > sizeof(gpios)) 631273650Sian return (ENXIO); 632273650Sian 633273650Sian /* Get 'gpios' property. */ 634273650Sian OF_getprop(child, "gpios", &gpios, len); 635273650Sian 636273650Sian e = (struct gpio_ctrl_entry *)&gpio_controllers; 637273650Sian 638273650Sian /* Find and call a handler. */ 639273650Sian for (; e->compat; e++) { 640273650Sian /* 641273650Sian * First cell of 'gpios' property should 642273650Sian * contain a ref. to a node defining GPIO 643273650Sian * controller. 644273650Sian */ 645273652Sian ctrl = OF_node_from_xref(fdt32_to_cpu(gpios[0])); 646273650Sian 647273650Sian if (fdt_is_compatible(ctrl, e->compat)) 648273650Sian /* Call a handler. */ 649273650Sian if ((rv = e->handler(ctrl, 650273650Sian (pcell_t *)&gpios, len))) 651273650Sian return (rv); 652273650Sian } 653273650Sian } 654273650Sian 655273650Sian if (OF_peer(child) == 0) { 656273650Sian /* No more siblings. */ 657273650Sian child = parent; 658273650Sian parent = OF_parent(child); 659273650Sian } 660273650Sian } 661273650Sian return (0); 662273650Sian} 663