[PATCH 3/4] i2c: Add option to send start condition after deblocking

Marek Vasut marex at denx.de
Fri Feb 7 16:57:51 CET 2020


Add option to send start condition after deblocking SDA.

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

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
  * @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
-- 
2.24.1



More information about the U-Boot mailing list