void * omgpio_intr_establish(unsigned int gpio, int level, int spl, int (*func)(void *), void *arg, char *name) { int psw; struct intrhand *ih; struct omgpio_softc *sc; /* * XXX - is gpio here the pin or the interrupt number * which is 96 + gpio pin? */ if (GPIO_PIN_TO_INST(gpio) > NOMGPIO) panic("omgpio_intr_establish: bogus irqnumber %d: %s", gpio, name); sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; if (sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] != NULL) panic("omgpio_intr_establish: gpio pin busy %d old %s new %s", gpio, sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)]->ih_name, name); psw = disable_interrupts(I32_bit); /* no point in sleeping unless someone can free memory. */ ih = (struct intrhand *)malloc( sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK); if (ih == NULL) panic("intr_establish: can't malloc handler info"); ih->ih_func = func; ih->ih_arg = arg; ih->ih_ipl = level; ih->ih_gpio = gpio; ih->ih_irq = gpio + INTC_NUM_IRQ; ih->ih_name = name; sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = ih; evcount_attach(&ih->ih_count, name, &ih->ih_irq); omgpio_intr_level(gpio, level); omgpio_intr_unmask(gpio); omgpio_recalc_interrupts(sc); restore_interrupts(psw); return (ih); }
void imxgpio_set_dir(unsigned int gpio, unsigned int dir) { struct imxgpio_softc *sc = imxgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; sc->sc_set_dir(sc, gpio, dir); }
void omgpio_intr_unmask(struct omgpio_softc *sc, unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; WRITE4(sc, sc->sc_regs.irqstatus_set0, 1 << GPIO_PIN_TO_OFFSET(gpio)); }
void imxgpio_clear_bit(unsigned int gpio) { struct imxgpio_softc *sc = imxgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; sc->sc_clear_bit(sc, gpio); }
void omgpio_set_dir(unsigned int gpio, unsigned int dir) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; omgpio_pin_dir_write(sc, GPIO_PIN_TO_OFFSET(gpio), dir); }
void omgpio_clear_bit(unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_LOW); }
unsigned int omgpio_get_bit(unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; return omgpio_pin_read(sc, GPIO_PIN_TO_OFFSET(gpio)); }
void omgpio_intr_unmask(unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_SETIRQENABLE1, 1 << GPIO_PIN_TO_OFFSET(gpio)); }
void omgpio_clear_intr(unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_IRQSTATUS1, 1 << GPIO_PIN_TO_OFFSET(gpio)); }
void omgpio_clear_bit(unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_CLEARDATAOUT, 1 << GPIO_PIN_TO_OFFSET(gpio)); }
unsigned int imxgpio_get_bit(unsigned int gpio) { struct imxgpio_softc *sc = imxgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; return sc->sc_get_bit(sc, gpio); }
unsigned int omgpio_get_bit(unsigned int gpio) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; u_int32_t reg; reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_DATAIN); return (reg >> GPIO_PIN_TO_OFFSET(gpio)) & 0x1; }
void omgpio_set_dir(unsigned int gpio, unsigned int dir) { struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; int s; u_int32_t reg; s = splhigh(); reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_DATAIN); if (dir == OMGPIO_DIR_IN) reg |= 1 << GPIO_PIN_TO_OFFSET(gpio); else reg &= ~(1 << GPIO_PIN_TO_OFFSET(gpio)); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_OE, reg); splx(s); }
void omgpio_intr_disestablish(void *cookie) { int psw; struct intrhand *ih = cookie; struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(ih->ih_gpio)]; int gpio = ih->ih_gpio; psw = disable_interrupts(I32_bit); ih = sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)]; sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = NULL; evcount_detach(&ih->ih_count); free(ih, M_DEVBUF); omgpio_intr_level(gpio, IST_NONE); omgpio_intr_mask(gpio); omgpio_clear_intr(gpio); /* Just in case */ omgpio_recalc_interrupts(sc); restore_interrupts(psw); }
void omgpio_intr_level(unsigned int gpio, unsigned int level) { u_int32_t fe, re, l0, l1, bit; struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; int s; s = splhigh(); fe = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_FALLINGDETECT); re = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_RISINGDETECT); l0 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT0); l1 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT1); bit = 1 << GPIO_PIN_TO_OFFSET(gpio); switch (level) { case IST_NONE: fe &= ~bit; re &= ~bit; l0 &= ~bit; l1 &= ~bit; break; case IST_EDGE_FALLING: fe |= bit; re &= ~bit; l0 &= ~bit; l1 &= ~bit; break; case IST_EDGE_RISING: fe &= ~bit; re |= bit; l0 &= ~bit; l1 &= ~bit; break; case IST_PULSE: /* XXX */ /* FALLTHRU */ case IST_EDGE_BOTH: fe |= bit; re |= bit; l0 &= ~bit; l1 &= ~bit; break; case IST_LEVEL_LOW: fe &= ~bit; re &= ~bit; l0 |= bit; l1 &= ~bit; break; case IST_LEVEL_HIGH: fe &= ~bit; re &= ~bit; l0 &= ~bit; l1 |= bit; break; break; default: panic("omgpio_intr_level: bad level: %d", level); break; } bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_FALLINGDETECT, fe); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_RISINGDETECT, re); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT0, l0); bus_space_write_4(sc->sc_iot, sc->sc_ioh, GPIO_LEVELDETECT1, l1); splx(s); }
void omgpio_intr_level(struct omgpio_softc *sc, unsigned int gpio, unsigned int level) { u_int32_t fe, re, l0, l1, bit; struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; int s; s = splhigh(); fe = READ4(sc, sc->sc_regs.fallingdetect); re = READ4(sc, sc->sc_regs.risingdetect); l0 = READ4(sc, sc->sc_regs.leveldetect0); l1 = READ4(sc, sc->sc_regs.leveldetect1); bit = 1 << GPIO_PIN_TO_OFFSET(gpio); switch (level) { case IST_NONE: fe &= ~bit; re &= ~bit; l0 &= ~bit; l1 &= ~bit; break; case IST_EDGE_FALLING: fe |= bit; re &= ~bit; l0 &= ~bit; l1 &= ~bit; break; case IST_EDGE_RISING: fe &= ~bit; re |= bit; l0 &= ~bit; l1 &= ~bit; break; case IST_PULSE: /* XXX */ /* FALLTHRU */ case IST_EDGE_BOTH: fe |= bit; re |= bit; l0 &= ~bit; l1 &= ~bit; break; case IST_LEVEL_LOW: fe &= ~bit; re &= ~bit; l0 |= bit; l1 &= ~bit; break; case IST_LEVEL_HIGH: fe &= ~bit; re &= ~bit; l0 &= ~bit; l1 |= bit; break; default: panic("omgpio_intr_level: bad level: %d", level); break; } WRITE4(sc, sc->sc_regs.fallingdetect, fe); WRITE4(sc, sc->sc_regs.risingdetect, re); WRITE4(sc, sc->sc_regs.leveldetect0, l0); WRITE4(sc, sc->sc_regs.leveldetect1, l1); splx(s); }