Fix the I2C on SAMA5D3
Subsystems (2)
cover Fix the I2C on SAMA5D3
Two patches to fix the I2C on SAMA5D3. The first fixes a race condition in pushing TX data to the hardware, and the second removes an errant probe_chip function which prevents devices from being probed properly
These have been tested on master and on 2017.07
Alan Ott (2):
i2c: at91_i2c: Wait for TXRDY after sending the first byte
i2c: at91_i2c: remove the .probe_chip function
drivers/i2c/at91_i2c.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-)
Signature · 1 line
2.9.3
PATCH 1/2 i2c: at91_i2c: Wait for TXRDY after sending the first byte
The driver must wait for TXRDY after each byte is pushed into the i2c FIFO before pushing the next byte. Previously this was not done for the first byte, causing a race condition with zeros sometimes being sent for the next byte (which is typically the first actual data byte).
--- drivers/i2c/at91_i2c.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/i2c/at91_i2c.c +2 -0
@@ -72,6 +72,8 @@ static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg) }else {writel (msg->buf[0 ], ®->thr); + ret =at91_wait_for_xfer (bus,TWI_SR_TXRDY ); +for (i =1 ; !ret && (i < msg->len); i++) {writel (msg->buf[i], ®->thr); ret =at91_wait_for_xfer (bus,TWI_SR_TXRDY );
Signature · 1 line
2.9.3
Yang
PATCH 1/2 i2c: at91_i2c: Wait for TXRDY after sending the first byte
Quoted 8 lines · Alan Ott
The driver must wait for TXRDY after each byte is pushed into the i2c FIFO before pushing the next byte. Previously this was not done for the first byte, causing a race condition with zeros sometimes being sent for the next byte (which is typically the first actual data byte).
Signed-off-by Alan Ott <[email protected]>---
Thank you for your patch.
Quoted 8 lines
drivers/i2c/at91_i2c.c | 2 ++ 1 file changed, 2 insertions(+)drivers/i2c/at91_i2c.c +0
-0
drivers/i2c/at91_i2c.c static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg) · line 79
Quoted 8 lines
drivers/i2c/at91_i2c.c +2
-0@@ -72,6 +72,8 @@ static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg) }else {writel (msg->buf[0 ], ®->thr); + ret =at91_wait_for_xfer (bus,TWI_SR_TXRDY ); +for (i =1 ; !ret && (i < msg->len); i++) {writel (msg->buf[i], ®->thr); ret =at91_wait_for_xfer (bus,TWI_SR_TXRDY );
Best Regards,
Wenyou Yang
PATCH 1/2 i2c: at91_i2c: Wait for TXRDY after sending the first byte
In reply to Alan OttHello Alan,
Am 29.11.2017 um 04:25 schrieb Alan Ott:
Quoted 10 lines
The driver must wait for TXRDY after each byte is pushed into the i2c FIFO before pushing the next byte. Previously this was not done for the first byte, causing a race condition with zeros sometimes being sent for the next byte (which is typically the first actual data byte).
Signed-off-by Alan Ott <[email protected]>--- drivers/i2c/at91_i2c.c | 2 ++ 1 file changed, 2 insertions(+)
Thanks!
bye,
Heiko
Signature · 3 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs at denx.de
PATCH 1/2 i2c: at91_i2c: Wait for TXRDY after sending the first byte
In reply to Alan OttHello Alan,
Am 29.11.2017 um 04:25 schrieb Alan Ott:
Quoted 10 lines
The driver must wait for TXRDY after each byte is pushed into the i2c FIFO before pushing the next byte. Previously this was not done for the first byte, causing a race condition with zeros sometimes being sent for the next byte (which is typically the first actual data byte).
Signed-off-by Alan Ott <[email protected]>--- drivers/i2c/at91_i2c.c | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-i2c master
Thanks!
bye,
Heiko
Signature · 3 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs at denx.de
PATCH 2/2 i2c: at91_i2c: remove the .probe_chip function
In reply to Alan OttThe .probe_chip function is supposed to probe an i2c device on the bus to determine whether a device is answering to a particular address. at91_i2c_probe_chip() did not do anything resembling this and always returned 0.
It looks as though at91_i2c_probe_chip() was intended to be a .probe function for the controller, as it was copied-and-pasted to become at91_i2c_probe() in 0bc8f640a4d7ed.
Removing the at91_i2c_probe_chip() function makes the higher layer (i2c_probe_chip()) try a zero-length read transfer to test for the presence of a device instead, which does work.
--- drivers/i2c/at91_i2c.c | 22 ---------------------- 1 file changed, 22 deletions(-)
drivers/i2c/at91_i2c.c +0 -22
@@ -201,27 +201,6 @@ static int at91_i2c_enable_clk(struct udevice *dev)return 0 ; } -static int at91_i2c_probe_chip (struct udevice *dev,uint chip,uint chip_flags) -{ -struct at91_i2c_bus *bus =dev_get_priv (dev); -struct at91_i2c_regs *reg = bus->regs; -int ret; - - ret =at91_i2c_enable_clk (dev); -if (ret) -return ret; - -writel (TWI_CR_SWRST , ®->cr); - -at91_calc_i2c_clock (dev, bus->clock_frequency); - -writel (bus->cwgr_val, ®->cwgr); -writel (TWI_CR_MSEN , ®->cr); -writel (TWI_CR_SVDIS , ®->cr); - -return 0 ; -} -static int at91_i2c_set_bus_speed (struct udevice *dev,unsigned int speed) {struct at91_i2c_bus *bus =dev_get_priv (dev);
@@ -256,7 +235,6 @@ static int at91_i2c_ofdata_to_platdata(struct udevice *dev)static const struct dm_i2c_ops at91_i2c_ops = { .xfer = at91_i2c_xfer, - .probe_chip = at91_i2c_probe_chip, .set_bus_speed = at91_i2c_set_bus_speed, .get_bus_speed = at91_i2c_get_bus_speed, };
Signature · 1 line
2.9.3
Yang
PATCH 2/2 i2c: at91_i2c: remove the .probe_chip function
Quoted 9 lines · Alan Ott
The .probe_chip function is supposed to probe an i2c device on the bus to determine whether a device is answering to a particular address.
at91_i2c_probe_chip()did not do anything resembling this and always returned 0.It looks as though
at91_i2c_probe_chip()was intended to be a .probe function for the controller, as it was copied-and-pasted to becomeat91_i2c_probe()in0bc8f640a4d7ed.
Quoted 6 lines
Removing the
at91_i2c_probe_chip()function makes the higher layer (i2c_probe_chip()) try a zero-length read transfer to test for the presence of a device instead, which does work.Signed-off-by Alan Ott <[email protected]>---
Thank you for your patch.
Quoted 36 lines
drivers/i2c/at91_i2c.c | 22 ---------------------- 1 file changed, 22 deletions(-)drivers/i2c/at91_i2c.c +0
-21@@ -201,27 +201,6 @@ static int at91_i2c_enable_clk(struct udevice *dev)return 0 ; } -static int at91_i2c_probe_chip (struct udevice *dev,uint chip,uint chip_flags) -{ -struct at91_i2c_bus *bus =dev_get_priv (dev); -struct at91_i2c_regs *reg = bus->regs; -int ret; - - ret =at91_i2c_enable_clk (dev); -if (ret) -return ret; - -writel (TWI_CR_SWRST , ®->cr); - -at91_calc_i2c_clock (dev, bus->clock_frequency); - -writel (bus->cwgr_val, ®->cwgr); -writel (TWI_CR_MSEN , ®->cr); -writel (TWI_CR_SVDIS , ®->cr); - -return 0 ; -} -static int at91_i2c_set_bus_speed (struct udevice *dev,unsigned int speed) {struct at91_i2c_bus *bus =dev_get_priv (dev);
drivers/i2c/at91_i2c.c static int at91_i2c_ofdata_to_platdata(struct udevice *dev) · line 240
Quoted 7 lines
drivers/i2c/at91_i2c.c +0
-1@@ -256,7 +235,6 @@ static int at91_i2c_ofdata_to_platdata(struct udevice *dev)static const struct dm_i2c_ops at91_i2c_ops = { .xfer = at91_i2c_xfer, - .probe_chip = at91_i2c_probe_chip, .set_bus_speed = at91_i2c_set_bus_speed, .get_bus_speed = at91_i2c_get_bus_speed, };
Best Regards,
Wenyou Yang
PATCH 2/2 i2c: at91_i2c: remove the .probe_chip function
In reply to Alan OttHello Alan,
Am 29.11.2017 um 04:25 schrieb Alan Ott:
Quoted 9 lines
The .probe_chip function is supposed to probe an i2c device on the bus to determine whether a device is answering to a particular address.
at91_i2c_probe_chip()did not do anything resembling this and always returned 0.It looks as though
at91_i2c_probe_chip()was intended to be a .probe function for the controller, as it was copied-and-pasted to becomeat91_i2c_probe()in0bc8f640a4d7ed.
Quoted 8 lines
Removing the
at91_i2c_probe_chip()function makes the higher layer (i2c_probe_chip()) try a zero-length read transfer to test for the presence of a device instead, which does work.Signed-off-by Alan Ott <[email protected]>--- drivers/i2c/at91_i2c.c | 22 ---------------------- 1 file changed, 22 deletions(-)
Thanks!
bye,
Heiko
Signature · 3 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs at denx.de
PATCH 2/2 i2c: at91_i2c: remove the .probe_chip function
In reply to Alan OttHello Alan,
Am 29.11.2017 um 04:25 schrieb Alan Ott:
Quoted 9 lines
The .probe_chip function is supposed to probe an i2c device on the bus to determine whether a device is answering to a particular address.
at91_i2c_probe_chip()did not do anything resembling this and always returned 0.It looks as though
at91_i2c_probe_chip()was intended to be a .probe function for the controller, as it was copied-and-pasted to becomeat91_i2c_probe()in0bc8f640a4d7ed.
Quoted 8 lines
Removing the
at91_i2c_probe_chip()function makes the higher layer (i2c_probe_chip()) try a zero-length read transfer to test for the presence of a device instead, which does work.Signed-off-by Alan Ott <[email protected]>--- drivers/i2c/at91_i2c.c | 22 ---------------------- 1 file changed, 22 deletions(-)
Applied to u-boot-i2c master
Thanks!
bye,
Heiko
Signature · 3 lines
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs at denx.de