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