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