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