1 /*- 2 * Copyright (c) 2020 Alstom Group. 3 * Copyright (c) 2020 Semihalf. 4 * Copyright (c) 2015 Justin Hibbits 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 * $FreeBSD$ 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/conf.h> 37 #include <sys/bus.h> 38 #include <sys/kernel.h> 39 #include <sys/module.h> 40 #include <sys/mutex.h> 41 #include <sys/rman.h> 42 #include <sys/gpio.h> 43 44 #include <machine/bus.h> 45 #include <machine/resource.h> 46 #include <machine/stdarg.h> 47 48 #include <dev/gpio/gpiobusvar.h> 49 #include <dev/ofw/ofw_bus.h> 50 #include <dev/ofw/ofw_bus_subr.h> 51 52 #include "gpio_if.h" 53 54 #define MAXPIN (31) 55 56 #define VALID_PIN(u) ((u) >= 0 && (u) <= MAXPIN) 57 #define DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ 58 GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL) 59 60 #define GPIO_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 61 #define GPIO_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 62 #define GPIO_LOCK_INIT(sc) \ 63 mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->dev), \ 64 "gpio", MTX_DEF) 65 #define GPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 66 67 #define GPIO_GPDIR 0x0 68 #define GPIO_GPODR 0x4 69 #define GPIO_GPDAT 0x8 70 #define GPIO_GPIER 0xc 71 #define GPIO_GPIMR 0x10 72 #define GPIO_GPICR 0x14 73 #define GPIO_GPIBE 0x18 74 75 struct qoriq_gpio_softc { 76 device_t dev; 77 device_t busdev; 78 struct mtx sc_mtx; 79 struct resource *sc_mem; /* Memory resource */ 80 struct gpio_pin sc_pins[MAXPIN + 1]; 81 }; 82 83 static device_t 84 qoriq_gpio_get_bus(device_t dev) 85 { 86 struct qoriq_gpio_softc *sc; 87 88 sc = device_get_softc(dev); 89 90 return (sc->busdev); 91 } 92 93 static int 94 qoriq_gpio_pin_max(device_t dev, int *maxpin) 95 { 96 97 *maxpin = MAXPIN; 98 return (0); 99 } 100 101 /* Get a specific pin's capabilities. */ 102 static int 103 qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 104 { 105 struct qoriq_gpio_softc *sc; 106 107 sc = device_get_softc(dev); 108 109 if (!VALID_PIN(pin)) 110 return (EINVAL); 111 112 GPIO_LOCK(sc); 113 *caps = sc->sc_pins[pin].gp_caps; 114 GPIO_UNLOCK(sc); 115 116 return (0); 117 } 118 119 /* Get a specific pin's name. */ 120 static int 121 qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 122 { 123 124 if (!VALID_PIN(pin)) 125 return (EINVAL); 126 127 snprintf(name, GPIOMAXNAME, "qoriq_gpio%d.%d", 128 device_get_unit(dev), pin); 129 name[GPIOMAXNAME-1] = '\0'; 130 131 return (0); 132 } 133 134 /* Set flags for the pin. */ 135 static int 136 qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 137 { 138 struct qoriq_gpio_softc *sc = device_get_softc(dev); 139 uint32_t reg; 140 141 if (!VALID_PIN(pin)) 142 return (EINVAL); 143 144 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 145 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) 146 return (EINVAL); 147 148 GPIO_LOCK(sc); 149 if ((flags & sc->sc_pins[pin].gp_caps) != flags) { 150 GPIO_UNLOCK(sc); 151 return (EINVAL); 152 } 153 154 if (flags & GPIO_PIN_INPUT) { 155 reg = bus_read_4(sc->sc_mem, GPIO_GPDIR); 156 reg &= ~(1 << (31 - pin)); 157 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg); 158 } 159 else if (flags & GPIO_PIN_OUTPUT) { 160 reg = bus_read_4(sc->sc_mem, GPIO_GPDIR); 161 reg |= (1 << (31 - pin)); 162 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg); 163 reg = bus_read_4(sc->sc_mem, GPIO_GPODR); 164 if (flags & GPIO_PIN_OPENDRAIN) 165 reg |= (1 << (31 - pin)); 166 else 167 reg &= ~(1 << (31 - pin)); 168 bus_write_4(sc->sc_mem, GPIO_GPODR, reg); 169 } 170 sc->sc_pins[pin].gp_flags = flags; 171 GPIO_UNLOCK(sc); 172 return (0); 173 } 174 175 static int 176 qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags) 177 { 178 struct qoriq_gpio_softc *sc; 179 180 if (!VALID_PIN(pin)) 181 return (EINVAL); 182 183 sc = device_get_softc(dev); 184 185 GPIO_LOCK(sc); 186 *pflags = sc->sc_pins[pin].gp_flags; 187 GPIO_UNLOCK(sc); 188 189 return (0); 190 } 191 192 /* Set a specific output pin's value. */ 193 static int 194 qoriq_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) 195 { 196 struct qoriq_gpio_softc *sc = device_get_softc(dev); 197 uint32_t outvals; 198 uint8_t pinbit; 199 200 if (!VALID_PIN(pin) || value > 1) 201 return (EINVAL); 202 203 GPIO_LOCK(sc); 204 pinbit = 31 - pin; 205 206 outvals = bus_read_4(sc->sc_mem, GPIO_GPDAT); 207 outvals &= ~(1 << pinbit); 208 outvals |= (value << pinbit); 209 bus_write_4(sc->sc_mem, GPIO_GPDAT, outvals); 210 211 GPIO_UNLOCK(sc); 212 213 return (0); 214 } 215 216 /* Get a specific pin's input value. */ 217 static int 218 qoriq_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) 219 { 220 struct qoriq_gpio_softc *sc = device_get_softc(dev); 221 222 if (!VALID_PIN(pin)) 223 return (EINVAL); 224 225 *value = (bus_read_4(sc->sc_mem, GPIO_GPDAT) >> (31 - pin)) & 1; 226 227 return (0); 228 } 229 230 /* Toggle a pin's output value. */ 231 static int 232 qoriq_gpio_pin_toggle(device_t dev, uint32_t pin) 233 { 234 struct qoriq_gpio_softc *sc = device_get_softc(dev); 235 uint32_t val; 236 237 if (!VALID_PIN(pin)) 238 return (EINVAL); 239 240 GPIO_LOCK(sc); 241 242 val = bus_read_4(sc->sc_mem, GPIO_GPDAT); 243 val ^= (1 << (31 - pin)); 244 bus_write_4(sc->sc_mem, GPIO_GPDAT, val); 245 246 GPIO_UNLOCK(sc); 247 248 return (0); 249 } 250 251 static struct ofw_compat_data gpio_matches[] = { 252 {"fsl,qoriq-gpio", 1}, 253 {"fsl,pq3-gpio", 1}, 254 {"fsl,mpc8572-gpio", 1}, 255 {0, 0} 256 }; 257 258 static int 259 qoriq_gpio_probe(device_t dev) 260 { 261 262 if (ofw_bus_search_compatible(dev, gpio_matches)->ocd_data == 0) 263 return (ENXIO); 264 265 device_set_desc(dev, "Freescale QorIQ GPIO driver"); 266 267 return (0); 268 } 269 270 static int 271 qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, 272 uint32_t change_pins, uint32_t *orig_pins) 273 { 274 struct qoriq_gpio_softc *sc; 275 uint32_t hwstate; 276 277 sc = device_get_softc(dev); 278 279 if (first_pin != 0) 280 return (EINVAL); 281 282 GPIO_LOCK(sc); 283 hwstate = bus_read_4(sc->sc_mem, GPIO_GPDAT); 284 bus_write_4(sc->sc_mem, GPIO_GPDAT, 285 (hwstate & ~clear_pins) ^ change_pins); 286 GPIO_UNLOCK(sc); 287 288 if (orig_pins != NULL) 289 *orig_pins = hwstate; 290 291 return (0); 292 } 293 294 static int 295 qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, 296 uint32_t *pin_flags) 297 { 298 uint32_t dir, odr, mask, reg; 299 struct qoriq_gpio_softc *sc; 300 uint32_t newflags[32]; 301 int i; 302 303 if (first_pin != 0 || !VALID_PIN(num_pins)) 304 return (EINVAL); 305 306 sc = device_get_softc(dev); 307 308 dir = odr = mask = 0; 309 310 for (i = 0; i < num_pins; i++) { 311 newflags[i] = 0; 312 mask |= (1 << i); 313 314 if (pin_flags[i] & GPIO_PIN_INPUT) { 315 newflags[i] = GPIO_PIN_INPUT; 316 dir &= ~(1 << i); 317 } else { 318 newflags[i] = GPIO_PIN_OUTPUT; 319 dir |= (1 << i); 320 321 if (pin_flags[i] & GPIO_PIN_OPENDRAIN) { 322 newflags[i] |= GPIO_PIN_OPENDRAIN; 323 odr |= (1 << i); 324 } else { 325 newflags[i] |= GPIO_PIN_PUSHPULL; 326 odr &= ~(1 << i); 327 } 328 } 329 } 330 331 GPIO_LOCK(sc); 332 333 reg = (bus_read_4(sc->sc_mem, GPIO_GPDIR) & ~mask) | dir; 334 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg); 335 336 reg = (bus_read_4(sc->sc_mem, GPIO_GPODR) & ~mask) | odr; 337 bus_write_4(sc->sc_mem, GPIO_GPODR, reg); 338 339 for (i = 0; i < num_pins; i++) 340 sc->sc_pins[i].gp_flags = newflags[i]; 341 342 GPIO_UNLOCK(sc); 343 344 return (0); 345 } 346 347 static int 348 qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, 349 pcell_t *gpios, uint32_t *pin, uint32_t *flags) 350 { 351 struct qoriq_gpio_softc *sc; 352 int err; 353 354 if (!VALID_PIN(gpios[0])) 355 return (EINVAL); 356 357 sc = device_get_softc(bus); 358 GPIO_LOCK(sc); 359 err = qoriq_gpio_pin_setflags(bus, gpios[0], gpios[1]); 360 GPIO_UNLOCK(sc); 361 362 if (err == 0) { 363 *pin = gpios[0]; 364 *flags = gpios[1]; 365 } 366 367 return (err); 368 } 369 370 static int qoriq_gpio_detach(device_t dev); 371 372 static int 373 qoriq_gpio_attach(device_t dev) 374 { 375 struct qoriq_gpio_softc *sc = device_get_softc(dev); 376 int i, rid; 377 378 sc->dev = dev; 379 380 GPIO_LOCK_INIT(sc); 381 382 /* Allocate memory. */ 383 rid = 0; 384 sc->sc_mem = bus_alloc_resource_any(dev, 385 SYS_RES_MEMORY, &rid, RF_ACTIVE); 386 if (sc->sc_mem == NULL) { 387 device_printf(dev, "Can't allocate memory for device output port"); 388 qoriq_gpio_detach(dev); 389 return (ENOMEM); 390 } 391 392 for (i = 0; i <= MAXPIN; i++) 393 sc->sc_pins[i].gp_caps = DEFAULT_CAPS; 394 395 sc->busdev = gpiobus_attach_bus(dev); 396 if (sc->busdev == NULL) { 397 qoriq_gpio_detach(dev); 398 return (ENOMEM); 399 } 400 /* 401 * Enable the GPIO Input Buffer for all GPIOs. 402 * This is safe on devices without a GPIBE register, because those 403 * devices ignore writes and read 0's in undefined portions of the map. 404 */ 405 if (ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) 406 bus_write_4(sc->sc_mem, GPIO_GPIBE, 0xffffffff); 407 408 OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev); 409 410 return (0); 411 } 412 413 static int 414 qoriq_gpio_detach(device_t dev) 415 { 416 struct qoriq_gpio_softc *sc = device_get_softc(dev); 417 418 gpiobus_detach_bus(dev); 419 420 if (sc->sc_mem != NULL) { 421 /* Release output port resource. */ 422 bus_release_resource(dev, SYS_RES_MEMORY, 423 rman_get_rid(sc->sc_mem), sc->sc_mem); 424 } 425 426 GPIO_LOCK_DESTROY(sc); 427 428 return (0); 429 } 430 431 static device_method_t qoriq_gpio_methods[] = { 432 /* device_if */ 433 DEVMETHOD(device_probe, qoriq_gpio_probe), 434 DEVMETHOD(device_attach, qoriq_gpio_attach), 435 DEVMETHOD(device_detach, qoriq_gpio_detach), 436 437 /* GPIO protocol */ 438 DEVMETHOD(gpio_get_bus, qoriq_gpio_get_bus), 439 DEVMETHOD(gpio_pin_max, qoriq_gpio_pin_max), 440 DEVMETHOD(gpio_pin_getname, qoriq_gpio_pin_getname), 441 DEVMETHOD(gpio_pin_getcaps, qoriq_gpio_pin_getcaps), 442 DEVMETHOD(gpio_pin_get, qoriq_gpio_pin_get), 443 DEVMETHOD(gpio_pin_set, qoriq_gpio_pin_set), 444 DEVMETHOD(gpio_pin_getflags, qoriq_gpio_pin_getflags), 445 DEVMETHOD(gpio_pin_setflags, qoriq_gpio_pin_setflags), 446 DEVMETHOD(gpio_pin_toggle, qoriq_gpio_pin_toggle), 447 448 DEVMETHOD(gpio_map_gpios, qoriq_gpio_map_gpios), 449 DEVMETHOD(gpio_pin_access_32, qoriq_gpio_pin_access_32), 450 DEVMETHOD(gpio_pin_config_32, qoriq_gpio_pin_config_32), 451 452 DEVMETHOD_END 453 }; 454 455 static driver_t qoriq_gpio_driver = { 456 "gpio", 457 qoriq_gpio_methods, 458 sizeof(struct qoriq_gpio_softc), 459 }; 460 static devclass_t qoriq_gpio_devclass; 461 462 EARLY_DRIVER_MODULE(qoriq_gpio, simplebus, qoriq_gpio_driver, 463 qoriq_gpio_devclass, NULL, NULL, 464 BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); 465