コード例 #1
0
ファイル: i2c.c プロジェクト: ChaosJohn/freebsd
static int
i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
{
	struct i2c_softc *sc;
	int error, reg;

	sc = device_get_softc(dev);
	*read = 0;

	mtx_lock(&sc->mutex);

	if (len) {
		if (len == 1)
			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
			    I2CCR_MSTA | I2CCR_TXAK);

		else
			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
			    I2CCR_MSTA);

		/* dummy read */
		i2c_read_reg(sc, I2C_DATA_REG);
		DELAY(1000);
	}

	while (*read < len) {
		error = wait_for_icf(sc);
		if (error) {
			mtx_unlock(&sc->mutex);
			return (error);
		}
		i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
		if ((*read == len - 2) && last) {
			/* NO ACK on last byte */
			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
			    I2CCR_MSTA | I2CCR_TXAK);
		}

		if ((*read == len - 1) && last) {
			/* Transfer done, remove master bit */
			i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
			    I2CCR_TXAK);
		}

		reg = i2c_read_reg(sc, I2C_DATA_REG);
		*buf++ = reg;
		(*read)++;
	}
	mtx_unlock(&sc->mutex);

	return (IIC_NOERR);
}
コード例 #2
0
ファイル: vf_i2c.c プロジェクト: Alkzndr/freebsd
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);
}