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/mxc_i2c.c | |
| parent | 83a1a19038b0bf36c966b7c7b67708e19b45c3b5 (diff) | |
| download | olio-uboot-2014.01-90a5b70f5914a3ac79cac3dd386cc98ce42bfd8e.tar.xz olio-uboot-2014.01-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/mxc_i2c.c')
| -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 717bc7ae0..1a5e379c2 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; |