i2c: recovery: make pin init look like STOP
authorWolfram Sang <wsa+renesas@sang-engineering.com>
Tue, 17 Jul 2018 09:00:05 +0000 (11:00 +0200)
committerWolfram Sang <wsa@the-dreams.de>
Fri, 20 Jul 2018 22:11:05 +0000 (00:11 +0200)
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 <wsa+renesas@sang-engineering.com>
Reviewed-by: Ulrich Hecht <ulrich.hecht+renesas@gmail.com>
Reviewed-by: Peter Rosin <peda@axentia.se>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/i2c-core-base.c

index 57538d72f2e5eb5b0f9dc5a122ee4ee92c9f2448..02d6f27b19e49cae39d77674c9bcf94bb7ada3a1 100644 (file)
@@ -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
@@ -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);