static int i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) { struct i2c_softc *sc; sc = device_get_softc(dev); vf_i2c_dbg(sc, "i2c reset\n"); switch (speed) { case IIC_FAST: case IIC_SLOW: case IIC_UNKNOWN: case IIC_FASTEST: default: break; } mtx_lock(&sc->mutex); WRITE1(sc, I2C_IBCR, IBCR_MDIS); DELAY(1000); WRITE1(sc, I2C_IBFD, 20); WRITE1(sc, I2C_IBCR, 0x0); /* Enable i2c */ DELAY(1000); mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static void auacer_halt(struct auacer_softc *sc, struct auacer_chan *chan) { uint32_t val; uint8_t port; uint32_t slot; port = chan->port; DPRINTF(ALI_DEBUG_API, ("auacer_halt: port=0x%x\n", port)); chan->intr = 0; slot = ALI_PORT2SLOT(port); val = READ4(sc, ALI_DMACR); val |= 1 << (slot+16); /* pause */ val &= ~(1 << slot); /* no start */ WRITE4(sc, ALI_DMACR, val); WRITE1(sc, port + ALI_OFF_CR, 0); while (READ1(sc, port + ALI_OFF_CR)) ; /* reset whole DMA things */ WRITE1(sc, port + ALI_OFF_CR, ALI_CR_RR); /* clear interrupts */ WRITE1(sc, port + ALI_OFF_SR, READ1(sc, port+ALI_OFF_SR) | ALI_SR_W1TC); WRITE4(sc, ALI_INTERRUPTSR, ALI_PORT2INTR(port)); }
static void auacer_setup_chan(struct auacer_softc *sc, struct auacer_chan *chan, uint32_t start, uint32_t size, uint32_t blksize, void (*intr)(void *), void *arg) { uint32_t port, slot; uint32_t offs, val; chan->start = start; chan->ptr = 0; chan->p = chan->start; chan->end = chan->start + size; chan->blksize = blksize; chan->ack = 0; chan->intr = intr; chan->arg = arg; auacer_add_entry(chan); auacer_add_entry(chan); port = chan->port; slot = ALI_PORT2SLOT(port); WRITE1(sc, port + ALI_OFF_CIV, 0); WRITE1(sc, port + ALI_OFF_LVI, (chan->ptr - 1) & ALI_LVI_MASK); offs = (char *)chan->dmalist - (char *)sc->sc_cdata; WRITE4(sc, port + ALI_OFF_BDBAR, sc->sc_cddma + offs); WRITE1(sc, port + ALI_OFF_CR, ALI_CR_IOCE | ALI_CR_FEIE | ALI_CR_LVBIE | ALI_CR_RPBM); val = READ4(sc, ALI_DMACR); val &= ~(1 << (slot+16)); /* no pause */ val |= 1 << slot; /* start */ WRITE4(sc, ALI_DMACR, val); }
static int i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) { struct i2c_softc *sc; int error; int reg; uint8_t d; sc = device_get_softc(dev); DPRINTF("i2c read\n"); reg = (RXTX_EN); reg |= (I2CMODE_MR << I2CMODE_S); reg |= I2C_START_STOP; WRITE1(sc, I2CSTAT, reg); *read = 0; mtx_lock(&sc->mutex); /* dummy read */ clear_ipend(sc); error = wait_for_iif(sc); if (error) { DPRINTF("cant i2c read: iif error\n"); mtx_unlock(&sc->mutex); return (error); } READ1(sc, I2CDS); DPRINTF("Read "); while (*read < len) { /* Do not ack last read */ if (*read == (len - 1)) { reg = READ1(sc, I2CCON); reg &= ~(ACKGEN); WRITE1(sc, I2CCON, reg); } clear_ipend(sc); error = wait_for_iif(sc); if (error) { DPRINTF("cant i2c read: iif error\n"); mtx_unlock(&sc->mutex); return (error); } d = READ1(sc, I2CDS); DPRINTF("0x%02x ", d); *buf++ = d; (*read)++; } DPRINTF("\n"); mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static int i2c_stop(device_t dev) { struct i2c_softc *sc; sc = device_get_softc(dev); vf_i2c_dbg(sc, "i2c stop\n"); mtx_lock(&sc->mutex); WRITE1(sc, I2C_IBCR, IBCR_NOACK | IBCR_IBIE); DELAY(100); /* Reset controller if bus still busy after STOP */ if (wait_for_nibb(sc) == IIC_ETIMEOUT) { WRITE1(sc, I2C_IBCR, IBCR_MDIS); DELAY(1000); WRITE1(sc, I2C_IBCR, IBCR_NOACK); } mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static int i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); vf_i2c_dbg(sc, "i2c read\n"); *read = 0; mtx_lock(&sc->mutex); if (len) { if (len == 1) WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | \ IBCR_NOACK); else WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL); /* dummy read */ READ1(sc, I2C_IBDR); DELAY(1000); } while (*read < len) { error = wait_for_icf(sc); if (error) { mtx_unlock(&sc->mutex); return (error); } if ((*read == len - 2) && last) { /* NO ACK on last byte */ WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_MSSL | \ IBCR_NOACK); } if ((*read == len - 1) && last) { /* Transfer done, remove master bit */ WRITE1(sc, I2C_IBCR, IBCR_IBIE | IBCR_NOACK); } *buf++ = READ1(sc, I2C_IBDR); (*read)++; } mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static int i2c_stop(device_t dev) { struct i2c_softc *sc; int reg; int error; sc = device_get_softc(dev); DPRINTF("i2c stop\n"); mtx_lock(&sc->mutex); reg = READ1(sc, I2CSTAT); int mode = (reg >> I2CMODE_S) & I2CMODE_M; reg = (RXTX_EN); reg |= (mode << I2CMODE_S); WRITE1(sc, I2CSTAT, reg); clear_ipend(sc); error = wait_for_nibb(sc); if (error) { DPRINTF("cant i2c stop: nibb error\n"); return (error); } mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static int i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); vf_i2c_dbg(sc, "i2c write\n"); *sent = 0; mtx_lock(&sc->mutex); while (*sent < len) { WRITE1(sc, I2C_IBDR, *buf++); error = wait_for_iif(sc); if (error) { mtx_unlock(&sc->mutex); return (error); } (*sent)++; } mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static int i2c_attach(device_t dev) { struct i2c_softc *sc; sc = device_get_softc(dev); sc->dev = dev; mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); if (bus_alloc_resources(dev, i2c_spec, sc->res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } /* Memory interface */ sc->bst = rman_get_bustag(sc->res[0]); sc->bsh = rman_get_bushandle(sc->res[0]); WRITE1(sc, I2C_IBIC, IBIC_BIIE); sc->iicbus = device_add_child(dev, "iicbus", -1); if (sc->iicbus == NULL) { device_printf(dev, "could not add iicbus child"); mtx_destroy(&sc->mutex); return (ENXIO); } bus_generic_attach(dev); return (0); }
static int i2c_start(device_t dev, u_char slave, int timeout) { struct i2c_softc *sc; int error; int reg; sc = device_get_softc(dev); vf_i2c_dbg(sc, "i2c start\n"); mtx_lock(&sc->mutex); WRITE1(sc, I2C_IBAD, slave); if (READ1(sc, I2C_IBSR) & IBSR_IBB) { mtx_unlock(&sc->mutex); vf_i2c_dbg(sc, "cant i2c start: IIC_EBUSBSY\n"); return (IIC_EBUSBSY); } /* Set start condition */ reg = (IBCR_MSSL | IBCR_NOACK | IBCR_IBIE); WRITE1(sc, I2C_IBCR, reg); DELAY(100); reg |= (IBCR_TXRX); WRITE1(sc, I2C_IBCR, reg); /* Write target address - LSB is R/W bit */ WRITE1(sc, I2C_IBDR, slave); error = wait_for_iif(sc); mtx_unlock(&sc->mutex); if (error) { vf_i2c_dbg(sc, "cant i2c start: iif error\n"); return (error); } return (IIC_NOERR); }
static int clear_ipend(struct i2c_softc *sc) { int reg; reg = READ1(sc, I2CCON); reg &= ~(IPEND); WRITE1(sc, I2CCON, reg); return (0); }
static int i2c_repeated_start(device_t dev, u_char slave, int timeout) { struct i2c_softc *sc; int error; int reg; sc = device_get_softc(dev); vf_i2c_dbg(sc, "i2c repeated start\n"); mtx_lock(&sc->mutex); WRITE1(sc, I2C_IBAD, slave); if ((READ1(sc, I2C_IBSR) & IBSR_IBB) == 0) { mtx_unlock(&sc->mutex); return (IIC_EBUSBSY); } /* Set repeated start condition */ DELAY(10); reg = READ1(sc, I2C_IBCR); reg |= (IBCR_RSTA | IBCR_IBIE); WRITE1(sc, I2C_IBCR, reg); DELAY(10); /* Write target address - LSB is R/W bit */ WRITE1(sc, I2C_IBDR, slave); error = wait_for_iif(sc); mtx_unlock(&sc->mutex); if (error) return (error); return (IIC_NOERR); }
static int i2c_attach(device_t dev) { struct i2c_softc *sc; int reg; sc = device_get_softc(dev); sc->dev = dev; mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF); if (bus_alloc_resources(dev, i2c_spec, sc->res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } /* Memory interface */ sc->bst = rman_get_bustag(sc->res[0]); sc->bsh = rman_get_bushandle(sc->res[0]); sc->iicbus = device_add_child(dev, "iicbus", -1); if (sc->iicbus == NULL) { device_printf(dev, "could not add iicbus child"); mtx_destroy(&sc->mutex); return (ENXIO); } WRITE1(sc, I2CSTAT, 0); WRITE1(sc, I2CADD, 0x00); /* Mode */ reg = (RXTX_EN); reg |= (I2CMODE_MT << I2CMODE_S); WRITE1(sc, I2CSTAT, reg); bus_generic_attach(dev); return (0); }
/* Wait for transfer interrupt flag */ static int wait_for_iif(struct i2c_softc *sc) { int retry; retry = 1000; while (retry --) { if (READ1(sc, I2C_IBSR) & IBSR_IBIF) { WRITE1(sc, I2C_IBSR, IBSR_IBIF); return (IIC_NOERR); } DELAY(10); } return (IIC_ETIMEOUT); }
static void edma_err_intr(void *arg) { struct edma_softc *sc; int reg; sc = arg; reg = READ4(sc, DMA_ERR); #if 0 device_printf(sc->dev, "DMA_ERR 0x%08x, ES 0x%08x\n", reg, READ4(sc, DMA_ES)); #endif WRITE1(sc, DMA_CERR, CERR_CAEI); }
static int i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); DPRINTF("i2c write\n"); *sent = 0; mtx_lock(&sc->mutex); DPRINTF("writing "); while (*sent < len) { uint8_t d = *buf++; DPRINTF("0x%02x ", d); WRITE1(sc, I2CDS, d); DELAY(50); clear_ipend(sc); error = wait_for_iif(sc); if (error) { DPRINTF("cant i2c write: iif error\n"); mtx_unlock(&sc->mutex); return (error); } if (!is_ack(sc)) { DPRINTF("cant i2c write: no ack\n"); mtx_unlock(&sc->mutex); return (IIC_ENOACK); } (*sent)++; } DPRINTF("\n"); mtx_unlock(&sc->mutex); return (IIC_NOERR); }
static void auacer_upd_chan(struct auacer_softc *sc, struct auacer_chan *chan) { uint32_t sts; uint32_t civ; sts = READ2(sc, chan->port + ALI_OFF_SR); /* intr ack */ WRITE2(sc, chan->port + ALI_OFF_SR, sts & ALI_SR_W1TC); WRITE4(sc, ALI_INTERRUPTSR, ALI_PORT2INTR(chan->port)); DPRINTF(ALI_DEBUG_INTR, ("auacer_upd_chan: sts=0x%x\n", sts)); if (sts & ALI_SR_DMA_INT_FIFO) { printf("%s: fifo underrun # %u\n", device_xname(&sc->sc_dev), ++chan->fifoe); } civ = READ1(sc, chan->port + ALI_OFF_CIV); DPRINTF(ALI_DEBUG_INTR,("auacer_intr: civ=%u ptr=%u\n",civ,chan->ptr)); /* XXX */ while (chan->ptr != civ) { auacer_add_entry(chan); } WRITE1(sc, chan->port + ALI_OFF_LVI, (chan->ptr - 1) & ALI_LVI_MASK); while (chan->ack != civ) { if (chan->intr) { DPRINTF(ALI_DEBUG_INTR,("auacer_upd_chan: callback\n")); chan->intr(chan->arg); } chan->ack++; if (chan->ack >= ALI_DMALIST_MAX) chan->ack = 0; } }
static void edma_transfer_complete_intr(void *arg) { struct edma_channel *ch; struct edma_softc *sc; int interrupts; int i; sc = arg; interrupts = READ4(sc, DMA_INT); WRITE1(sc, DMA_CINT, CINT_CAIR); for (i = 0; i < EDMA_NUM_CHANNELS; i++) { if (interrupts & (0x1 << i)) { ch = &edma_map[i]; if (ch->enabled == 1) { if (ch->ih != NULL) { ch->ih(ch->ih_user, i); } } } } }
void fbGlyph24(FbBits * dstBits, FbStride dstStride, int dstBpp, FbStip * stipple, FbBits fg, int x, int height) { int lshift; FbStip bits; CARD8 *dstLine; CARD8 *dst; FbStip f0, f1, f2; int n; int shift; f0 = fg; f1 = FbRot24(f0, 16); f2 = FbRot24(f0, 8); dstLine = (CARD8 *) dstBits; dstLine += (x & ~3) * 3; dstStride *= (sizeof(FbBits) / sizeof(CARD8)); shift = x & 3; lshift = 4 - shift; while (height--) { bits = *stipple++; n = lshift; dst = dstLine; while (bits) { switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) { case CASE(0, 0, 0, 0): break; case CASE(1, 0, 0, 0): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); break; case CASE(0, 1, 0, 0): WRITE1(dst, 3, _A); WRITE2(dst, 4, _BC); break; case CASE(1, 1, 0, 0): WRITE4(dst, 0, _ABCA); WRITE2(dst, 4, _BC); break; case CASE(0, 0, 1, 0): WRITE2(dst, 6, _AB); WRITE1(dst, 8, _C); break; case CASE(1, 0, 1, 0): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); WRITE2(dst, 6, _AB); WRITE1(dst, 8, _C); break; case CASE(0, 1, 1, 0): WRITE1(dst, 3, _A); WRITE4(dst, 4, _BCAB); WRITE1(dst, 8, _C); break; case CASE(1, 1, 1, 0): WRITE8(dst); WRITE1(dst, 8, _C); break; case CASE(0, 0, 0, 1): WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(1, 0, 0, 1): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(0, 1, 0, 1): WRITE1(dst, 3, _A); WRITE2(dst, 4, _BC); WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(1, 1, 0, 1): WRITE4(dst, 0, _ABCA); WRITE2(dst, 4, _BC); WRITE1(dst, 9, _A); WRITE2(dst, 10, _BC); break; case CASE(0, 0, 1, 1): WRITE2(dst, 6, _AB); WRITE4(dst, 8, _CABC); break; case CASE(1, 0, 1, 1): WRITE2(dst, 0, _AB); WRITE1(dst, 2, _C); WRITE2(dst, 6, _AB); WRITE4(dst, 8, _CABC); break; case CASE(0, 1, 1, 1): WRITE1(dst, 3, _A); WRITE4(dst, 4, _BCAB); WRITE4(dst, 8, _CABC); break; case CASE(1, 1, 1, 1): WRITE8(dst); WRITE4(dst, 8, _CABC); break; } bits = FbStipLeft(bits, n); n = 4; dst += 12; } dstLine += dstStride; } }
static int i2c_start(device_t dev, u_char slave, int timeout) { struct i2c_softc *sc; int error; int reg; sc = device_get_softc(dev); DPRINTF("i2c start\n"); mtx_lock(&sc->mutex); #if 0 DPRINTF("I2CCON == 0x%08x\n", READ1(sc, I2CCON)); DPRINTF("I2CSTAT == 0x%08x\n", READ1(sc, I2CSTAT)); #endif if (slave & 1) { slave &= ~(1); slave <<= 1; slave |= 1; } else { slave <<= 1; } error = wait_for_nibb(sc); if (error) { mtx_unlock(&sc->mutex); DPRINTF("cant i2c start: IIC_EBUSERR\n"); return (IIC_EBUSERR); } reg = READ1(sc, I2CCON); reg |= (IRQ_EN | ACKGEN); WRITE1(sc, I2CCON, reg); WRITE1(sc, I2CDS, slave); DELAY(50); reg = (RXTX_EN); reg |= I2C_START_STOP; reg |= (I2CMODE_MT << I2CMODE_S); WRITE1(sc, I2CSTAT, reg); error = wait_for_iif(sc); if (error) { DPRINTF("cant i2c start: iif error\n"); mtx_unlock(&sc->mutex); return (error); } if (!is_ack(sc)) { DPRINTF("cant i2c start: no ack\n"); mtx_unlock(&sc->mutex); return (IIC_ENOACK); } mtx_unlock(&sc->mutex); return (IIC_NOERR); }