diff options
author | Troy Kisky <troy.kisky@boundarydevices.com> | 2012-07-19 08:18:13 +0000 |
---|---|---|
committer | Heiko Schocher <hs@denx.de> | 2012-07-31 07:51:22 +0200 |
commit | 90a5b70f5914a3ac79cac3dd386cc98ce42bfd8e (patch) | |
tree | 1c43dd1c828f9b59a4d7fb9104bb0e685cce584c /drivers/i2c | |
parent | 83a1a19038b0bf36c966b7c7b67708e19b45c3b5 (diff) | |
download | u-boot-90a5b70f5914a3ac79cac3dd386cc98ce42bfd8e.tar.gz u-boot-90a5b70f5914a3ac79cac3dd386cc98ce42bfd8e.tar.xz u-boot-90a5b70f5914a3ac79cac3dd386cc98ce42bfd8e.zip |
mxc_i2c: don't disable controller after every transaction
This helps in a multiple bus master environment which
is why I also added a wait for bus idle.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/mxc_i2c.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index 717bc7ae01..1a5e379c2f 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -192,24 +192,19 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte) } /* - * Stop the controller + * Stop I2C transaction */ void i2c_imx_stop(void) { int ret; struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE; - unsigned int temp = 0; + unsigned int temp = readb(&i2c_regs->i2cr); - /* Stop I2C transaction */ - temp = readb(&i2c_regs->i2cr); temp &= ~(I2CR_MSTA | I2CR_MTX); writeb(temp, &i2c_regs->i2cr); - ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE); if (ret < 0) printf("%s:trigger stop failed\n", __func__); - /* Disable I2C controller */ - writeb(0, &i2c_regs->i2cr); } /* @@ -223,11 +218,15 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, int ret; /* Enable I2C controller */ + if (!(readb(&i2c_regs->i2cr) & I2CR_IEN)) { + writeb(I2CR_IEN, &i2c_regs->i2cr); + /* Wait for controller to be stable */ + udelay(50); + } writeb(0, &i2c_regs->i2sr); - writeb(I2CR_IEN, &i2c_regs->i2cr); - - /* Wait for controller to be stable */ - udelay(50); + ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE); + if (ret < 0) + goto exit; /* Start I2C transaction */ temp = readb(&i2c_regs->i2cr); @@ -254,6 +253,8 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs, return 0; exit: i2c_imx_stop(); + /* Disable I2C controller */ + writeb(0, &i2c_regs->i2cr); return ret; } @@ -303,10 +304,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) * 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); - wait_for_sr_state(i2c_regs, ST_BUS_IDLE); + i2c_imx_stop(); } else if (i == (len - 2)) { temp = readb(&i2c_regs->i2cr); temp |= I2CR_TX_NO_AK; |