Esempio n. 1
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. 2
0
static int i2c_imx_xfer(struct i2c_adapter *adapter,
                        struct i2c_msg *msgs, int num)
{
    unsigned int i, temp;
    int result;
    struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter);

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

    /* Start I2C transfer */
    result = i2c_imx_start(i2c_imx);
    if (result)
        goto fail0;

    /* read/write data */
    for (i = 0; i < num; i++) {
        if (i) {
            dev_dbg(&i2c_imx->adapter.dev,
                    "<%s> repeated start\n", __func__);
            temp = readb(i2c_imx->base + IMX_I2C_I2CR);
            temp |= I2CR_RSTA;
            writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
            result =  i2c_imx_bus_busy(i2c_imx, 1);
            if (result)
                goto fail0;
        }
        dev_dbg(&i2c_imx->adapter.dev,
                "<%s> transfer message: %d\n", __func__, i);
        /* write/read data */
#ifdef CONFIG_I2C_DEBUG_BUS
        temp = readb(i2c_imx->base + IMX_I2C_I2CR);
        dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, "
                "MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
                (temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
                (temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
                (temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0));
        temp = readb(i2c_imx->base + IMX_I2C_I2SR);
        dev_dbg(&i2c_imx->adapter.dev,
                "<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
                "IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__,
                (temp & I2SR_ICF ? 1 : 0), (temp & I2SR_IAAS ? 1 : 0),
                (temp & I2SR_IBB ? 1 : 0), (temp & I2SR_IAL ? 1 : 0),
                (temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0),
                (temp & I2SR_RXAK ? 1 : 0));
#endif
        if (msgs[i].flags & I2C_M_RD)
            result = i2c_imx_read(i2c_imx, &msgs[i]);
        else
            result = i2c_imx_write(i2c_imx, &msgs[i]);
    }

fail0:
    /* Stop I2C transfer */
    i2c_imx_stop(i2c_imx);

    dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__,
            (result < 0) ? "error" : "success msg",
            (result < 0) ? result : num);
    return (result < 0) ? result : num;
}
Esempio n. 3
0
/*
 * Try if a chip add given address responds (probe the chip)
 */
int i2c_probe(uchar chip)
{
	int ret;

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

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

	i2c_imx_stop();

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

	/* Start I2C transfer */
	result = i2c_imx_start(adapter);
	if (result)
		goto fail0;

	/* read/write data */
	for (i = 0; i < num; i++) {
		if (i && !(msgs[i].flags & I2C_M_DATA_ONLY)) {
			temp = readb(base + IMX_I2C_I2CR);
			temp |= I2CR_RSTA;
			writeb(temp, base + IMX_I2C_I2CR);

			result = i2c_imx_bus_busy(adapter, 1);
			if (result)
				goto fail0;
		}
		i2c_imx_dump_reg(adapter);

		/* write/read data */
		if (msgs[i].flags & I2C_M_RD)
			result = i2c_imx_read(adapter, &msgs[i]);
		else
			result = i2c_imx_write(adapter, &msgs[i]);
		if (result)
			goto fail0;
	}

fail0:
	/* Stop I2C transfer */
	i2c_imx_stop(adapter);

	return (result < 0) ? result : num;
}
Esempio n. 5
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;
}