Messages in this thread | | | Subject | Re: [PATCH] i2c: at91: Send bus clear command if SCL or SDA is down | From | kbouhara <> | Date | Thu, 19 Sep 2019 17:06:18 +0200 |
| |
On 9/11/19 11:58 AM, Codrin Ciubotariu wrote: > After a transfer timeout, some faulty I2C slave devices might hold down > the SCL or the SDA pins. We can generate a bus clear command, hoping that > the slave might release the pins. > > Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> > --- > drivers/i2c/busses/i2c-at91-master.c | 20 ++++++++++++++++++++ > drivers/i2c/busses/i2c-at91.h | 6 +++++- > 2 files changed, 25 insertions(+), 1 deletion(-) > > diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c > index a3fcc35ffd3b..5f544a16db96 100644 > --- a/drivers/i2c/busses/i2c-at91-master.c > +++ b/drivers/i2c/busses/i2c-at91-master.c > @@ -599,6 +599,26 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) > at91_twi_write(dev, AT91_TWI_CR, > AT91_TWI_THRCLR | AT91_TWI_LOCKCLR); > } > + > + /* > + * After timeout, some faulty I2C slave devices might hold SCL/SDA down; > + * we can send a bus clear command, hoping that the pins will be > + * released > + */ > + if (!(dev->transfer_status & AT91_TWI_SDA) || > + !(dev->transfer_status & AT91_TWI_SCL)) { > + dev_dbg(dev->dev, > + "SDA/SCL are down; sending bus clear command\n"); > + if (dev->use_alt_cmd) { > + unsigned int acr; > + > + acr = at91_twi_read(dev, AT91_TWI_ACR); > + acr &= ~AT91_TWI_ACR_DATAL_MASK; > + at91_twi_write(dev, AT91_TWI_ACR, acr); > + } > + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_CLEAR);
This bit is not documented on SoCs before SAMA5D2/D4, this write shouldn't be done unconditionally.
-- Kamel Bouhara, Bootlin Embedded Linux and kernel engineering https://bootlin.com
| |