示例#1
0
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);
}
示例#2
0
文件: i2c.c 项目: ChaosJohn/freebsd
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);
}
示例#3
0
文件: i2c.c 项目: ChaosJohn/freebsd
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);
}
示例#4
0
文件: vf_i2c.c 项目: Alkzndr/freebsd
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);
}
示例#5
0
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);
}
示例#6
0
文件: vf_i2c.c 项目: Alkzndr/freebsd
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);
}
示例#7
0
文件: vf_i2c.c 项目: Alkzndr/freebsd
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);
}
示例#8
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);

	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);
}