1/*- 2 * Copyright (c) 2006 M. Warner Losh. All rights reserved. 3 * Copyright (C) 2012 Ian Lepore. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include "opt_platform.h" 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); 31 32#include <sys/param.h> 33#include <sys/systm.h> 34#include <sys/bus.h> 35#include <sys/conf.h> 36#include <sys/kernel.h> 37#include <sys/lock.h> 38#include <sys/mbuf.h> 39#include <sys/malloc.h> 40#include <sys/module.h> 41#include <sys/poll.h> 42#include <sys/rman.h> 43#include <sys/selinfo.h> 44#include <sys/sx.h> 45#include <sys/uio.h> 46#include <machine/at91_gpio.h> 47#include <machine/bus.h> 48 49#include <arm/at91/at91reg.h> 50#include <arm/at91/at91_pioreg.h> 51#include <arm/at91/at91_piovar.h> 52 53#ifdef FDT 54#include <dev/fdt/fdt_common.h> 55#include <dev/ofw/ofw_bus.h> 56#include <dev/ofw/ofw_bus_subr.h> 57#endif 58 59#define MAX_CHANGE 64 60 61struct at91_pio_softc 62{ 63 device_t dev; /* Myself */ 64 void *intrhand; /* Interrupt handle */ 65 struct resource *irq_res; /* IRQ resource */ 66 struct resource *mem_res; /* Memory resource */ 67 struct sx sc_mtx; /* basically a perimeter lock */ 68 struct cdev *cdev; 69 struct selinfo selp; 70 int buflen; 71 uint8_t buf[MAX_CHANGE]; 72 int flags; 73#define OPENED 1 74}; 75 76static inline uint32_t 77RD4(struct at91_pio_softc *sc, bus_size_t off) 78{ 79 80 return (bus_read_4(sc->mem_res, off)); 81} 82 83static inline void 84WR4(struct at91_pio_softc *sc, bus_size_t off, uint32_t val) 85{ 86 87 bus_write_4(sc->mem_res, off, val); 88} 89 90#define AT91_PIO_LOCK(_sc) sx_xlock(&(_sc)->sc_mtx) 91#define AT91_PIO_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_mtx) 92#define AT91_PIO_LOCK_INIT(_sc) \ 93 sx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev)) 94#define AT91_PIO_LOCK_DESTROY(_sc) sx_destroy(&_sc->sc_mtx); 95#define AT91_PIO_ASSERT_LOCKED(_sc) sx_assert(&_sc->sc_mtx, SA_XLOCKED); 96#define AT91_PIO_ASSERT_UNLOCKED(_sc) sx_assert(&_sc->sc_mtx, SA_UNLOCKED); 97#define CDEV2SOFTC(dev) ((dev)->si_drv1) 98 99static devclass_t at91_pio_devclass; 100 101/* bus entry points */ 102 103static int at91_pio_probe(device_t dev); 104static int at91_pio_attach(device_t dev); 105static int at91_pio_detach(device_t dev); 106static void at91_pio_intr(void *); 107 108/* helper routines */ 109static int at91_pio_activate(device_t dev); 110static void at91_pio_deactivate(device_t dev); 111 112/* cdev routines */ 113static d_open_t at91_pio_open; 114static d_close_t at91_pio_close; 115static d_read_t at91_pio_read; 116static d_poll_t at91_pio_poll; 117static d_ioctl_t at91_pio_ioctl; 118 119static struct cdevsw at91_pio_cdevsw = 120{ 121 .d_version = D_VERSION, 122 .d_open = at91_pio_open, 123 .d_close = at91_pio_close, 124 .d_read = at91_pio_read, 125 .d_poll = at91_pio_poll, 126 .d_ioctl = at91_pio_ioctl 127}; 128 129static int 130at91_pio_probe(device_t dev) 131{ 132 const char *name; 133#ifdef FDT 134 if (!ofw_bus_is_compatible(dev, "atmel,at91rm9200-gpio")) 135 return (ENXIO); 136#endif 137 switch (device_get_unit(dev)) { 138 case 0: 139 name = "PIOA"; 140 break; 141 case 1: 142 name = "PIOB"; 143 break; 144 case 2: 145 name = "PIOC"; 146 break; 147 case 3: 148 name = "PIOD"; 149 break; 150 case 4: 151 name = "PIOE"; 152 break; 153 case 5: 154 name = "PIOF"; 155 break; 156 default: 157 name = "PIO"; 158 break; 159 } 160 device_set_desc(dev, name); 161 return (0); 162} 163 164static int 165at91_pio_attach(device_t dev) 166{ 167 struct at91_pio_softc *sc; 168 int err; 169 170 sc = device_get_softc(dev); 171 sc->dev = dev; 172 err = at91_pio_activate(dev); 173 if (err) 174 goto out; 175 176 if (bootverbose) 177 device_printf(dev, "ABSR: %#x OSR: %#x PSR:%#x ODSR: %#x\n", 178 RD4(sc, PIO_ABSR), RD4(sc, PIO_OSR), RD4(sc, PIO_PSR), 179 RD4(sc, PIO_ODSR)); 180 AT91_PIO_LOCK_INIT(sc); 181 182 /* 183 * Activate the interrupt, but disable all interrupts in the hardware. 184 */ 185 WR4(sc, PIO_IDR, 0xffffffff); 186 err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC, 187 NULL, at91_pio_intr, sc, &sc->intrhand); 188 if (err) { 189 AT91_PIO_LOCK_DESTROY(sc); 190 goto out; 191 } 192 sc->cdev = make_dev(&at91_pio_cdevsw, device_get_unit(dev), UID_ROOT, 193 GID_WHEEL, 0600, "pio%d", device_get_unit(dev)); 194 if (sc->cdev == NULL) { 195 err = ENOMEM; 196 goto out; 197 } 198 sc->cdev->si_drv1 = sc; 199out: 200 if (err) 201 at91_pio_deactivate(dev); 202 return (err); 203} 204 205static int 206at91_pio_detach(device_t dev) 207{ 208 209 return (EBUSY); /* XXX */ 210} 211 212static int 213at91_pio_activate(device_t dev) 214{ 215 struct at91_pio_softc *sc; 216 int rid; 217 218 sc = device_get_softc(dev); 219 rid = 0; 220 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 221 RF_ACTIVE); 222 if (sc->mem_res == NULL) 223 goto errout; 224 rid = 0; 225 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 226 RF_ACTIVE | RF_SHAREABLE); 227 if (sc->irq_res == NULL) 228 goto errout; 229 return (0); 230errout: 231 at91_pio_deactivate(dev); 232 return (ENOMEM); 233} 234 235static void 236at91_pio_deactivate(device_t dev) 237{ 238 struct at91_pio_softc *sc; 239 240 sc = device_get_softc(dev); 241 if (sc->intrhand) 242 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 243 sc->intrhand = NULL; 244 bus_generic_detach(sc->dev); 245 if (sc->mem_res) 246 bus_release_resource(dev, SYS_RES_MEMORY, 247 rman_get_rid(sc->mem_res), sc->mem_res); 248 sc->mem_res = NULL; 249 if (sc->irq_res) 250 bus_release_resource(dev, SYS_RES_IRQ, 251 rman_get_rid(sc->irq_res), sc->irq_res); 252 sc->irq_res = NULL; 253} 254 255static void 256at91_pio_intr(void *xsc) 257{ 258 struct at91_pio_softc *sc = xsc; 259 uint32_t status; 260 int i; 261 262 /* Reading the status also clears the interrupt. */ 263 status = RD4(sc, PIO_ISR) & RD4(sc, PIO_IMR); 264 if (status != 0) { 265 AT91_PIO_LOCK(sc); 266 for (i = 0; status != 0 && sc->buflen < MAX_CHANGE; ++i) { 267 if (status & 1) 268 sc->buf[sc->buflen++] = (uint8_t)i; 269 status >>= 1; 270 } 271 AT91_PIO_UNLOCK(sc); 272 wakeup(sc); 273 selwakeup(&sc->selp); 274 } 275} 276 277static int 278at91_pio_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 279{ 280 struct at91_pio_softc *sc; 281 282 sc = CDEV2SOFTC(dev); 283 AT91_PIO_LOCK(sc); 284 if (!(sc->flags & OPENED)) { 285 sc->flags |= OPENED; 286 } 287 AT91_PIO_UNLOCK(sc); 288 return (0); 289} 290 291static int 292at91_pio_close(struct cdev *dev, int fflag, int devtype, struct thread *td) 293{ 294 struct at91_pio_softc *sc; 295 296 sc = CDEV2SOFTC(dev); 297 AT91_PIO_LOCK(sc); 298 sc->flags &= ~OPENED; 299 AT91_PIO_UNLOCK(sc); 300 return (0); 301} 302 303static int 304at91_pio_poll(struct cdev *dev, int events, struct thread *td) 305{ 306 struct at91_pio_softc *sc; 307 int revents = 0; 308 309 sc = CDEV2SOFTC(dev); 310 AT91_PIO_LOCK(sc); 311 if (events & (POLLIN | POLLRDNORM)) { 312 if (sc->buflen != 0) 313 revents |= events & (POLLIN | POLLRDNORM); 314 else 315 selrecord(td, &sc->selp); 316 } 317 AT91_PIO_UNLOCK(sc); 318 319 return (revents); 320} 321 322static int 323at91_pio_read(struct cdev *dev, struct uio *uio, int flag) 324{ 325 struct at91_pio_softc *sc; 326 int err, ret, len; 327 328 sc = CDEV2SOFTC(dev); 329 AT91_PIO_LOCK(sc); 330 err = 0; 331 ret = 0; 332 while (uio->uio_resid) { 333 while (sc->buflen == 0 && err == 0) 334 err = msleep(sc, &sc->sc_mtx, PCATCH | PZERO, "prd", 0); 335 if (err != 0) 336 break; 337 len = MIN(sc->buflen, uio->uio_resid); 338 err = uiomove(sc->buf, len, uio); 339 if (err != 0) 340 break; 341 /* 342 * If we read the whole thing no datacopy is needed, 343 * otherwise we move the data down. 344 */ 345 ret += len; 346 if (sc->buflen == len) 347 sc->buflen = 0; 348 else { 349 bcopy(sc->buf + len, sc->buf, sc->buflen - len); 350 sc->buflen -= len; 351 } 352 /* If there's no data left, end the read. */ 353 if (sc->buflen == 0) 354 break; 355 } 356 AT91_PIO_UNLOCK(sc); 357 return (err); 358} 359 360static void 361at91_pio_bang32(struct at91_pio_softc *sc, uint32_t bits, uint32_t datapin, 362 uint32_t clockpin) 363{ 364 int i; 365 366 for (i = 0; i < 32; i++) { 367 if (bits & 0x80000000) 368 WR4(sc, PIO_SODR, datapin); 369 else 370 WR4(sc, PIO_CODR, datapin); 371 bits <<= 1; 372 WR4(sc, PIO_CODR, clockpin); 373 WR4(sc, PIO_SODR, clockpin); 374 } 375} 376 377static void 378at91_pio_bang(struct at91_pio_softc *sc, uint8_t bits, uint32_t bitcount, 379 uint32_t datapin, uint32_t clockpin) 380{ 381 int i; 382 383 for (i = 0; i < bitcount; i++) { 384 if (bits & 0x80) 385 WR4(sc, PIO_SODR, datapin); 386 else 387 WR4(sc, PIO_CODR, datapin); 388 bits <<= 1; 389 WR4(sc, PIO_CODR, clockpin); 390 WR4(sc, PIO_SODR, clockpin); 391 } 392} 393 394static int 395at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 396 struct thread *td) 397{ 398 struct at91_pio_softc *sc; 399 struct at91_gpio_cfg *cfg; 400 struct at91_gpio_info *info; 401 struct at91_gpio_bang *bang; 402 struct at91_gpio_bang_many *bangmany; 403 uint32_t i, num; 404 uint8_t many[1024], *walker; 405 int err; 406 int bitcount; 407 408 sc = CDEV2SOFTC(dev); 409 switch(cmd) { 410 case AT91_GPIO_SET: /* turn bits on */ 411 WR4(sc, PIO_SODR, *(uint32_t *)data); 412 return (0); 413 case AT91_GPIO_CLR: /* turn bits off */ 414 WR4(sc, PIO_CODR, *(uint32_t *)data); 415 return (0); 416 case AT91_GPIO_READ: /* Get the status of input bits */ 417 *(uint32_t *)data = RD4(sc, PIO_PDSR); 418 return (0); 419 case AT91_GPIO_CFG: /* Configure AT91_GPIO pins */ 420 cfg = (struct at91_gpio_cfg *)data; 421 if (cfg->cfgmask & AT91_GPIO_CFG_INPUT) { 422 WR4(sc, PIO_OER, cfg->iomask & ~cfg->input); 423 WR4(sc, PIO_ODR, cfg->iomask & cfg->input); 424 } 425 if (cfg->cfgmask & AT91_GPIO_CFG_HI_Z) { 426 WR4(sc, PIO_MDDR, cfg->iomask & ~cfg->hi_z); 427 WR4(sc, PIO_MDER, cfg->iomask & cfg->hi_z); 428 } 429 if (cfg->cfgmask & AT91_GPIO_CFG_PULLUP) { 430 WR4(sc, PIO_PUDR, cfg->iomask & ~cfg->pullup); 431 WR4(sc, PIO_PUER, cfg->iomask & cfg->pullup); 432 } 433 if (cfg->cfgmask & AT91_GPIO_CFG_GLITCH) { 434 WR4(sc, PIO_IFDR, cfg->iomask & ~cfg->glitch); 435 WR4(sc, PIO_IFER, cfg->iomask & cfg->glitch); 436 } 437 if (cfg->cfgmask & AT91_GPIO_CFG_GPIO) { 438 WR4(sc, PIO_PDR, cfg->iomask & ~cfg->gpio); 439 WR4(sc, PIO_PER, cfg->iomask & cfg->gpio); 440 } 441 if (cfg->cfgmask & AT91_GPIO_CFG_PERIPH) { 442 WR4(sc, PIO_ASR, cfg->iomask & ~cfg->periph); 443 WR4(sc, PIO_BSR, cfg->iomask & cfg->periph); 444 } 445 if (cfg->cfgmask & AT91_GPIO_CFG_INTR) { 446 WR4(sc, PIO_IDR, cfg->iomask & ~cfg->intr); 447 WR4(sc, PIO_IER, cfg->iomask & cfg->intr); 448 } 449 return (0); 450 case AT91_GPIO_BANG: 451 bang = (struct at91_gpio_bang *)data; 452 at91_pio_bang32(sc, bang->bits, bang->datapin, bang->clockpin); 453 return (0); 454 case AT91_GPIO_BANG_MANY: 455 bangmany = (struct at91_gpio_bang_many *)data; 456 walker = (uint8_t *)bangmany->bits; 457 bitcount = bangmany->numbits; 458 while (bitcount > 0) { 459 num = MIN((bitcount + 7) / 8, sizeof(many)); 460 err = copyin(walker, many, num); 461 if (err) 462 return err; 463 for (i = 0; i < num && bitcount > 0; i++, bitcount -= 8) 464 if (bitcount >= 8) 465 at91_pio_bang(sc, many[i], 8, bangmany->datapin, bangmany->clockpin); 466 else 467 at91_pio_bang(sc, many[i], bitcount, bangmany->datapin, bangmany->clockpin); 468 walker += num; 469 } 470 return (0); 471 case AT91_GPIO_INFO: /* Learn about this device's AT91_GPIO bits */ 472 info = (struct at91_gpio_info *)data; 473 info->output_status = RD4(sc, PIO_ODSR); 474 info->input_status = RD4(sc, PIO_OSR); 475 info->highz_status = RD4(sc, PIO_MDSR); 476 info->pullup_status = RD4(sc, PIO_PUSR); 477 info->glitch_status = RD4(sc, PIO_IFSR); 478 info->enabled_status = RD4(sc, PIO_PSR); 479 info->periph_status = RD4(sc, PIO_ABSR); 480 info->intr_status = RD4(sc, PIO_IMR); 481 memset(info->extra_status, 0, sizeof(info->extra_status)); 482 return (0); 483 } 484 return (ENOTTY); 485} 486 487/* 488 * The following functions are called early in the boot process, so 489 * don't use bus_space, as that isn't yet available when we need to use 490 * them. 491 */ 492 493void 494at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup) 495{ 496 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 497 498 PIO[PIO_ASR / 4] = periph_a_mask; 499 PIO[PIO_PDR / 4] = periph_a_mask; 500 if (use_pullup) 501 PIO[PIO_PUER / 4] = periph_a_mask; 502 else 503 PIO[PIO_PUDR / 4] = periph_a_mask; 504} 505 506void 507at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup) 508{ 509 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 510 511 PIO[PIO_BSR / 4] = periph_b_mask; 512 PIO[PIO_PDR / 4] = periph_b_mask; 513 if (use_pullup) 514 PIO[PIO_PUER / 4] = periph_b_mask; 515 else 516 PIO[PIO_PUDR / 4] = periph_b_mask; 517} 518 519void 520at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask) 521{ 522 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 523 524 PIO[PIO_PER / 4] = gpio_mask; 525} 526 527void 528at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask) 529{ 530 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 531 532 PIO[PIO_ODR / 4] = input_enable_mask; 533} 534 535void 536at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup) 537{ 538 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 539 540 PIO[PIO_OER / 4] = output_enable_mask; 541 if (use_pullup) 542 PIO[PIO_PUER / 4] = output_enable_mask; 543 else 544 PIO[PIO_PUDR / 4] = output_enable_mask; 545} 546 547void 548at91_pio_gpio_high_z(uint32_t pio, uint32_t high_z_mask, int enable) 549{ 550 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 551 552 if (enable) 553 PIO[PIO_MDER / 4] = high_z_mask; 554 else 555 PIO[PIO_MDDR / 4] = high_z_mask; 556} 557 558void 559at91_pio_gpio_set(uint32_t pio, uint32_t data_mask) 560{ 561 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 562 563 PIO[PIO_SODR / 4] = data_mask; 564} 565 566void 567at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask) 568{ 569 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 570 571 PIO[PIO_CODR / 4] = data_mask; 572} 573 574uint32_t 575at91_pio_gpio_get(uint32_t pio, uint32_t data_mask) 576{ 577 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 578 579 return (PIO[PIO_PDSR / 4] & data_mask); 580} 581 582void 583at91_pio_gpio_set_deglitch(uint32_t pio, uint32_t data_mask, int use_deglitch) 584{ 585 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 586 587 if (use_deglitch) 588 PIO[PIO_IFER / 4] = data_mask; 589 else 590 PIO[PIO_IFDR / 4] = data_mask; 591} 592 593void 594at91_pio_gpio_pullup(uint32_t pio, uint32_t data_mask, int do_pullup) 595{ 596 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 597 598 if (do_pullup) 599 PIO[PIO_PUER / 4] = data_mask; 600 else 601 PIO[PIO_PUDR / 4] = data_mask; 602} 603 604void 605at91_pio_gpio_set_interrupt(uint32_t pio, uint32_t data_mask, 606 int enable_interrupt) 607{ 608 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 609 610 if (enable_interrupt) 611 PIO[PIO_IER / 4] = data_mask; 612 else 613 PIO[PIO_IDR / 4] = data_mask; 614} 615 616uint32_t 617at91_pio_gpio_clear_interrupt(uint32_t pio) 618{ 619 uint32_t *PIO = (uint32_t *)(AT91_BASE + pio); 620 621 /* Reading this register will clear the interrupts. */ 622 return (PIO[PIO_ISR / 4]); 623} 624 625static void 626at91_pio_new_pass(device_t dev) 627{ 628 629 device_printf(dev, "Pass %d\n", bus_current_pass); 630} 631 632static device_method_t at91_pio_methods[] = { 633 /* Device interface */ 634 DEVMETHOD(device_probe, at91_pio_probe), 635 DEVMETHOD(device_attach, at91_pio_attach), 636 DEVMETHOD(device_detach, at91_pio_detach), 637 638 DEVMETHOD(bus_new_pass, at91_pio_new_pass), 639 640 DEVMETHOD_END 641}; 642 643static driver_t at91_pio_driver = { 644 "at91_pio", 645 at91_pio_methods, 646 sizeof(struct at91_pio_softc), 647}; 648 649#ifdef FDT 650EARLY_DRIVER_MODULE(at91_pio, at91_pinctrl, at91_pio_driver, at91_pio_devclass, 651 NULL, NULL, BUS_PASS_INTERRUPT); 652#else 653DRIVER_MODULE(at91_pio, atmelarm, at91_pio_driver, at91_pio_devclass, NULL, NULL); 654#endif 655