Skip to content

Commit

Permalink
i2c: recovery: make pin init look like STOP
Browse files Browse the repository at this point in the history
When we initialize the pins, make sure it looks like STOP by dividing
the delay into halves. It shouldn't matter because SDA is expected to be
held low by a device, but for super-safety, let's do it.

Signed-off-by: Wolfram Sang <[email protected]>
Reviewed-by: Ulrich Hecht <[email protected]>
Reviewed-by: Peter Rosin <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
  • Loading branch information
Wolfram Sang authored and Wolfram Sang committed Jul 20, 2018
1 parent ea3cfbd commit c4ae05b
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions drivers/i2c/i2c-core-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,17 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
if (bri->prepare_recovery)
bri->prepare_recovery(adap);

/*
* If we can set SDA, we will always create a STOP to ensure additional
* pulses will do no harm. This is achieved by letting SDA follow SCL
* half a cycle later. Check the 'incomplete_write_byte' fault injector
* for details.
*/
bri->set_scl(adap, scl);
ndelay(RECOVERY_NDELAY / 2);
if (bri->set_sda)
bri->set_sda(adap, 1);
ndelay(RECOVERY_NDELAY);
bri->set_sda(adap, scl);
ndelay(RECOVERY_NDELAY / 2);

/*
* By this time SCL is high, as we need to give 9 falling-rising edges
Expand All @@ -211,13 +218,7 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)

scl = !scl;
bri->set_scl(adap, scl);

/*
* If we can set SDA, we will always create STOP here to ensure
* the additional pulses will do no harm. This is achieved by
* letting SDA follow SCL half a cycle later. Check the
* 'incomplete_write_byte' fault injector for details.
*/
/* Creating STOP again, see above */
ndelay(RECOVERY_NDELAY / 2);
if (bri->set_sda)
bri->set_sda(adap, scl);
Expand Down

0 comments on commit c4ae05b

Please sign in to comment.