Hello Marek,

Am 07.02.2020 um 16:57 schrieb Marek Vasut:
Add option to send start condition after deblocking SDA.

Signed-off-by: Marek Vasut <ma...@denx.de>
---
  drivers/i2c/i2c-uclass.c | 23 ++++++++++++++++++++---
  include/i2c.h            |  4 +++-
  2 files changed, 23 insertions(+), 4 deletions(-)

Reviewed-by: Heiko Schocher <h...@denx.de>

diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 86f529241f..e9ec388576 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -504,9 +504,10 @@ static int i2c_gpio_get_pin(struct gpio_desc *pin)
  int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
                          struct gpio_desc *scl_pin,
                          unsigned int scl_count,
+                         unsigned int start_count,
                          unsigned int delay)
  {
-       int ret = 0;
+       int i, ret = -EREMOTEIO;
i2c_gpio_set_pin(sda_pin, 1);
        i2c_gpio_set_pin(scl_pin, 1);
@@ -518,8 +519,24 @@ int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
                udelay(delay);
                i2c_gpio_set_pin(scl_pin, 0);
                udelay(delay);
-               if (i2c_gpio_get_pin(sda_pin))
+               if (i2c_gpio_get_pin(sda_pin)) {
+                       ret = 0;
                        break;
+               }
+       }
+
+       if (!ret && start_count) {
+               for (i = 0; i < start_count; i++) {
+                       /* Send start condition */
+                       udelay(delay);
+                       i2c_gpio_set_pin(sda_pin, 1);
+                       udelay(delay);
+                       i2c_gpio_set_pin(scl_pin, 1);
+                       udelay(delay);
+                       i2c_gpio_set_pin(sda_pin, 0);
+                       udelay(delay);
+                       i2c_gpio_set_pin(scl_pin, 0);
+               }
        }
/* Then, send I2C stop */
@@ -562,7 +579,7 @@ static int i2c_deblock_gpio(struct udevice *bus)
                goto out_no_pinctrl;
        }
- ret0 = i2c_deblock_gpio_loop(&gpios[PIN_SDA], &gpios[PIN_SCL], 9, 5);
+       ret0 = i2c_deblock_gpio_loop(&gpios[PIN_SDA], &gpios[PIN_SCL], 9, 0, 5);
ret = pinctrl_select_state(bus, "default");
        if (ret) {
diff --git a/include/i2c.h b/include/i2c.h
index 7c92042c58..059200115a 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -339,12 +339,14 @@ int i2c_deblock(struct udevice *bus);
   * @sda_pin:  SDA GPIO
   * @scl_pin:  SCL GPIO
   * @scl_count:        Number of SCL clock cycles generated to deblock SDA
+ * @start_count:Number of I2C start conditions sent after deblocking SDA

Is there a tab missing? If so I can add it, when applying this patch.

   * @delay:    Delay between SCL clock line changes
   * @return 0 if OK, -ve on error
   */
  struct gpio_desc;
  int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin, struct gpio_desc 
*scl_pin,
-                         unsigned int scl_count, unsigned int delay);
+                         unsigned int scl_count, unsigned int start_count,
+                         unsigned int delay);
/**
   * struct dm_i2c_ops - driver operations for I2C uclass


bye,
Heiko
--
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: h...@denx.de

Reply via email to