1/*- 2 * Copyright (c) 2010-2011, Aleksandr Rybalko <ray@ddteam.net> 3 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 4 * Copyright (c) 2009, 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 unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * GPIO driver for RT305X SoC. 32 */ 33 34#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2010-2011, Aleksandr Rybalko <ray@ddteam.net> 3 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 4 * Copyright (c) 2009, 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 unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * GPIO driver for RT305X SoC. 32 */ 33 34#include <sys/cdefs.h>
|
36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/bus.h> 40 41#include <sys/kernel.h> 42#include <sys/module.h> 43#include <sys/rman.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46#include <sys/gpio.h> 47 48#include <machine/bus.h> 49#include <machine/resource.h> 50#include <mips/rt305x/rt305xreg.h> 51#include <mips/rt305x/rt305x_gpio.h> 52#include <mips/rt305x/rt305x_gpiovar.h> 53#include <mips/rt305x/rt305x_sysctlvar.h> 54 55#include "gpio_if.h" 56 57#ifdef notyet 58#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | \ 59 GPIO_PIN_INVOUT | GPIO_PIN_REPORT ) 60#else 61#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | \ 62 GPIO_PIN_INVOUT ) 63#endif 64 65/* 66 * Helpers 67 */ 68static void rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc, 69 struct gpio_pin *pin, uint32_t flags); 70 71/* 72 * Driver stuff 73 */ 74static int rt305x_gpio_probe(device_t dev); 75static int rt305x_gpio_attach(device_t dev); 76static int rt305x_gpio_detach(device_t dev); 77static int rt305x_gpio_intr(void *arg); 78 79int rt305x_get_int_mask (device_t); 80void rt305x_set_int_mask (device_t, uint32_t); 81int rt305x_get_int_status(device_t); 82void rt305x_set_int_status(device_t, uint32_t); 83 84/* 85 * GPIO interface 86 */ 87static int rt305x_gpio_pin_max(device_t dev, int *maxpin); 88static int rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); 89static int rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t 90 *flags); 91static int rt305x_gpio_pin_getname(device_t dev, uint32_t pin, char *name); 92static int rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags); 93static int rt305x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); 94static int rt305x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val); 95static int rt305x_gpio_pin_toggle(device_t dev, uint32_t pin); 96 97static void 98rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc, struct gpio_pin *pin, 99 unsigned int flags) 100{ 101 GPIO_LOCK(sc); 102 103 /* 104 * Manage input/output 105 */ 106 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 107 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 108 if (flags & GPIO_PIN_OUTPUT) { 109 pin->gp_flags |= GPIO_PIN_OUTPUT; 110 GPIO_BIT_SET(sc, pin->gp_pin, DIR); 111 } 112 else { 113 pin->gp_flags |= GPIO_PIN_INPUT; 114 GPIO_BIT_CLR(sc, pin->gp_pin, DIR); 115 } 116 } 117 118 if (flags & GPIO_PIN_INVOUT) { 119 pin->gp_flags |= GPIO_PIN_INVOUT; 120 GPIO_BIT_SET(sc, pin->gp_pin, POL); 121 } 122 else { 123 pin->gp_flags &= ~GPIO_PIN_INVOUT; 124 GPIO_BIT_CLR(sc, pin->gp_pin, POL); 125 } 126 127 if (flags & GPIO_PIN_INVIN) { 128 pin->gp_flags |= GPIO_PIN_INVIN; 129 GPIO_BIT_SET(sc, pin->gp_pin, POL); 130 } 131 else { 132 pin->gp_flags &= ~GPIO_PIN_INVIN; 133 GPIO_BIT_CLR(sc, pin->gp_pin, POL); 134 } 135 136#ifdef notyet 137 /* Enable interrupt bits for rising/falling transitions */ 138 if (flags & GPIO_PIN_REPORT) { 139 pin->gp_flags |= GPIO_PIN_REPORT; 140 GPIO_BIT_SET(sc, pin->gp_pin, RENA); 141 GPIO_BIT_SET(sc, pin->gp_pin, FENA); 142 device_printf(sc->dev, "Will report interrupt on pin %d\n", 143 pin->gp_pin); 144 145 } 146 else { 147 pin->gp_flags &= ~GPIO_PIN_REPORT; 148 GPIO_BIT_CLR(sc, pin->gp_pin, RENA); 149 GPIO_BIT_CLR(sc, pin->gp_pin, FENA); 150 } 151#else 152 /* Disable generating interrupts for now */ 153 GPIO_BIT_CLR(sc, pin->gp_pin, RENA); 154 GPIO_BIT_CLR(sc, pin->gp_pin, FENA); 155#endif 156 157 GPIO_UNLOCK(sc); 158} 159 160static int 161rt305x_gpio_pin_max(device_t dev, int *maxpin) 162{ 163 164 *maxpin = NGPIO - 1; 165 return (0); 166} 167 168static int 169rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 170{ 171 struct rt305x_gpio_softc *sc = device_get_softc(dev); 172 int i; 173 174 for (i = 0; i < sc->gpio_npins; i++) { 175 if (sc->gpio_pins[i].gp_pin == pin) 176 break; 177 } 178 179 if (i >= sc->gpio_npins) 180 return (EINVAL); 181 182 GPIO_LOCK(sc); 183 *caps = sc->gpio_pins[i].gp_caps; 184 GPIO_UNLOCK(sc); 185 186 return (0); 187} 188 189static int 190rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 191{ 192 struct rt305x_gpio_softc *sc = device_get_softc(dev); 193 int i; 194 195 for (i = 0; i < sc->gpio_npins; i++) { 196 if (sc->gpio_pins[i].gp_pin == pin) 197 break; 198 } 199 200 if (i >= sc->gpio_npins) 201 return (EINVAL); 202 203 GPIO_LOCK(sc); 204 *flags = sc->gpio_pins[i].gp_flags; 205 GPIO_UNLOCK(sc); 206 207 return (0); 208} 209 210static int 211rt305x_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 212{ 213 struct rt305x_gpio_softc *sc = device_get_softc(dev); 214 int i; 215 216 for (i = 0; i < sc->gpio_npins; i++) { 217 if (sc->gpio_pins[i].gp_pin == pin) 218 break; 219 } 220 221 if (i >= sc->gpio_npins) 222 return (EINVAL); 223 224 GPIO_LOCK(sc); 225 memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); 226 GPIO_UNLOCK(sc); 227 228 return (0); 229} 230 231static int 232rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 233{ 234 int i; 235 struct rt305x_gpio_softc *sc = device_get_softc(dev); 236 237 for (i = 0; i < sc->gpio_npins; i++) { 238 if (sc->gpio_pins[i].gp_pin == pin) 239 break; 240 } 241 242 if (i >= sc->gpio_npins) 243 return (EINVAL); 244
| 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/bus.h> 40 41#include <sys/kernel.h> 42#include <sys/module.h> 43#include <sys/rman.h> 44#include <sys/lock.h> 45#include <sys/mutex.h> 46#include <sys/gpio.h> 47 48#include <machine/bus.h> 49#include <machine/resource.h> 50#include <mips/rt305x/rt305xreg.h> 51#include <mips/rt305x/rt305x_gpio.h> 52#include <mips/rt305x/rt305x_gpiovar.h> 53#include <mips/rt305x/rt305x_sysctlvar.h> 54 55#include "gpio_if.h" 56 57#ifdef notyet 58#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | \ 59 GPIO_PIN_INVOUT | GPIO_PIN_REPORT ) 60#else 61#define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INVIN | \ 62 GPIO_PIN_INVOUT ) 63#endif 64 65/* 66 * Helpers 67 */ 68static void rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc, 69 struct gpio_pin *pin, uint32_t flags); 70 71/* 72 * Driver stuff 73 */ 74static int rt305x_gpio_probe(device_t dev); 75static int rt305x_gpio_attach(device_t dev); 76static int rt305x_gpio_detach(device_t dev); 77static int rt305x_gpio_intr(void *arg); 78 79int rt305x_get_int_mask (device_t); 80void rt305x_set_int_mask (device_t, uint32_t); 81int rt305x_get_int_status(device_t); 82void rt305x_set_int_status(device_t, uint32_t); 83 84/* 85 * GPIO interface 86 */ 87static int rt305x_gpio_pin_max(device_t dev, int *maxpin); 88static int rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); 89static int rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t 90 *flags); 91static int rt305x_gpio_pin_getname(device_t dev, uint32_t pin, char *name); 92static int rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags); 93static int rt305x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); 94static int rt305x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val); 95static int rt305x_gpio_pin_toggle(device_t dev, uint32_t pin); 96 97static void 98rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc, struct gpio_pin *pin, 99 unsigned int flags) 100{ 101 GPIO_LOCK(sc); 102 103 /* 104 * Manage input/output 105 */ 106 if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { 107 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); 108 if (flags & GPIO_PIN_OUTPUT) { 109 pin->gp_flags |= GPIO_PIN_OUTPUT; 110 GPIO_BIT_SET(sc, pin->gp_pin, DIR); 111 } 112 else { 113 pin->gp_flags |= GPIO_PIN_INPUT; 114 GPIO_BIT_CLR(sc, pin->gp_pin, DIR); 115 } 116 } 117 118 if (flags & GPIO_PIN_INVOUT) { 119 pin->gp_flags |= GPIO_PIN_INVOUT; 120 GPIO_BIT_SET(sc, pin->gp_pin, POL); 121 } 122 else { 123 pin->gp_flags &= ~GPIO_PIN_INVOUT; 124 GPIO_BIT_CLR(sc, pin->gp_pin, POL); 125 } 126 127 if (flags & GPIO_PIN_INVIN) { 128 pin->gp_flags |= GPIO_PIN_INVIN; 129 GPIO_BIT_SET(sc, pin->gp_pin, POL); 130 } 131 else { 132 pin->gp_flags &= ~GPIO_PIN_INVIN; 133 GPIO_BIT_CLR(sc, pin->gp_pin, POL); 134 } 135 136#ifdef notyet 137 /* Enable interrupt bits for rising/falling transitions */ 138 if (flags & GPIO_PIN_REPORT) { 139 pin->gp_flags |= GPIO_PIN_REPORT; 140 GPIO_BIT_SET(sc, pin->gp_pin, RENA); 141 GPIO_BIT_SET(sc, pin->gp_pin, FENA); 142 device_printf(sc->dev, "Will report interrupt on pin %d\n", 143 pin->gp_pin); 144 145 } 146 else { 147 pin->gp_flags &= ~GPIO_PIN_REPORT; 148 GPIO_BIT_CLR(sc, pin->gp_pin, RENA); 149 GPIO_BIT_CLR(sc, pin->gp_pin, FENA); 150 } 151#else 152 /* Disable generating interrupts for now */ 153 GPIO_BIT_CLR(sc, pin->gp_pin, RENA); 154 GPIO_BIT_CLR(sc, pin->gp_pin, FENA); 155#endif 156 157 GPIO_UNLOCK(sc); 158} 159 160static int 161rt305x_gpio_pin_max(device_t dev, int *maxpin) 162{ 163 164 *maxpin = NGPIO - 1; 165 return (0); 166} 167 168static int 169rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 170{ 171 struct rt305x_gpio_softc *sc = device_get_softc(dev); 172 int i; 173 174 for (i = 0; i < sc->gpio_npins; i++) { 175 if (sc->gpio_pins[i].gp_pin == pin) 176 break; 177 } 178 179 if (i >= sc->gpio_npins) 180 return (EINVAL); 181 182 GPIO_LOCK(sc); 183 *caps = sc->gpio_pins[i].gp_caps; 184 GPIO_UNLOCK(sc); 185 186 return (0); 187} 188 189static int 190rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 191{ 192 struct rt305x_gpio_softc *sc = device_get_softc(dev); 193 int i; 194 195 for (i = 0; i < sc->gpio_npins; i++) { 196 if (sc->gpio_pins[i].gp_pin == pin) 197 break; 198 } 199 200 if (i >= sc->gpio_npins) 201 return (EINVAL); 202 203 GPIO_LOCK(sc); 204 *flags = sc->gpio_pins[i].gp_flags; 205 GPIO_UNLOCK(sc); 206 207 return (0); 208} 209 210static int 211rt305x_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 212{ 213 struct rt305x_gpio_softc *sc = device_get_softc(dev); 214 int i; 215 216 for (i = 0; i < sc->gpio_npins; i++) { 217 if (sc->gpio_pins[i].gp_pin == pin) 218 break; 219 } 220 221 if (i >= sc->gpio_npins) 222 return (EINVAL); 223 224 GPIO_LOCK(sc); 225 memcpy(name, sc->gpio_pins[i].gp_name, GPIOMAXNAME); 226 GPIO_UNLOCK(sc); 227 228 return (0); 229} 230 231static int 232rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 233{ 234 int i; 235 struct rt305x_gpio_softc *sc = device_get_softc(dev); 236 237 for (i = 0; i < sc->gpio_npins; i++) { 238 if (sc->gpio_pins[i].gp_pin == pin) 239 break; 240 } 241 242 if (i >= sc->gpio_npins) 243 return (EINVAL); 244
|
257 return (0); 258} 259 260static int 261rt305x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 262{ 263 struct rt305x_gpio_softc *sc = device_get_softc(dev); 264 int i; 265 266 for (i = 0; i < sc->gpio_npins; i++) { 267 if (sc->gpio_pins[i].gp_pin == pin) 268 break; 269 } 270 271 if (i >= sc->gpio_npins) 272 return (EINVAL); 273 274 275 GPIO_LOCK(sc); 276 if (value) GPIO_BIT_SET(sc, i, DATA); 277 else GPIO_BIT_CLR(sc, i, DATA); 278 GPIO_UNLOCK(sc); 279 280 return (0); 281} 282 283static int 284rt305x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 285{ 286 struct rt305x_gpio_softc *sc = device_get_softc(dev); 287 int i; 288 289 for (i = 0; i < sc->gpio_npins; i++) { 290 if (sc->gpio_pins[i].gp_pin == pin) 291 break; 292 } 293 294 if (i >= sc->gpio_npins) 295 return (EINVAL); 296 297 GPIO_LOCK(sc); 298 *val = GPIO_BIT_GET(sc, i, DATA); 299 GPIO_UNLOCK(sc); 300 301 return (0); 302} 303 304static int 305rt305x_gpio_pin_toggle(device_t dev, uint32_t pin) 306{ 307 int i; 308 struct rt305x_gpio_softc *sc = device_get_softc(dev); 309 310 for (i = 0; i < sc->gpio_npins; i++) { 311 if (sc->gpio_pins[i].gp_pin == pin) 312 break; 313 } 314 315 if (i >= sc->gpio_npins) 316 return (EINVAL); 317 318 GPIO_LOCK(sc); 319 GPIO_BIT_SET(sc, i, TOG); 320 GPIO_UNLOCK(sc); 321 322 return (0); 323} 324 325static int 326rt305x_gpio_intr(void *arg) 327{ 328 struct rt305x_gpio_softc *sc = arg; 329#ifdef notyet 330 uint32_t i; 331#endif 332 uint64_t input, value; 333#ifdef notyet 334 uint64_t reset_pin; 335 char notify[16]; 336 char pinname[6]; 337#endif 338 339 /* Read all reported pins */ 340 input = GPIO_READ_ALL(sc, INT); 341 /* Clear int status */ 342 GPIO_WRITE_ALL(sc, INT, input); 343 /* Clear report for OUTs */ 344 input &= ~GPIO_READ_ALL(sc, DIR); 345 value = input & GPIO_READ_ALL(sc, DATA); 346 347 if (!input) goto intr_done; 348 349#ifdef notyet 350 /* if reset_gpio and this pin is input */ 351 if (sc->reset_gpio >= 0 && (input & (1 << sc->reset_gpio))) { 352 /* get reset_gpio pin value */ 353 reset_pin = (value & (1 << sc->reset_gpio))?1:0; 354 if ( sc->reset_gpio_last != reset_pin ) { 355 /* 356 * if now reset is high, check how long 357 * and do reset if less than 2 seconds 358 */ 359 if ( reset_pin && 360 (time_uptime - sc->reset_gpio_ontime) < 2 ) 361 shutdown_nice(0); 362 363 sc->reset_gpio_last = reset_pin; 364 sc->reset_gpio_ontime = time_uptime; 365 } 366 } 367 368 for ( i = 0; i < NGPIO; i ++ ) 369 { 370 /* Next if output pin */ 371 if ( !(( input >> i) & 1) ) continue; 372 373 if ( (((value & input) >> i) & 1) != sc->gpio_pins[i].gp_last ) 374 { 375 /* !system=GPIO subsystem=pin7 type=PIN_HIGH period=3 */ 376 snprintf(notify , sizeof(notify ), "period=%d", 377 (uint32_t)time_uptime - sc->gpio_pins[i].gp_time); 378 snprintf(pinname, sizeof(pinname), "pin%02d", i); 379 devctl_notify("GPIO", pinname, 380 (((value & input) >> i) & 1)?"PIN_HIGH":"PIN_LOW", 381 notify); 382 printf("GPIO[%s] %s %s\n", pinname, 383 (((value & input) >> i) & 1)?"PIN_HIGH":"PIN_LOW", 384 notify); 385 sc->gpio_pins[i].gp_last = ((value & input) >> i) & 1; 386 sc->gpio_pins[i].gp_time = time_uptime; 387 } 388 389 } 390#endif 391 392intr_done: 393 return (FILTER_HANDLED); 394} 395 396static int 397rt305x_gpio_probe(device_t dev) 398{ 399 device_set_desc(dev, "RT305X GPIO driver"); 400 return (0); 401} 402 403static uint64_t 404rt305x_gpio_init(device_t dev) 405{ 406 uint64_t avl = ~0ULL; 407 uint32_t gmode = rt305x_sysctl_get(SYSCTL_GPIOMODE); 408 if (!(gmode & SYSCTL_GPIOMODE_RGMII_GPIO_MODE)) 409 avl &= ~RGMII_GPIO_MODE_MASK; 410 if (!(gmode & SYSCTL_GPIOMODE_SDRAM_GPIO_MODE)) 411 avl &= ~SDRAM_GPIO_MODE_MASK; 412 if (!(gmode & SYSCTL_GPIOMODE_MDIO_GPIO_MODE)) 413 avl &= ~MDIO_GPIO_MODE_MASK; 414 if (!(gmode & SYSCTL_GPIOMODE_JTAG_GPIO_MODE)) 415 avl &= ~JTAG_GPIO_MODE_MASK; 416 if (!(gmode & SYSCTL_GPIOMODE_UARTL_GPIO_MODE)) 417 avl &= ~UARTL_GPIO_MODE_MASK; 418 if (!(gmode & SYSCTL_GPIOMODE_SPI_GPIO_MODE)) 419 avl &= ~SPI_GPIO_MODE_MASK; 420 if (!(gmode & SYSCTL_GPIOMODE_I2C_GPIO_MODE)) 421 avl &= ~I2C_GPIO_MODE_MASK; 422 if ((gmode & SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO) != 423 SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO) 424 avl &= ~I2C_GPIO_MODE_MASK; 425/* D-Link DAP-1350 Board have 426 * MDIO_GPIO_MODE 427 * UARTF_GPIO_MODE 428 * SPI_GPIO_MODE 429 * I2C_GPIO_MODE 430 * So we have 431 * 00000001 10000000 01111111 11111110 432*/ 433 return (avl); 434 435} 436 437#define DAP1350_RESET_GPIO 10 438 439static int 440rt305x_gpio_attach(device_t dev) 441{ 442 struct rt305x_gpio_softc *sc = device_get_softc(dev); 443 int error = 0, i; 444 uint64_t avlpins = 0; 445 sc->reset_gpio = DAP1350_RESET_GPIO; 446 447 KASSERT((device_get_unit(dev) == 0), 448 ("rt305x_gpio_gpio: Only one gpio module supported")); 449 450 mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 451 452 /* Map control/status registers. */ 453 sc->gpio_mem_rid = 0; 454 sc->gpio_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 455 &sc->gpio_mem_rid, RF_ACTIVE); 456 457 if (sc->gpio_mem_res == NULL) { 458 device_printf(dev, "couldn't map memory\n"); 459 error = ENXIO; 460 rt305x_gpio_detach(dev); 461 return(error); 462 } 463 464 if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 465 &sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 466 device_printf(dev, "unable to allocate IRQ resource\n"); 467 return (ENXIO); 468 } 469 470 if ((bus_setup_intr(dev, sc->gpio_irq_res, INTR_TYPE_MISC, 471 /* rt305x_gpio_filter, */ 472 rt305x_gpio_intr, NULL, sc, &sc->gpio_ih))) { 473 device_printf(dev, 474 "WARNING: unable to register interrupt handler\n"); 475 return (ENXIO); 476 } 477 478 sc->dev = dev; 479 avlpins = rt305x_gpio_init(dev); 480 481 /* Configure all pins as input */ 482 /* disable interrupts for all pins */ 483 /* TODO */ 484 485 sc->gpio_npins = NGPIO; 486 resource_int_value(device_get_name(dev), device_get_unit(dev), 487 "pins", &sc->gpio_npins); 488 489 for (i = 0; i < sc->gpio_npins; i++) { 490 sc->gpio_pins[i].gp_pin = i; 491 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 492 sc->gpio_pins[i].gp_flags = 0; 493 } 494 495 /* Setup reset pin interrupt */ 496 if (TUNABLE_INT_FETCH("reset_gpio", &sc->reset_gpio)) { 497 device_printf(dev, "\tHinted reset_gpio %d\n", sc->reset_gpio); 498 } 499#ifdef notyet 500 if (sc->reset_gpio != -1) { 501 rt305x_gpio_pin_setflags(dev, sc->reset_gpio, 502 GPIO_PIN_INPUT|GPIO_PIN_INVOUT| 503 GPIO_PIN_INVOUT|GPIO_PIN_REPORT); 504 device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio); 505 } 506#else 507 if (sc->reset_gpio != -1) { 508 rt305x_gpio_pin_setflags(dev, sc->reset_gpio, 509 GPIO_PIN_INPUT|GPIO_PIN_INVOUT); 510 device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio); 511 } 512#endif 513 514 device_add_child(dev, "gpioc", -1); 515 device_add_child(dev, "gpiobus", -1); 516 517 return (bus_generic_attach(dev)); 518} 519 520static int 521rt305x_gpio_detach(device_t dev) 522{ 523 struct rt305x_gpio_softc *sc = device_get_softc(dev); 524 525 KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); 526 527 bus_generic_detach(dev); 528 529 if (sc->gpio_mem_res) 530 bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid, 531 sc->gpio_mem_res); 532 533 mtx_destroy(&sc->gpio_mtx); 534 535 return(0); 536} 537 538#ifdef notyet 539static struct resource * 540rt305x_gpio_alloc_resource(device_t bus, device_t child, int type, int *rid, 541 u_long start, u_long end, u_long count, u_int flags) 542{ 543 struct obio_softc *sc = device_get_softc(bus); 544 struct resource *rv; 545 struct rman *rm; 546 547 switch (type) { 548 case SYS_RES_GPIO: 549 rm = &sc->gpio_rman; 550 break; 551 default: 552 printf("%s: unknown resource type %d\n", __func__, type); 553 return (0); 554 } 555 556 rv = rman_reserve_resource(rm, start, end, count, flags, child); 557 if (rv == 0) { 558 printf("%s: could not reserve resource\n", __func__); 559 return (0); 560 } 561 562 rman_set_rid(rv, *rid); 563 564 return (rv); 565} 566 567static int 568rt305x_gpio_activate_resource(device_t bus, device_t child, int type, int rid, 569 struct resource *r) 570{ 571 572 return (rman_activate_resource(r)); 573} 574 575static int 576rt305x_gpio_deactivate_resource(device_t bus, device_t child, int type, int rid, 577 struct resource *r) 578{ 579 580 return (rman_deactivate_resource(r)); 581} 582 583static int 584rt305x_gpio_release_resource(device_t dev, device_t child, int type, 585 int rid, struct resource *r) 586{ 587 rman_release_resource(r); 588 return (0); 589} 590#endif 591 592static device_method_t rt305x_gpio_methods[] = { 593 DEVMETHOD(device_probe, rt305x_gpio_probe), 594 DEVMETHOD(device_attach, rt305x_gpio_attach), 595 DEVMETHOD(device_detach, rt305x_gpio_detach), 596 597 /* GPIO protocol */ 598 DEVMETHOD(gpio_pin_max, rt305x_gpio_pin_max), 599 DEVMETHOD(gpio_pin_getname, rt305x_gpio_pin_getname), 600 DEVMETHOD(gpio_pin_getflags, rt305x_gpio_pin_getflags), 601 DEVMETHOD(gpio_pin_getcaps, rt305x_gpio_pin_getcaps), 602 DEVMETHOD(gpio_pin_setflags, rt305x_gpio_pin_setflags), 603 DEVMETHOD(gpio_pin_get, rt305x_gpio_pin_get), 604 DEVMETHOD(gpio_pin_set, rt305x_gpio_pin_set), 605 DEVMETHOD(gpio_pin_toggle, rt305x_gpio_pin_toggle), 606 {0, 0}, 607}; 608 609static driver_t rt305x_gpio_driver = { 610 "gpio", 611 rt305x_gpio_methods, 612 sizeof(struct rt305x_gpio_softc), 613}; 614static devclass_t rt305x_gpio_devclass; 615 616DRIVER_MODULE(rt305x_gpio, obio, rt305x_gpio_driver, 617 rt305x_gpio_devclass, 0, 0);
| 247 return (0); 248} 249 250static int 251rt305x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 252{ 253 struct rt305x_gpio_softc *sc = device_get_softc(dev); 254 int i; 255 256 for (i = 0; i < sc->gpio_npins; i++) { 257 if (sc->gpio_pins[i].gp_pin == pin) 258 break; 259 } 260 261 if (i >= sc->gpio_npins) 262 return (EINVAL); 263 264 265 GPIO_LOCK(sc); 266 if (value) GPIO_BIT_SET(sc, i, DATA); 267 else GPIO_BIT_CLR(sc, i, DATA); 268 GPIO_UNLOCK(sc); 269 270 return (0); 271} 272 273static int 274rt305x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 275{ 276 struct rt305x_gpio_softc *sc = device_get_softc(dev); 277 int i; 278 279 for (i = 0; i < sc->gpio_npins; i++) { 280 if (sc->gpio_pins[i].gp_pin == pin) 281 break; 282 } 283 284 if (i >= sc->gpio_npins) 285 return (EINVAL); 286 287 GPIO_LOCK(sc); 288 *val = GPIO_BIT_GET(sc, i, DATA); 289 GPIO_UNLOCK(sc); 290 291 return (0); 292} 293 294static int 295rt305x_gpio_pin_toggle(device_t dev, uint32_t pin) 296{ 297 int i; 298 struct rt305x_gpio_softc *sc = device_get_softc(dev); 299 300 for (i = 0; i < sc->gpio_npins; i++) { 301 if (sc->gpio_pins[i].gp_pin == pin) 302 break; 303 } 304 305 if (i >= sc->gpio_npins) 306 return (EINVAL); 307 308 GPIO_LOCK(sc); 309 GPIO_BIT_SET(sc, i, TOG); 310 GPIO_UNLOCK(sc); 311 312 return (0); 313} 314 315static int 316rt305x_gpio_intr(void *arg) 317{ 318 struct rt305x_gpio_softc *sc = arg; 319#ifdef notyet 320 uint32_t i; 321#endif 322 uint64_t input, value; 323#ifdef notyet 324 uint64_t reset_pin; 325 char notify[16]; 326 char pinname[6]; 327#endif 328 329 /* Read all reported pins */ 330 input = GPIO_READ_ALL(sc, INT); 331 /* Clear int status */ 332 GPIO_WRITE_ALL(sc, INT, input); 333 /* Clear report for OUTs */ 334 input &= ~GPIO_READ_ALL(sc, DIR); 335 value = input & GPIO_READ_ALL(sc, DATA); 336 337 if (!input) goto intr_done; 338 339#ifdef notyet 340 /* if reset_gpio and this pin is input */ 341 if (sc->reset_gpio >= 0 && (input & (1 << sc->reset_gpio))) { 342 /* get reset_gpio pin value */ 343 reset_pin = (value & (1 << sc->reset_gpio))?1:0; 344 if ( sc->reset_gpio_last != reset_pin ) { 345 /* 346 * if now reset is high, check how long 347 * and do reset if less than 2 seconds 348 */ 349 if ( reset_pin && 350 (time_uptime - sc->reset_gpio_ontime) < 2 ) 351 shutdown_nice(0); 352 353 sc->reset_gpio_last = reset_pin; 354 sc->reset_gpio_ontime = time_uptime; 355 } 356 } 357 358 for ( i = 0; i < NGPIO; i ++ ) 359 { 360 /* Next if output pin */ 361 if ( !(( input >> i) & 1) ) continue; 362 363 if ( (((value & input) >> i) & 1) != sc->gpio_pins[i].gp_last ) 364 { 365 /* !system=GPIO subsystem=pin7 type=PIN_HIGH period=3 */ 366 snprintf(notify , sizeof(notify ), "period=%d", 367 (uint32_t)time_uptime - sc->gpio_pins[i].gp_time); 368 snprintf(pinname, sizeof(pinname), "pin%02d", i); 369 devctl_notify("GPIO", pinname, 370 (((value & input) >> i) & 1)?"PIN_HIGH":"PIN_LOW", 371 notify); 372 printf("GPIO[%s] %s %s\n", pinname, 373 (((value & input) >> i) & 1)?"PIN_HIGH":"PIN_LOW", 374 notify); 375 sc->gpio_pins[i].gp_last = ((value & input) >> i) & 1; 376 sc->gpio_pins[i].gp_time = time_uptime; 377 } 378 379 } 380#endif 381 382intr_done: 383 return (FILTER_HANDLED); 384} 385 386static int 387rt305x_gpio_probe(device_t dev) 388{ 389 device_set_desc(dev, "RT305X GPIO driver"); 390 return (0); 391} 392 393static uint64_t 394rt305x_gpio_init(device_t dev) 395{ 396 uint64_t avl = ~0ULL; 397 uint32_t gmode = rt305x_sysctl_get(SYSCTL_GPIOMODE); 398 if (!(gmode & SYSCTL_GPIOMODE_RGMII_GPIO_MODE)) 399 avl &= ~RGMII_GPIO_MODE_MASK; 400 if (!(gmode & SYSCTL_GPIOMODE_SDRAM_GPIO_MODE)) 401 avl &= ~SDRAM_GPIO_MODE_MASK; 402 if (!(gmode & SYSCTL_GPIOMODE_MDIO_GPIO_MODE)) 403 avl &= ~MDIO_GPIO_MODE_MASK; 404 if (!(gmode & SYSCTL_GPIOMODE_JTAG_GPIO_MODE)) 405 avl &= ~JTAG_GPIO_MODE_MASK; 406 if (!(gmode & SYSCTL_GPIOMODE_UARTL_GPIO_MODE)) 407 avl &= ~UARTL_GPIO_MODE_MASK; 408 if (!(gmode & SYSCTL_GPIOMODE_SPI_GPIO_MODE)) 409 avl &= ~SPI_GPIO_MODE_MASK; 410 if (!(gmode & SYSCTL_GPIOMODE_I2C_GPIO_MODE)) 411 avl &= ~I2C_GPIO_MODE_MASK; 412 if ((gmode & SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO) != 413 SYSCTL_GPIOMODE_UARTF_SHARE_MODE_GPIO) 414 avl &= ~I2C_GPIO_MODE_MASK; 415/* D-Link DAP-1350 Board have 416 * MDIO_GPIO_MODE 417 * UARTF_GPIO_MODE 418 * SPI_GPIO_MODE 419 * I2C_GPIO_MODE 420 * So we have 421 * 00000001 10000000 01111111 11111110 422*/ 423 return (avl); 424 425} 426 427#define DAP1350_RESET_GPIO 10 428 429static int 430rt305x_gpio_attach(device_t dev) 431{ 432 struct rt305x_gpio_softc *sc = device_get_softc(dev); 433 int error = 0, i; 434 uint64_t avlpins = 0; 435 sc->reset_gpio = DAP1350_RESET_GPIO; 436 437 KASSERT((device_get_unit(dev) == 0), 438 ("rt305x_gpio_gpio: Only one gpio module supported")); 439 440 mtx_init(&sc->gpio_mtx, device_get_nameunit(dev), NULL, MTX_DEF); 441 442 /* Map control/status registers. */ 443 sc->gpio_mem_rid = 0; 444 sc->gpio_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 445 &sc->gpio_mem_rid, RF_ACTIVE); 446 447 if (sc->gpio_mem_res == NULL) { 448 device_printf(dev, "couldn't map memory\n"); 449 error = ENXIO; 450 rt305x_gpio_detach(dev); 451 return(error); 452 } 453 454 if ((sc->gpio_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, 455 &sc->gpio_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 456 device_printf(dev, "unable to allocate IRQ resource\n"); 457 return (ENXIO); 458 } 459 460 if ((bus_setup_intr(dev, sc->gpio_irq_res, INTR_TYPE_MISC, 461 /* rt305x_gpio_filter, */ 462 rt305x_gpio_intr, NULL, sc, &sc->gpio_ih))) { 463 device_printf(dev, 464 "WARNING: unable to register interrupt handler\n"); 465 return (ENXIO); 466 } 467 468 sc->dev = dev; 469 avlpins = rt305x_gpio_init(dev); 470 471 /* Configure all pins as input */ 472 /* disable interrupts for all pins */ 473 /* TODO */ 474 475 sc->gpio_npins = NGPIO; 476 resource_int_value(device_get_name(dev), device_get_unit(dev), 477 "pins", &sc->gpio_npins); 478 479 for (i = 0; i < sc->gpio_npins; i++) { 480 sc->gpio_pins[i].gp_pin = i; 481 sc->gpio_pins[i].gp_caps = DEFAULT_CAPS; 482 sc->gpio_pins[i].gp_flags = 0; 483 } 484 485 /* Setup reset pin interrupt */ 486 if (TUNABLE_INT_FETCH("reset_gpio", &sc->reset_gpio)) { 487 device_printf(dev, "\tHinted reset_gpio %d\n", sc->reset_gpio); 488 } 489#ifdef notyet 490 if (sc->reset_gpio != -1) { 491 rt305x_gpio_pin_setflags(dev, sc->reset_gpio, 492 GPIO_PIN_INPUT|GPIO_PIN_INVOUT| 493 GPIO_PIN_INVOUT|GPIO_PIN_REPORT); 494 device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio); 495 } 496#else 497 if (sc->reset_gpio != -1) { 498 rt305x_gpio_pin_setflags(dev, sc->reset_gpio, 499 GPIO_PIN_INPUT|GPIO_PIN_INVOUT); 500 device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio); 501 } 502#endif 503 504 device_add_child(dev, "gpioc", -1); 505 device_add_child(dev, "gpiobus", -1); 506 507 return (bus_generic_attach(dev)); 508} 509 510static int 511rt305x_gpio_detach(device_t dev) 512{ 513 struct rt305x_gpio_softc *sc = device_get_softc(dev); 514 515 KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); 516 517 bus_generic_detach(dev); 518 519 if (sc->gpio_mem_res) 520 bus_release_resource(dev, SYS_RES_MEMORY, sc->gpio_mem_rid, 521 sc->gpio_mem_res); 522 523 mtx_destroy(&sc->gpio_mtx); 524 525 return(0); 526} 527 528#ifdef notyet 529static struct resource * 530rt305x_gpio_alloc_resource(device_t bus, device_t child, int type, int *rid, 531 u_long start, u_long end, u_long count, u_int flags) 532{ 533 struct obio_softc *sc = device_get_softc(bus); 534 struct resource *rv; 535 struct rman *rm; 536 537 switch (type) { 538 case SYS_RES_GPIO: 539 rm = &sc->gpio_rman; 540 break; 541 default: 542 printf("%s: unknown resource type %d\n", __func__, type); 543 return (0); 544 } 545 546 rv = rman_reserve_resource(rm, start, end, count, flags, child); 547 if (rv == 0) { 548 printf("%s: could not reserve resource\n", __func__); 549 return (0); 550 } 551 552 rman_set_rid(rv, *rid); 553 554 return (rv); 555} 556 557static int 558rt305x_gpio_activate_resource(device_t bus, device_t child, int type, int rid, 559 struct resource *r) 560{ 561 562 return (rman_activate_resource(r)); 563} 564 565static int 566rt305x_gpio_deactivate_resource(device_t bus, device_t child, int type, int rid, 567 struct resource *r) 568{ 569 570 return (rman_deactivate_resource(r)); 571} 572 573static int 574rt305x_gpio_release_resource(device_t dev, device_t child, int type, 575 int rid, struct resource *r) 576{ 577 rman_release_resource(r); 578 return (0); 579} 580#endif 581 582static device_method_t rt305x_gpio_methods[] = { 583 DEVMETHOD(device_probe, rt305x_gpio_probe), 584 DEVMETHOD(device_attach, rt305x_gpio_attach), 585 DEVMETHOD(device_detach, rt305x_gpio_detach), 586 587 /* GPIO protocol */ 588 DEVMETHOD(gpio_pin_max, rt305x_gpio_pin_max), 589 DEVMETHOD(gpio_pin_getname, rt305x_gpio_pin_getname), 590 DEVMETHOD(gpio_pin_getflags, rt305x_gpio_pin_getflags), 591 DEVMETHOD(gpio_pin_getcaps, rt305x_gpio_pin_getcaps), 592 DEVMETHOD(gpio_pin_setflags, rt305x_gpio_pin_setflags), 593 DEVMETHOD(gpio_pin_get, rt305x_gpio_pin_get), 594 DEVMETHOD(gpio_pin_set, rt305x_gpio_pin_set), 595 DEVMETHOD(gpio_pin_toggle, rt305x_gpio_pin_toggle), 596 {0, 0}, 597}; 598 599static driver_t rt305x_gpio_driver = { 600 "gpio", 601 rt305x_gpio_methods, 602 sizeof(struct rt305x_gpio_softc), 603}; 604static devclass_t rt305x_gpio_devclass; 605 606DRIVER_MODULE(rt305x_gpio, obio, rt305x_gpio_driver, 607 rt305x_gpio_devclass, 0, 0);
|