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_write(device_t dev, const char *buf, int len, int *sent, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); *sent = 0; mtx_lock(&sc->mutex); while (*sent < len) { i2c_write_reg(sc, I2C_STATUS_REG, 0x0); i2c_write_reg(sc, I2C_DATA_REG, *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_start(device_t dev, u_char slave, int timeout) { struct i2c_softc *sc; int error; sc = device_get_softc(dev); mtx_lock(&sc->mutex); i2c_write_reg(sc, I2C_ADDR_REG, slave); if (i2c_read_reg(sc, I2C_STATUS_REG) & I2CSR_MBB) { mtx_unlock(&sc->mutex); return (IIC_EBUSBSY); } /* Set start condition */ i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_TXAK); DELAY(100); i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX | I2CCR_TXAK); /* Clear status */ i2c_write_reg(sc, I2C_STATUS_REG, 0x0); /* Write target address - LSB is R/W bit */ i2c_write_reg(sc, I2C_DATA_REG, slave); error = wait_for_iif(sc); mtx_unlock(&sc->mutex); if (error) return (error); 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_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 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 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_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); }