1 /*- 2 * Copyright (c) 2015 Rubicon Communications, LLC (Netgate) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 #include <sys/cdefs.h> 27 __FBSDID("$FreeBSD$"); 28 29 /* 30 * GPIO driver for the ADI Engineering RCC-VE and RCC-DFF/DFFv2. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/bus.h> 36 #include <sys/gpio.h> 37 #include <sys/kernel.h> 38 #include <sys/module.h> 39 #include <sys/rman.h> 40 41 #include <machine/bus.h> 42 43 #include <dev/gpio/gpiobusvar.h> 44 #include <isa/isavar.h> 45 46 #include "gpio_if.h" 47 48 #define RCC_GPIO_BASE 0x500 49 #define RCC_GPIO_USE_SEL 0x00 50 #define RCC_GPIO_IO_SEL 0x04 51 #define RCC_GPIO_GP_LVL 0x08 52 53 struct rcc_gpio_pin { 54 uint32_t pin; 55 const char *name; 56 uint32_t caps; 57 }; 58 59 static struct rcc_gpio_pin rcc_pins[] = { 60 { .pin = 11, .name = "reset switch", .caps = GPIO_PIN_INPUT }, 61 { .pin = 15, .name = "red LED", .caps = GPIO_PIN_OUTPUT }, 62 { .pin = 17, .name = "green LED", .caps = GPIO_PIN_OUTPUT }, 63 #if 0 64 { .pin = 16, .name = "HD1 LED", .caps = GPIO_PIN_OUTPUT }, 65 { .pin = 18, .name = "HD2 LED", .caps = GPIO_PIN_OUTPUT }, 66 #endif 67 }; 68 69 struct rcc_gpio_softc { 70 device_t sc_dev; 71 device_t sc_busdev; 72 struct mtx sc_mtx; 73 struct resource *sc_io_res; 74 bus_space_tag_t sc_bst; 75 bus_space_handle_t sc_bsh; 76 uint32_t sc_output; 77 int sc_io_rid; 78 int sc_gpio_npins; 79 }; 80 81 #define RCC_GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 82 #define RCC_GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 83 #define RCC_WRITE(_sc, _off, _val) \ 84 bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val) 85 #define RCC_READ(_sc, _off) \ 86 bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, _off) 87 88 static void 89 rcc_gpio_modify_bits(struct rcc_gpio_softc *sc, uint32_t reg, uint32_t mask, 90 uint32_t bit) 91 { 92 uint32_t value; 93 94 RCC_GPIO_LOCK(sc); 95 value = RCC_READ(sc, reg); 96 value &= ~(1 << mask); 97 value |= (1 << bit); 98 RCC_WRITE(sc, reg, value); 99 RCC_GPIO_UNLOCK(sc); 100 } 101 102 static device_t 103 rcc_gpio_get_bus(device_t dev) 104 { 105 struct rcc_gpio_softc *sc; 106 107 sc = device_get_softc(dev); 108 109 return (sc->sc_busdev); 110 } 111 112 static int 113 rcc_gpio_pin_max(device_t dev, int *maxpin) 114 { 115 struct rcc_gpio_softc *sc; 116 117 sc = device_get_softc(dev); 118 *maxpin = sc->sc_gpio_npins - 1; 119 120 return (0); 121 } 122 123 static int 124 rcc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 125 { 126 struct rcc_gpio_softc *sc; 127 128 sc = device_get_softc(dev); 129 if (pin > sc->sc_gpio_npins) 130 return (EINVAL); 131 132 *caps = rcc_pins[pin].caps; 133 134 return (0); 135 } 136 137 static int 138 rcc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 139 { 140 struct rcc_gpio_softc *sc; 141 142 sc = device_get_softc(dev); 143 if (pin > sc->sc_gpio_npins) 144 return (EINVAL); 145 146 /* Flags cannot be changed. */ 147 *flags = rcc_pins[pin].caps; 148 149 return (0); 150 } 151 152 static int 153 rcc_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 154 { 155 struct rcc_gpio_softc *sc; 156 157 sc = device_get_softc(dev); 158 if (pin > sc->sc_gpio_npins) 159 return (EINVAL); 160 161 memcpy(name, rcc_pins[pin].name, GPIOMAXNAME); 162 163 return (0); 164 } 165 166 static int 167 rcc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 168 { 169 struct rcc_gpio_softc *sc; 170 171 sc = device_get_softc(dev); 172 if (pin > sc->sc_gpio_npins) 173 return (EINVAL); 174 175 /* Flags cannot be changed - risk of short-circuit!!! */ 176 177 return (0); 178 } 179 180 static int 181 rcc_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 182 { 183 struct rcc_gpio_softc *sc; 184 185 sc = device_get_softc(dev); 186 if (pin > sc->sc_gpio_npins) 187 return (EINVAL); 188 189 RCC_GPIO_LOCK(sc); 190 if (value) 191 sc->sc_output |= (1 << rcc_pins[pin].pin); 192 else 193 sc->sc_output &= ~(1 << rcc_pins[pin].pin); 194 RCC_WRITE(sc, RCC_GPIO_GP_LVL, sc->sc_output); 195 RCC_GPIO_UNLOCK(sc); 196 197 return (0); 198 } 199 200 static int 201 rcc_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 202 { 203 struct rcc_gpio_softc *sc; 204 uint32_t value; 205 206 sc = device_get_softc(dev); 207 if (pin > sc->sc_gpio_npins) 208 return (EINVAL); 209 210 RCC_GPIO_LOCK(sc); 211 if (rcc_pins[pin].caps & GPIO_PIN_INPUT) 212 value = RCC_READ(sc, RCC_GPIO_GP_LVL); 213 else 214 value = sc->sc_output; 215 RCC_GPIO_UNLOCK(sc); 216 *val = (value & (1 << rcc_pins[pin].pin)) ? 1 : 0; 217 218 return (0); 219 } 220 221 static int 222 rcc_gpio_pin_toggle(device_t dev, uint32_t pin) 223 { 224 struct rcc_gpio_softc *sc; 225 226 sc = device_get_softc(dev); 227 if (pin > sc->sc_gpio_npins) 228 return (EINVAL); 229 230 RCC_GPIO_LOCK(sc); 231 if ((sc->sc_output & (1 << rcc_pins[pin].pin)) == 0) 232 sc->sc_output |= (1 << rcc_pins[pin].pin); 233 else 234 sc->sc_output &= ~(1 << rcc_pins[pin].pin); 235 RCC_WRITE(sc, RCC_GPIO_GP_LVL, sc->sc_output); 236 RCC_GPIO_UNLOCK(sc); 237 238 return (0); 239 } 240 241 static int 242 rcc_gpio_probe(device_t dev) 243 { 244 char *prod; 245 int port; 246 247 /* 248 * We don't know of any PnP ID's for this GPIO controller. 249 */ 250 if (isa_get_logicalid(dev) != 0) 251 return (ENXIO); 252 253 /* 254 * We have to have an IO port hint that is valid. 255 */ 256 port = isa_get_port(dev); 257 if (port != RCC_GPIO_BASE) 258 return (ENXIO); 259 260 prod = kern_getenv("smbios.system.product"); 261 if (prod == NULL || 262 (strcmp(prod, "RCC-VE") != 0 && strcmp(prod, "RCC-DFF") != 0)) 263 return (ENXIO); 264 265 device_set_desc(dev, "RCC-VE/DFF GPIO controller"); 266 267 return (BUS_PROBE_DEFAULT); 268 } 269 270 static int 271 rcc_gpio_attach(device_t dev) 272 { 273 int i; 274 struct rcc_gpio_softc *sc; 275 276 sc = device_get_softc(dev); 277 sc->sc_dev = dev; 278 279 /* Allocate IO resources. */ 280 sc->sc_io_rid = 0; 281 sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 282 &sc->sc_io_rid, RF_ACTIVE); 283 if (sc->sc_io_res == NULL) { 284 device_printf(dev, "cannot allocate memory window\n"); 285 return (ENXIO); 286 } 287 sc->sc_bst = rman_get_bustag(sc->sc_io_res); 288 sc->sc_bsh = rman_get_bushandle(sc->sc_io_res); 289 mtx_init(&sc->sc_mtx, "rcc-gpio", "gpio", MTX_DEF); 290 291 /* Initialize the pins. */ 292 sc->sc_gpio_npins = nitems(rcc_pins); 293 for (i = 0; i < sc->sc_gpio_npins; i++) { 294 /* Enable it for GPIO. */ 295 rcc_gpio_modify_bits(sc, RCC_GPIO_USE_SEL, 0, rcc_pins[i].pin); 296 /* Set the pin as input or output. */ 297 if (rcc_pins[i].caps & GPIO_PIN_OUTPUT) 298 rcc_gpio_modify_bits(sc, RCC_GPIO_IO_SEL, 299 rcc_pins[i].pin, 0); 300 else 301 rcc_gpio_modify_bits(sc, RCC_GPIO_IO_SEL, 302 0, rcc_pins[i].pin); 303 } 304 RCC_WRITE(sc, RCC_GPIO_GP_LVL, sc->sc_output); 305 306 /* Attach the gpiobus. */ 307 sc->sc_busdev = gpiobus_attach_bus(dev); 308 if (sc->sc_busdev == NULL) { 309 bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_io_rid, 310 sc->sc_io_res); 311 mtx_destroy(&sc->sc_mtx); 312 return (ENXIO); 313 } 314 315 return (0); 316 } 317 318 static int 319 rcc_gpio_detach(device_t dev) 320 { 321 int i; 322 struct rcc_gpio_softc *sc; 323 324 sc = device_get_softc(dev); 325 gpiobus_detach_bus(dev); 326 327 /* Disable the GPIO function. */ 328 for (i = 0; i < sc->sc_gpio_npins; i++) 329 rcc_gpio_modify_bits(sc, RCC_GPIO_USE_SEL, rcc_pins[i].pin, 0); 330 331 if (sc->sc_io_res != NULL) 332 bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_io_rid, 333 sc->sc_io_res); 334 mtx_destroy(&sc->sc_mtx); 335 336 return (0); 337 } 338 339 static device_method_t rcc_gpio_methods[] = { 340 /* Device interface */ 341 DEVMETHOD(device_probe, rcc_gpio_probe), 342 DEVMETHOD(device_attach, rcc_gpio_attach), 343 DEVMETHOD(device_detach, rcc_gpio_detach), 344 345 /* GPIO protocol */ 346 DEVMETHOD(gpio_get_bus, rcc_gpio_get_bus), 347 DEVMETHOD(gpio_pin_max, rcc_gpio_pin_max), 348 DEVMETHOD(gpio_pin_getname, rcc_gpio_pin_getname), 349 DEVMETHOD(gpio_pin_getflags, rcc_gpio_pin_getflags), 350 DEVMETHOD(gpio_pin_getcaps, rcc_gpio_pin_getcaps), 351 DEVMETHOD(gpio_pin_setflags, rcc_gpio_pin_setflags), 352 DEVMETHOD(gpio_pin_get, rcc_gpio_pin_get), 353 DEVMETHOD(gpio_pin_set, rcc_gpio_pin_set), 354 DEVMETHOD(gpio_pin_toggle, rcc_gpio_pin_toggle), 355 356 DEVMETHOD_END 357 }; 358 359 static devclass_t rcc_gpio_devclass; 360 361 static driver_t rcc_gpio_driver = { 362 "gpio", 363 rcc_gpio_methods, 364 sizeof(struct rcc_gpio_softc), 365 }; 366 367 DRIVER_MODULE(rcc_gpio, isa, rcc_gpio_driver, rcc_gpio_devclass, 0, 0); 368 MODULE_DEPEND(rcc_gpio, gpiobus, 1, 1, 1); 369