summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorStefan Roese <sr@denx.de>2021-11-18 09:18:41 +0100
committerHeiko Schocher <hs@denx.de>2021-12-20 07:57:48 +0100
commitccea46c05b08b34ef829d460e50e2ce9bc17cdc7 (patch)
tree9c1968823a6680550160b4c074a4b3612283e283 /drivers/i2c
parentd3213c26b56e564207515f1e28e663718e015dc3 (diff)
i2c: mvtwsi: Swab the register address if its size is > 1
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> Tested-by: Marek Behún <marek.behun@nic.cz>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/mvtwsi.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 236bfb8d8e..ff21e3c52b 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,
+ return __twsi_i2c_read(dev->base, dmsg->addr, addr_buf,
omsg->len, dmsg->buf, dmsg->len,
dev->tick);
else
- 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);
}