
Hi Heiko,
On 11/18/21 09:18, Stefan Roese wrote:
Testing on Armada XP with an EEPROM using register address with size of 2 has shown, that the register address bytes are sent to the I2C EEPROM in the incorrect order. This patch swabs the address bytes so that the correct address is transferred to the I2C device.
BTW: This worked without any issues before migrating Armada XP to DM I2C.
Signed-off-by: Stefan Roese sr@denx.de Cc: Heiko Schocher hs@denx.de Cc: Samuel Holland samuel@sholland.org Cc: Baruch Siach baruch@tkos.co.il Cc: Pali Rohár pali@kernel.org Cc: Marek Behún marek.behun@nic.cz
It would be good if other users of this I2C driver could test this change with e.g. I2C EEPROM devices using 2 bytes (or more) for addressing.
Could you and other please take a look at this? Would be great, if this could be pulled in the next merge window.
Thanks, Stefan
drivers/i2c/mvtwsi.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 236bfb8d8e7f..ff21e3c52b58 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -860,6 +860,9 @@ static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) { struct mvtwsi_i2c_dev *dev = dev_get_priv(bus); struct i2c_msg *dmsg, *omsg, dummy;
u8 *addr_buf_ptr;
u8 addr_buf[4];
int i;
memset(&dummy, 0, sizeof(struct i2c_msg));
@@ -873,12 +876,17 @@ static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) omsg = nmsgs == 1 ? &dummy : msg; dmsg = nmsgs == 1 ? msg : msg + 1;
- /* We need to swap the register address if its size is > 1 */
- addr_buf_ptr = &addr_buf[0];
- for (i = omsg->len; i > 0; i--)
*addr_buf_ptr++ = omsg->buf[i - 1];
- if (dmsg->flags & I2C_M_RD)
return __twsi_i2c_read(dev->base, dmsg->addr, omsg->buf,
elsereturn __twsi_i2c_read(dev->base, dmsg->addr, addr_buf, omsg->len, dmsg->buf, dmsg->len, dev->tick);
return __twsi_i2c_write(dev->base, dmsg->addr, omsg->buf,
}return __twsi_i2c_write(dev->base, dmsg->addr, addr_buf, omsg->len, dmsg->buf, dmsg->len, dev->tick);
Viele Grüße, Stefan Roese