[U-Boot] rockchip: i2c: fix >32 byte reads

Philipp Tomsich philipp.tomsich at theobroma-systems.com
Fri Aug 18 13:06:05 UTC 2017



On Thu, 3 Aug 2017, Wadim Egorov wrote:

> The hw can read up to 32 bytes at a time. If we need
> more than one chunk, we have to enter the plain RX mode.

Why does this need to be in 'plain RX' mode for more than 32 bytes?
What happens if someone wants to write/transmit more than 32 bytes?

>
> Signed-off-by: Wadim Egorov <w.egorov at phytec.de>
> Acked-by: Philipp Tomsich <philipp.tomsich at theobroma-systems.com>
> ---
> drivers/i2c/rk_i2c.c | 19 ++++++++++++++++---
> 1 file changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c
> index 8bc045a..68e6653 100644
> --- a/drivers/i2c/rk_i2c.c
> +++ b/drivers/i2c/rk_i2c.c
> @@ -164,6 +164,7 @@ static int rk_i2c_read(struct rk_i2c *i2c, uchar chip, uint reg, uint r_len,
> 	uint rxdata;
> 	uint i, j;
> 	int err;
> +	bool snd_chunk = false;
>
> 	debug("rk_i2c_read: chip = %d, reg = %d, r_len = %d, b_len = %d\n",
> 	      chip, reg, r_len, b_len);
> @@ -184,15 +185,26 @@ static int rk_i2c_read(struct rk_i2c *i2c, uchar chip, uint reg, uint r_len,
>
> 	while (bytes_remain_len) {
> 		if (bytes_remain_len > RK_I2C_FIFO_SIZE) {
> -			con = I2C_CON_EN | I2C_CON_MOD(I2C_MODE_TRX);
> +			con = I2C_CON_EN;
> 			bytes_xferred = 32;
> 		} else {
> -			con = I2C_CON_EN | I2C_CON_MOD(I2C_MODE_TRX) |
> -				I2C_CON_LASTACK;
> +			/*
> +			 * The hw can read up to 32 bytes at a time. If we need
> +			 * more than one chunk, send an ACK after the last byte.
> +			 */
> +			con = I2C_CON_EN | I2C_CON_LASTACK;
> 			bytes_xferred = bytes_remain_len;
> 		}
> 		words_xferred = DIV_ROUND_UP(bytes_xferred, 4);
>
> +		/*
> +		 * make sure we are in plain RX mode if we read a second chunk
> +		 */
> +		if (snd_chunk)
> +			con |= I2C_CON_MOD(I2C_MODE_RX);
> +		else
> +			con |= I2C_CON_MOD(I2C_MODE_TRX);
> +
> 		writel(con, &regs->con);
> 		writel(bytes_xferred, &regs->mrxcnt);
> 		writel(I2C_MBRFIEN | I2C_NAKRCVIEN, &regs->ien);
> @@ -227,6 +239,7 @@ static int rk_i2c_read(struct rk_i2c *i2c, uchar chip, uint reg, uint r_len,
> 		}
>
> 		bytes_remain_len -= bytes_xferred;
> +		snd_chunk = true;
> 		debug("I2C Read bytes_remain_len %d\n", bytes_remain_len);
> 	}
>
>


More information about the U-Boot mailing list