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; }
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; }
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; }
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; }
/* * 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; }
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; }
/* * 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; }
/* * 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; }
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; }
/* * 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; }