Esempio n. 1
0
static int i2c_imx_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
{
	unsigned long base = adapter->dev->map_base;
	int i, result;

	dev_dbg(adapter->dev,
		"<%s> write slave address: addr=0x%02x\n",
		__func__, msgs->addr << 1);

	/* write slave address */
	writeb(msgs->addr << 1, base + IMX_I2C_I2DR);

	result = i2c_imx_trx_complete(adapter);
	if (result)
		return result;
	result = i2c_imx_acked(adapter);
	if (result)
		return result;

	/* write data */
	for (i = 0; i < msgs->len; i++) {
		dev_dbg(adapter->dev,
			"<%s> write byte: B%d=0x%02X\n",
			__func__, i, msgs->buf[i]);
		writeb(msgs->buf[i], base + IMX_I2C_I2DR);

		result = i2c_imx_trx_complete(adapter);
		if (result)
			return result;
		result = i2c_imx_acked(adapter);
		if (result)
			return result;
	}
	return 0;
}
Esempio n. 2
0
static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
{
	int i, result;

	dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n",
		__func__, msgs->addr << 1);

	/* write slave address */
	writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR);
	result = i2c_imx_trx_complete(i2c_imx);
	if (result)
		return result;
	result = i2c_imx_acked(i2c_imx);
	if (result)
		return result;
	dev_dbg(&i2c_imx->adapter.dev, "<%s> write data\n", __func__);

	/* write data */
	for (i = 0; i < msgs->len; i++) {
		dev_dbg(&i2c_imx->adapter.dev,
			"<%s> write byte: B%d=0x%X\n",
			__func__, i, msgs->buf[i]);
		writeb(msgs->buf[i], i2c_imx->base + IMX_I2C_I2DR);
		result = i2c_imx_trx_complete(i2c_imx);
		if (result)
			return result;
		result = i2c_imx_acked(i2c_imx);
		if (result)
			return result;
	}
	return 0;
}
Esempio n. 3
0
static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
{
	int i, result;
	unsigned int temp;

	dev_dbg(&i2c_imx->adapter.dev,
		"<%s> write slave address: addr=0x%x\n",
		__func__, (msgs->addr << 1) | 0x01);

	/* write slave address */
	writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR);
	result = i2c_imx_trx_complete(i2c_imx);
	if (result)
		return result;
	result = i2c_imx_acked(i2c_imx);
	if (result)
		return result;

	dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);

	/* setup bus to read data */
	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
	temp &= ~I2CR_MTX;
	if (msgs->len - 1)
		temp &= ~I2CR_TXAK;
	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
	readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */

	dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);

	/* read data */
	for (i = 0; i < msgs->len; i++) {
		result = i2c_imx_trx_complete(i2c_imx);
		if (result)
			return result;
		if (i == (msgs->len - 1)) {
			/* It must generate STOP before read I2DR to prevent
			   controller from generating another clock cycle */
			dev_dbg(&i2c_imx->adapter.dev,
				"<%s> clear MSTA\n", __func__);
			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
			temp &= ~(I2CR_MSTA | I2CR_MTX);
			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
			i2c_imx_bus_busy(i2c_imx, 0);
			i2c_imx->stopped = 1;
		} else if (i == (msgs->len - 2)) {
			dev_dbg(&i2c_imx->adapter.dev,
				"<%s> set TXAK\n", __func__);
			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
			temp |= I2CR_TXAK;
			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
		}
		msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR);
		dev_dbg(&i2c_imx->adapter.dev,
			"<%s> read byte: B%d=0x%X\n",
			__func__, i, msgs->buf[i]);
	}
	return 0;
}
Esempio n. 4
0
static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
{
	int i, result;
	unsigned int temp;

	dev_dbg(&i2c_imx->adapter.dev,
		"<%s> write slave address: addr=0x%x\n",
		__func__, (msgs->addr << 1) | 0x01);

	/* write slave address */
	writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR);
	result = i2c_imx_trx_complete(i2c_imx);
	if (result)
		return result;
	result = i2c_imx_acked(i2c_imx);
	if (result)
		return result;

	dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);

	/* setup bus to read data */
	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
	temp &= ~I2CR_MTX;
	if (msgs->len - 1)
		temp &= ~I2CR_TXAK;
	writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
	readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */

	dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);

	/* read data */
	for (i = 0; i < msgs->len; i++) {
		result = i2c_imx_trx_complete(i2c_imx);
		if (result)
			return result;
		if (i == (msgs->len - 1)) {
			dev_dbg(&i2c_imx->adapter.dev,
				"<%s> clear MSTA\n", __func__);
			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
			temp &= ~I2CR_MSTA;
			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
		} else if (i == (msgs->len - 2)) {
			dev_dbg(&i2c_imx->adapter.dev,
				"<%s> set TXAK\n", __func__);
			temp = readb(i2c_imx->base + IMX_I2C_I2CR);
			temp |= I2CR_TXAK;
			writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
		}
		msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR);
		dev_dbg(&i2c_imx->adapter.dev,
			"<%s> read byte: B%d=0x%X\n",
			__func__, i, msgs->buf[i]);
	}
	return 0;
}
Esempio n. 5
0
/*
 * Write data to I2C device
 */
