Skip to content

Commit

Permalink
rockchip: i2c: fix >32 byte reads
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Wadim Egorov <[email protected]>
Acked-by: Philipp Tomsich <[email protected]>
  • Loading branch information
wdmegrv authored and Philipp Tomsich committed Sep 5, 2017
1 parent 313bbcf commit 5deaa53
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions drivers/i2c/rk_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit 5deaa53

Please sign in to comment.