diff mbox series

i2c: mvtwsi: Swab the register address if its size is > 1

Message ID 20211118081841.861158-1-sr@denx.de
State Accepted
Commit ccea46c05b08b34ef829d460e50e2ce9bc17cdc7
Delegated to: Heiko Schocher
Headers show
Series i2c: mvtwsi: Swab the register address if its size is > 1 | expand

Commit Message

Stefan Roese Nov. 18, 2021, 8:18 a.m. UTC
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.

 drivers/i2c/mvtwsi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Stefan Roese Dec. 18, 2021, 1:42 p.m. UTC | #1
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,
> +		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);
>   }
> 

Viele Grüße,
Stefan Roese
Marek Behún Dec. 18, 2021, 10:41 p.m. UTC | #2
On Sat, 18 Dec 2021 14:42:51 +0100
Stefan Roese <sr@denx.de> wrote:

> 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.

Tested-by: Marek Behún <marek.behun@nic.cz>
Heiko Schocher Dec. 20, 2021, 7:03 a.m. UTC | #3
Hello Marek,

On 18.12.21 23:41, Marek Behún wrote:
> On Sat, 18 Dec 2021 14:42:51 +0100
> Stefan Roese <sr@denx.de> wrote:
> 
>> 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.
> 
> Tested-by: Marek Behún <marek.behun@nic.cz>
> 

Thanks for testing. Just triggered azure build now,
if all works fine, I send a pull request to Tom.

bye,
Heiko
Heiko Schocher Dec. 20, 2021, 10:12 a.m. UTC | #4
Hello Stefan,

On 18.12.21 14:42, Stefan Roese wrote:
> 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.

Applied to u-boot-i2c master

Thanks!

bye,
Heiko
diff mbox series

Patch

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,
+		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);
 }