i2c: fix bus recovery stop mode timing

The I2C specification states that tsu:sto for standard mode timing must
be at minimum 4us. Pictographically, this is:

SCL: ____/~~~~~~~~~
SDA: _________/~~~~
->| |<- 4us minimum

We are currently waiting 2.5us between asserting SCL and SDA, which is
in violation of the standard. Adjust the timings to ensure that we meet
what is stipulated as the minimum timings to ensure that all devices
correctly interpret the STOP bus transition.

This is more important than trying to generate a square wave with even
duty cycle.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by Russell King and committed by Wolfram Sang cf8ce8b8 3b722da6

+10 -3
+10 -3
drivers/i2c/i2c-core-base.c
··· 186 * If we can set SDA, we will always create a STOP to ensure additional 187 * pulses will do no harm. This is achieved by letting SDA follow SCL 188 * half a cycle later. Check the 'incomplete_write_byte' fault injector 189 - * for details. 190 */ 191 bri->set_scl(adap, scl); 192 - ndelay(RECOVERY_NDELAY / 2); 193 if (bri->set_sda) 194 bri->set_sda(adap, scl); 195 ndelay(RECOVERY_NDELAY / 2); ··· 212 scl = !scl; 213 bri->set_scl(adap, scl); 214 /* Creating STOP again, see above */ 215 - ndelay(RECOVERY_NDELAY / 2); 216 if (bri->set_sda) 217 bri->set_sda(adap, scl); 218 ndelay(RECOVERY_NDELAY / 2);
··· 186 * If we can set SDA, we will always create a STOP to ensure additional 187 * pulses will do no harm. This is achieved by letting SDA follow SCL 188 * half a cycle later. Check the 'incomplete_write_byte' fault injector 189 + * for details. Note that we must honour tsu:sto, 4us, but lets use 5us 190 + * here for simplicity. 191 */ 192 bri->set_scl(adap, scl); 193 + ndelay(RECOVERY_NDELAY); 194 if (bri->set_sda) 195 bri->set_sda(adap, scl); 196 ndelay(RECOVERY_NDELAY / 2); ··· 211 scl = !scl; 212 bri->set_scl(adap, scl); 213 /* Creating STOP again, see above */ 214 + if (scl) { 215 + /* Honour minimum tsu:sto */ 216 + ndelay(RECOVERY_NDELAY); 217 + } else { 218 + /* Honour minimum tf and thd:dat */ 219 + ndelay(RECOVERY_NDELAY / 2); 220 + } 221 if (bri->set_sda) 222 bri->set_sda(adap, scl); 223 ndelay(RECOVERY_NDELAY / 2);