int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
{
	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
	int ret;
	int i;

	ret = i2c_imx_start();
	if (ret)
		return ret;

	/* write slave address */
	ret = i2c_imx_set_chip_addr(chip, 0);
	if (ret)
		return ret;

	ret = i2c_imx_set_reg_addr(addr, alen);
	if (ret)
		return ret;

	for (i = 0; i < len; i++) {
		writeb(buf[i], &i2c_regs->i2dr);

		ret = i2c_imx_trx_complete();
		if (ret)
			return ret;

		ret = i2c_imx_acked();
		if (ret)
			return ret;
	}

	i2c_imx_stop();

	return ret;
}
Esempio n. 6
0
static int i2c_imx_write(struct i2c_adapter *adapter, struct i2c_msg *msgs)
{
	struct imx_i2c_struct *i2c_imx = to_imx_i2c_struct(adapter);
	void __iomem *base = i2c_imx->base;
	int i, result;

	if ( !(msgs->flags & I2C_M_DATA_ONLY) ) {
		dev_dbg(adapter->dev,
			"<%s> write slave address: addr=0x%02x\n",
			__func__, msgs->addr << 1);

		/* write slave address */
		writeb(msgs->addr << 1, base + IMX_I2C_I2DR);

		result = i2c_imx_trx_complete(adapter);
		if (result)
			return result;
		result = i2c_imx_acked(adapter);
		if (result)
			return result;
	}

	/* write data */
	for (i = 0; i < msgs->len; i++) {
		dev_dbg(adapter->dev,
			"<%s> write byte: B%d=0x%02X\n",
			__func__, i, msgs->buf[i]);
		writeb(msgs->buf[i], base + IMX_I2C_I2DR);

		result = i2c_imx_trx_complete(adapter);
		if (result)
			return result;
		result = i2c_imx_acked(adapter);
		if (result)
			return result;
	}
	return 0;
}
Esempio n. 7
0
/*
 * Set chip address and access mode
 *
 * read = 1: READ access
 * read = 0: WRITE access
 */
int i2c_imx_set_chip_addr(uchar chip, int read)
{
	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
	int ret;

	writeb((chip << 1) | read, &i2c_regs->i2dr);

	ret = i2c_imx_trx_complete();
	if (ret)
		return ret;

	ret = i2c_imx_acked();
	if (ret)
		return ret;

	return ret;
}
Esempio n. 8
0
/*
 * Write register address
 */
