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 (0); 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 {0, 0} 239 }; 240 241 static int 242 qoriq_gpio_probe(device_t dev) 243 { 244 245 if (ofw_bus_search_compatible(dev, gpio_matches)->ocd_data == 0) 246 return (ENXIO); 247 248 device_set_desc(dev, "Freescale QorIQ GPIO driver"); 249 250 return (0); 251 } 252 253 static int 254 qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, 255 uint32_t change_pins, uint32_t *orig_pins) 256 { 257 struct qoriq_gpio_softc *sc; 258 uint32_t hwstate; 259 260 sc = device_get_softc(dev); 261 262 if (first_pin != 0) 263 return (EINVAL); 264 265 GPIO_LOCK(sc); 266 hwstate = bus_read_4(sc->sc_mem, GPIO_GPDAT); 267 bus_write_4(sc->sc_mem, GPIO_GPDAT, 268 (hwstate & ~clear_pins) ^ change_pins); 269 GPIO_UNLOCK(sc); 270 271 if (orig_pins != NULL) 272 *orig_pins = hwstate; 273 274 return (0); 275 } 276 277 static int 278 qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, 279 uint32_t *pin_flags) 280 { 281 uint32_t dir, odr, mask, reg; 282 struct qoriq_gpio_softc *sc; 283 uint32_t newflags[32]; 284 int i; 285 286 if (first_pin != 0 || !VALID_PIN(num_pins)) 287 return (EINVAL); 288 289 sc = device_get_softc(dev); 290 291 dir = odr = mask = 0; 292 293 for (i = 0; i < num_pins; i++) { 294 newflags[i] = 0; 295 mask |= (1 << i); 296 297 if (pin_flags[i] & GPIO_PIN_INPUT) { 298 newflags[i] = GPIO_PIN_INPUT; 299 dir &= ~(1 << i); 300 } else { 301 newflags[i] = GPIO_PIN_OUTPUT; 302 dir |= (1 << i); 303 304 if (pin_flags[i] & GPIO_PIN_OPENDRAIN) { 305 newflags[i] |= GPIO_PIN_OPENDRAIN; 306 odr |= (1 << i); 307 } else { 308 newflags[i] |= GPIO_PIN_PUSHPULL; 309 odr &= ~(1 << i); 310 } 311 } 312 } 313 314 GPIO_LOCK(sc); 315 316 reg = (bus_read_4(sc->sc_mem, GPIO_GPDIR) & ~mask) | dir; 317 bus_write_4(sc->sc_mem, GPIO_GPDIR, reg); 318 319 reg = (bus_read_4(sc->sc_mem, GPIO_GPODR) & ~mask) | odr; 320 bus_write_4(sc->sc_mem, GPIO_GPODR, reg); 321 322 for (i = 0; i < num_pins; i++) 323 sc->sc_pins[i].gp_flags = newflags[i]; 324 325 GPIO_UNLOCK(sc); 326 327 return (0); 328 } 329 330 static int 331 qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, 332 pcell_t *gpios, uint32_t *pin, uint32_t *flags) 333 { 334 struct qoriq_gpio_softc *sc; 335 int err; 336 337 if (!VALID_PIN(gpios[0])) 338 return (EINVAL); 339 340 sc = device_get_softc(bus); 341 GPIO_LOCK(sc); 342 err = qoriq_gpio_pin_configure(bus, gpios[0], gpios[1]); 343 GPIO_UNLOCK(sc); 344 345 if (err == 0) { 346 *pin = gpios[0]; 347 *flags = gpios[1]; 348 } 349 350 return (err); 351 } 352 353 int 354 qoriq_gpio_attach(device_t dev) 355 { 356 struct qoriq_gpio_softc *sc = device_get_softc(dev); 357 int i, rid; 358 359 sc->dev = dev; 360 361 GPIO_LOCK_INIT(sc); 362 363 /* Allocate memory. */ 364 rid = 0; 365 sc->sc_mem = bus_alloc_resource_any(dev, 366 SYS_RES_MEMORY, &rid, RF_ACTIVE); 367 if (sc->sc_mem == NULL) { 368 device_printf(dev, "Can't allocate memory for device output port"); 369 qoriq_gpio_detach(dev); 370 return (ENOMEM); 371 } 372 373 for (i = 0; i <= MAXPIN; i++) 374 sc->sc_pins[i].gp_caps = DEFAULT_CAPS; 375 376 sc->busdev = gpiobus_attach_bus(dev); 377 if (sc->busdev == NULL) { 378 qoriq_gpio_detach(dev); 379 return (ENOMEM); 380 } 381 /* 382 * Enable the GPIO Input Buffer for all GPIOs. 383 * This is safe on devices without a GPIBE register, because those 384 * devices ignore writes and read 0's in undefined portions of the map. 385 */ 386 if (ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) 387 bus_write_4(sc->sc_mem, GPIO_GPIBE, 0xffffffff); 388 389 OF_device_register_xref(OF_xref_from_node(ofw_bus_get_node(dev)), dev); 390 391 return (0); 392 } 393 394 int 395 qoriq_gpio_detach(device_t dev) 396 { 397 struct qoriq_gpio_softc *sc = device_get_softc(dev); 398 399 gpiobus_detach_bus(dev); 400 401 if (sc->sc_mem != NULL) { 402 /* Release output port resource. */ 403 bus_release_resource(dev, SYS_RES_MEMORY, 404 rman_get_rid(sc->sc_mem), sc->sc_mem); 405 } 406 407 GPIO_LOCK_DESTROY(sc); 408 409 return (0); 410 } 411 412 static device_method_t qoriq_gpio_methods[] = { 413 /* device_if */ 414 DEVMETHOD(device_probe, qoriq_gpio_probe), 415 DEVMETHOD(device_attach, qoriq_gpio_attach), 416 DEVMETHOD(device_detach, qoriq_gpio_detach), 417 418 /* GPIO protocol */ 419 DEVMETHOD(gpio_get_bus, qoriq_gpio_get_bus), 420 DEVMETHOD(gpio_pin_max, qoriq_gpio_pin_max), 421 DEVMETHOD(gpio_pin_getname, qoriq_gpio_pin_getname), 422 DEVMETHOD(gpio_pin_getcaps, qoriq_gpio_pin_getcaps), 423 DEVMETHOD(gpio_pin_get, qoriq_gpio_pin_get), 424 DEVMETHOD(gpio_pin_set, qoriq_gpio_pin_set), 425 DEVMETHOD(gpio_pin_getflags, qoriq_gpio_pin_getflags), 426 DEVMETHOD(gpio_pin_setflags, qoriq_gpio_pin_setflags), 427 DEVMETHOD(gpio_pin_toggle, qoriq_gpio_pin_toggle), 428 429 DEVMETHOD(gpio_map_gpios, qoriq_gpio_map_gpios), 430 DEVMETHOD(gpio_pin_access_32, qoriq_gpio_pin_access_32), 431 DEVMETHOD(gpio_pin_config_32, qoriq_gpio_pin_config_32), 432 433 DEVMETHOD_END 434 }; 435 436 static devclass_t qoriq_gpio_devclass; 437 438 DEFINE_CLASS_0(gpio, qoriq_gpio_driver, qoriq_gpio_methods, 439 sizeof(struct qoriq_gpio_softc)); 440 441 EARLY_DRIVER_MODULE(qoriq_gpio, simplebus, qoriq_gpio_driver, 442 qoriq_gpio_devclass, NULL, NULL, 443 BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); 444