1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2020 Alstom Group. 5 * Copyright (c) 2020 Semihalf. 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 34#include <sys/bus.h> 35#include <sys/endian.h> 36#include <sys/gpio.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/mutex.h> 40 41#include <dev/gpio/gpiobusvar.h> 42#include <dev/ofw/ofw_bus.h> 43#include <machine/bus.h> 44 45#include "gpio_if.h" 46 47/* constants */ 48enum { 49 DIRECTION = 0x0, 50 OPEN_DRAIN = 0x4, 51 DATA = 0x8, 52 INT_EV = 0xC, 53 INT_MASK = 0x10, 54 INT_CTRL = 0x14 55}; 56 57#define PIN_COUNT 32 58#define DEFAULT_CAPS \ 59 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ 60 GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL) 61#define GPIO(n) (1 << (31 - (n))) 62 63struct gpio_res { 64 int mem_rid; 65 struct resource *mem_res; 66}; 67 68/* software context */ 69struct gpio_softc { 70 device_t dev; 71 device_t busdev; 72 struct gpio_res res; 73 struct gpio_pin setup[PIN_COUNT]; 74 struct mtx mutex; 75}; 76 77#define QORIQ_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->mutex) 78#define QORIQ_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->mutex) 79#define QORIQ_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mutex, MA_OWNED) 80 81/* prototypes */ 82/* helpers */ 83static bool qoriq_make_gpio_res(device_t, struct gpio_res*); 84static uint32_t qoriq_gpio_reg_read(device_t, uint32_t); 85static void qoriq_gpio_reg_write(device_t, uint32_t, uint32_t); 86static void qoriq_gpio_set(device_t, uint32_t, uint32_t, uint32_t); 87static int qoriq_gpio_configure(device_t, uint32_t, uint32_t); 88 89/* GPIO API */ 90static int qoriq_gpio_probe(device_t); 91static int qoriq_gpio_attach(device_t); 92static device_t qoriq_gpio_get_bus(device_t); 93static int qoriq_gpio_pin_max(device_t, int*); 94static int qoriq_gpio_pin_getname(device_t, uint32_t, char*); 95static int qoriq_gpio_pin_getflags(device_t, uint32_t, uint32_t*); 96static int qoriq_gpio_pin_setflags(device_t, uint32_t, uint32_t); 97static int qoriq_gpio_pin_getcaps(device_t, uint32_t, uint32_t*); 98static int qoriq_gpio_pin_get(device_t, uint32_t, uint32_t*); 99static int qoriq_gpio_pin_set(device_t, uint32_t, uint32_t); 100static int qoriq_gpio_pin_toggle(device_t, uint32_t); 101static int qoriq_gpio_map_gpios(device_t, phandle_t, phandle_t, 102 int, pcell_t*, uint32_t*, uint32_t*); 103static int qoriq_gpio_pin_access_32(device_t, uint32_t, uint32_t, uint32_t, 104 uint32_t*); 105static int qoriq_gpio_pin_config_32(device_t, uint32_t, uint32_t, uint32_t*); 106 107static device_method_t qoriq_gpio_methods[] = { 108 DEVMETHOD(device_probe, qoriq_gpio_probe), 109 DEVMETHOD(device_attach, qoriq_gpio_attach), 110 111 /* GPIO protocol */ 112 DEVMETHOD(gpio_get_bus, qoriq_gpio_get_bus), 113 DEVMETHOD(gpio_pin_max, qoriq_gpio_pin_max), 114 DEVMETHOD(gpio_pin_getname, qoriq_gpio_pin_getname), 115 DEVMETHOD(gpio_pin_getflags, qoriq_gpio_pin_getflags), 116 DEVMETHOD(gpio_pin_setflags, qoriq_gpio_pin_setflags), 117 DEVMETHOD(gpio_pin_getcaps, qoriq_gpio_pin_getcaps), 118 DEVMETHOD(gpio_pin_get, qoriq_gpio_pin_get), 119 DEVMETHOD(gpio_pin_set, qoriq_gpio_pin_set), 120 DEVMETHOD(gpio_pin_toggle, qoriq_gpio_pin_toggle), 121 DEVMETHOD(gpio_map_gpios, qoriq_gpio_map_gpios), 122 DEVMETHOD(gpio_pin_access_32, qoriq_gpio_pin_access_32), 123 DEVMETHOD(gpio_pin_config_32, qoriq_gpio_pin_config_32), 124 125 DEVMETHOD_END 126}; 127 128static driver_t gpio_driver = { 129 "gpio", 130 qoriq_gpio_methods, 131 sizeof(struct gpio_softc), 132}; 133 134static devclass_t gpio_devclass; 135 136DRIVER_MODULE(gpio, simplebus, gpio_driver, gpio_devclass, 0, 0); 137MODULE_VERSION(gpio, 1); 138 139/* 140 * helpers 141 */ 142static bool 143qoriq_make_gpio_res(device_t dev, struct gpio_res *out) 144{ 145 146 out->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 147 &out->mem_rid, RF_ACTIVE | RF_SHAREABLE); 148 149 return (out->mem_res == NULL); 150} 151 152static uint32_t 153qoriq_gpio_reg_read(device_t dev, uint32_t reg) 154{ 155 struct gpio_softc *sc = device_get_softc(dev); 156 uint32_t result; 157 158 QORIQ_GPIO_ASSERT_LOCKED(sc); 159 result = bus_read_4(sc->res.mem_res, reg); 160 161 return be32toh(result); 162} 163 164static void 165qoriq_gpio_reg_write(device_t dev, uint32_t reg, uint32_t val) 166{ 167 struct gpio_softc *sc = device_get_softc(dev); 168 169 QORIQ_GPIO_ASSERT_LOCKED(sc); 170 val = htobe32(val); 171 172 bus_write_4(sc->res.mem_res, reg, val); 173 bus_barrier(sc->res.mem_res, reg, 4, BUS_SPACE_BARRIER_READ | 174 BUS_SPACE_BARRIER_WRITE); 175} 176 177static void 178qoriq_gpio_set(device_t dev, uint32_t reg, uint32_t pin, uint32_t set) 179{ 180 uint32_t val; 181 182 set = set != 0; 183 val = (qoriq_gpio_reg_read(dev, reg) & ~(1U << pin)) | (set << pin); 184 qoriq_gpio_reg_write(dev, reg, val); 185} 186 187static int 188qoriq_gpio_configure(device_t dev, uint32_t pin, uint32_t flags) 189{ 190 struct gpio_softc *sc = device_get_softc(dev); 191 uint32_t newflags; 192 193 if (pin >= PIN_COUNT) 194 return (EINVAL); 195 196 /* 197 * Pin cannot function as input and output at the same time. 198 * The same applies to open-drain and push-pull functionality. 199 */ 200 if (((flags & GPIO_PIN_INPUT) && (flags & GPIO_PIN_OUTPUT)) || 201 ((flags & GPIO_PIN_OPENDRAIN) && (flags & GPIO_PIN_PUSHPULL))) 202 return (EINVAL); 203 204 QORIQ_GPIO_ASSERT_LOCKED(sc); 205 206 if (flags & GPIO_PIN_INPUT) { 207 newflags = GPIO_PIN_INPUT; 208 qoriq_gpio_set(dev, DIRECTION, pin, 0); 209 } 210 211 if (flags & GPIO_PIN_OUTPUT) { 212 newflags = GPIO_PIN_OUTPUT; 213 qoriq_gpio_set(dev, DIRECTION, pin, 1); 214 215 if (flags & GPIO_PIN_OPENDRAIN) { 216 newflags |= GPIO_PIN_OPENDRAIN; 217 qoriq_gpio_set(dev, OPEN_DRAIN, pin, 1); 218 } else { 219 newflags |= GPIO_PIN_PUSHPULL; 220 qoriq_gpio_set(dev, OPEN_DRAIN, pin, 0); 221 } 222 } 223 224 sc->setup[pin].gp_flags = newflags; 225 226 return (0); 227} 228 229/* GPIO API */ 230static int 231qoriq_gpio_probe(device_t dev) 232{ 233 234 if (!ofw_bus_status_okay(dev)) 235 return (ENXIO); 236 237 if (!ofw_bus_is_compatible(dev, "fsl,qoriq-gpio")) 238 return (ENXIO); 239 240 device_set_desc(dev, "Integrated GPIO Controller"); 241 242 return (BUS_PROBE_DEFAULT); 243} 244 245static int 246qoriq_gpio_attach(device_t dev) 247{ 248 struct gpio_softc *sc = device_get_softc(dev); 249 int i; 250 251 if (qoriq_make_gpio_res(dev, &sc->res)) 252 return (ENXIO); 253 254 for (i = 0; i < PIN_COUNT; i++) 255 sc->setup[i].gp_caps = DEFAULT_CAPS; 256 257 sc->dev = dev; 258 259 sc->busdev = gpiobus_attach_bus(dev); 260 if (sc->busdev == NULL) 261 return (ENXIO); 262 263 return (0); 264} 265 266static device_t 267qoriq_gpio_get_bus(device_t dev) 268{ 269 struct gpio_softc *softc = device_get_softc(dev); 270 271 return (softc->busdev); 272} 273 274static int 275qoriq_gpio_pin_max(device_t dev, int *maxpin) 276{ 277 278 if (maxpin == NULL) 279 return (EINVAL); 280 281 *maxpin = PIN_COUNT - 1; 282 283 return (0); 284} 285 286static int 287qoriq_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 288{ 289 290 if (name == NULL || pin >= PIN_COUNT) 291 return (EINVAL); 292 293 snprintf(name, GPIOMAXNAME, "pin %d", pin); 294 295 return (0); 296} 297 298static int 299qoriq_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags) 300{ 301 struct gpio_softc *sc = device_get_softc(dev); 302 303 if (pflags == NULL || pin >= PIN_COUNT) 304 return (EINVAL); 305 306 QORIQ_GPIO_LOCK(sc); 307 *pflags = sc->setup[pin].gp_flags; 308 QORIQ_GPIO_UNLOCK(sc); 309 310 return (0); 311} 312 313static int 314qoriq_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 315{ 316 struct gpio_softc *sc = device_get_softc(dev); 317 int ret; 318 319 if (pin >= PIN_COUNT) 320 return (EINVAL); 321 322 /* Check for unwanted flags. */ 323 QORIQ_GPIO_LOCK(sc); 324 325 if ((flags & sc->setup[pin].gp_caps) != flags) { 326 QORIQ_GPIO_UNLOCK(sc); 327 return (EINVAL); 328 } 329 330 ret = qoriq_gpio_configure(dev, pin, flags); 331 332 QORIQ_GPIO_UNLOCK(sc); 333 334 return (ret); 335} 336 337static int 338qoriq_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 339{ 340 struct gpio_softc *sc = device_get_softc(dev); 341 342 if (caps == NULL || pin >= PIN_COUNT) 343 return (EINVAL); 344 345 QORIQ_GPIO_LOCK(sc); 346 *caps = sc->setup[pin].gp_caps; 347 QORIQ_GPIO_UNLOCK(sc); 348 349 return (0); 350} 351 352static int 353qoriq_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value) 354{ 355 struct gpio_softc *sc = device_get_softc(dev); 356 357 if (value == NULL || pin >= PIN_COUNT) 358 return (EINVAL); 359 360 QORIQ_GPIO_LOCK(sc); 361 *value = (qoriq_gpio_reg_read(dev, DATA) & GPIO(pin)) != 0; 362 QORIQ_GPIO_UNLOCK(sc); 363 364 return (0); 365} 366 367static int 368qoriq_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value) 369{ 370 struct gpio_softc *sc = device_get_softc(dev); 371 372 if (pin >= PIN_COUNT) 373 return (EINVAL); 374 375 QORIQ_GPIO_LOCK(sc); 376 qoriq_gpio_set(dev, DATA, pin, value); 377 QORIQ_GPIO_UNLOCK(sc); 378 379 return (0); 380} 381 382static int 383qoriq_gpio_pin_toggle(device_t dev, uint32_t pin) 384{ 385 struct gpio_softc *sc; 386 uint32_t value; 387 388 if (pin >= PIN_COUNT) 389 return (EINVAL); 390 391 sc = device_get_softc(dev); 392 393 QORIQ_GPIO_LOCK(sc); 394 value = qoriq_gpio_reg_read(dev, DATA) ^ (1 << pin); 395 qoriq_gpio_reg_write(dev, DATA, value); 396 QORIQ_GPIO_UNLOCK(sc); 397 398 return (0); 399} 400 401static int 402qoriq_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, 403 pcell_t *gpios, uint32_t *pin, uint32_t *flags) 404{ 405 struct gpio_softc *sc = device_get_softc(bus); 406 int err; 407 408 if (gpios[0] >= PIN_COUNT) 409 return (EINVAL); 410 411 QORIQ_GPIO_LOCK(sc); 412 err = qoriq_gpio_configure(bus, gpios[0], gpios[1]); 413 QORIQ_GPIO_UNLOCK(sc); 414 415 if (err != 0) 416 return (err); 417 418 *pin = gpios[0]; 419 *flags = gpios[1]; 420 421 return (0); 422} 423 424static int 425qoriq_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, 426 uint32_t change_pins, uint32_t *orig_pins) 427{ 428 struct gpio_softc *sc; 429 uint32_t hwstate; 430 431 sc = device_get_softc(dev); 432 433 if (first_pin != 0) 434 return (EINVAL); 435 436 QORIQ_GPIO_LOCK(sc); 437 hwstate = qoriq_gpio_reg_read(dev, DATA); 438 qoriq_gpio_reg_write(dev, DATA, (hwstate & ~clear_pins) ^ change_pins); 439 QORIQ_GPIO_UNLOCK(sc); 440 441 if (orig_pins != NULL) 442 *orig_pins = hwstate; 443 444 return (0); 445} 446 447static int 448qoriq_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, 449 uint32_t *pin_flags) 450{ 451 uint32_t dir, odr, mask, reg; 452 struct gpio_softc *sc; 453 uint32_t newflags[32]; 454 int i; 455 456 if (first_pin != 0 || num_pins > PIN_COUNT) 457 return (EINVAL); 458 459 sc = device_get_softc(dev); 460 461 dir = odr = mask = 0; 462 463 for (i = 0; i < num_pins; i++) { 464 newflags[i] = 0; 465 mask |= (1 << i); 466 467 if (pin_flags[i] & GPIO_PIN_INPUT) { 468 newflags[i] = GPIO_PIN_INPUT; 469 dir &= ~(1 << i); 470 } else { 471 newflags[i] = GPIO_PIN_OUTPUT; 472 dir |= (1 << i); 473 474 if (pin_flags[i] & GPIO_PIN_OPENDRAIN) { 475 newflags[i] |= GPIO_PIN_OPENDRAIN; 476 odr |= (1 << i); 477 } else { 478 newflags[i] |= GPIO_PIN_PUSHPULL; 479 odr &= ~(1 << i); 480 } 481 } 482 } 483 484 QORIQ_GPIO_LOCK(sc); 485 486 reg = (qoriq_gpio_reg_read(dev, DIRECTION) & ~mask) | dir; 487 qoriq_gpio_reg_write(dev, DIRECTION, reg); 488 489 reg = (qoriq_gpio_reg_read(dev, OPEN_DRAIN) & ~mask) | odr; 490 qoriq_gpio_reg_write(dev, OPEN_DRAIN, reg); 491 492 for (i = 0; i < num_pins; i++) 493 sc->setup[i].gp_flags = newflags[i]; 494 495 QORIQ_GPIO_UNLOCK(sc); 496 497 return (0); 498} 499