int i2c_imx_set_reg_addr(uint addr, int alen)
{
	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
	int ret;
	int i;

	for (i = 0; i < (8 * alen); i += 8) {
		writeb((addr >> i) & 0xff, &i2c_regs->i2dr);

		ret = i2c_imx_trx_complete();
		if (ret)
			break;

		ret = i2c_imx_acked();
		if (ret)
			break;
	}

	return ret;
}
Esempio n. 9
0
static int i2c_imx_read(struct i2c_adapter *adapter, struct i2c_msg *msgs)
{
	struct imx_i2c_struct *i2c_imx = to_imx_i2c_struct(adapter);
	unsigned long base = adapter->dev->map_base;
	int i, result;
	unsigned int temp;

	dev_dbg(adapter->dev,
		"<%s> write slave address: addr=0x%02x\n",
		__func__, (msgs->addr << 1) | 0x01);

	/* clear IIF */
	writeb(0x0, base + IMX_I2C_I2SR);

	/* write slave address */
	writeb((msgs->addr << 1) | 0x01, base + IMX_I2C_I2DR);

	result = i2c_imx_trx_complete(adapter);
	if (result)
		return result;
	result = i2c_imx_acked(adapter);
	if (result)
		return result;

	result = i2c_imx_wait_iif(adapter);
	if (result)
		return result;

	/* setup bus to read data */
	temp = readb(base + IMX_I2C_I2CR);
	temp &= ~I2CR_MTX;
	if (msgs->len - 1)
		temp &= ~I2CR_TXAK;
	writeb(temp, base + IMX_I2C_I2CR);

	readb(base + IMX_I2C_I2DR);	/* dummy read */

	/* read data */
	for (i = 0; i < msgs->len; i++) {
		result = i2c_imx_trx_complete(adapter);
		if (result)
			return result;

		if (i == (msgs->len - 1)) {
			/*
			 * It must generate STOP before read I2DR to prevent
			 * controller from generating another clock cycle
			 */
			temp = readb(base + IMX_I2C_I2CR);
			temp &= ~(I2CR_MSTA | I2CR_MTX);
			writeb(temp, base + IMX_I2C_I2CR);

			/*
			 * adding this delay helps on low bitrates
			 */
			udelay(i2c_imx->disable_delay);

			i2c_imx_bus_busy(adapter, 0);
			i2c_imx->stopped = 1;
		} else if (i == (msgs->len - 2)) {
			temp = readb(base + IMX_I2C_I2CR);
			temp |= I2CR_TXAK;
			writeb(temp, base + IMX_I2C_I2CR);
		}
		msgs->buf[i] = readb(base + IMX_I2C_I2DR);

		dev_dbg(adapter->dev, "<%s> read byte: B%d=0x%02X\n",
			__func__, i, msgs->buf[i]);
	}
	return 0;
}
Esempio n. 10
0
/*
 * Read data from I2C device
 */
int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
{
	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
	int ret;
	unsigned int temp;
	int i;

	ret = i2c_imx_start();
	if (ret)
		return ret;

	/* write slave address */
	ret = i2c_imx_set_chip_addr(chip, 0);
	if (ret)
		return ret;

	ret = i2c_imx_set_reg_addr(addr, alen);
	if (ret)
		return ret;

	temp = readb(&i2c_regs->i2cr);
	temp |= I2CR_RSTA;
	writeb(temp, &i2c_regs->i2cr);

	ret = i2c_imx_set_chip_addr(chip, 1);
	if (ret)
		return ret;

	/* setup bus to read data */
	temp = readb(&i2c_regs->i2cr);
	temp &= ~(I2CR_MTX | I2CR_TX_NO_AK);
	if (len == 1)
		temp |= I2CR_TX_NO_AK;
	writeb(temp, &i2c_regs->i2cr);
	readb(&i2c_regs->i2dr);

	/* read data */
	for (i = 0; i < len; i++) {
		ret = i2c_imx_trx_complete();
		if (ret)
			return ret;

		/*
		 * It must generate STOP before read I2DR to prevent
		 * controller from generating another clock cycle
		 */
		if (i == (len - 1)) {
			temp = readb(&i2c_regs->i2cr);
			temp &= ~(I2CR_MSTA | I2CR_MTX);
			writeb(temp, &i2c_regs->i2cr);
			i2c_imx_bus_busy(0);
		} else if (i == (len - 2)) {
			temp = readb(&i2c_regs->i2cr);
			temp |= I2CR_TX_NO_AK;
			writeb(temp, &i2c_regs->i2cr);
		}

		buf[i] = readb(&i2c_regs->i2dr);
	}

	i2c_imx_stop();

	return ret;
}