]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
i2c: mvtwsi: Swab the register address if its size is > 1
authorStefan Roese <sr@denx.de>
Thu, 18 Nov 2021 08:18:41 +0000 (09:18 +0100)
committerHeiko Schocher <hs@denx.de>
Mon, 20 Dec 2021 06:57:48 +0000 (07:57 +0100)
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>
drivers/i2c/mvtwsi.c

index 236bfb8d8e7f55222a6e6bef9a2f7ff5afb55858..ff21e3c52b58c1fcaef18d20497f10b219f40984 100644 (file)
@@ -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);
 }