diff mbox series

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

Message ID 20200207155752.40930-3-marex@denx.de
State Accepted
Commit a19172863335dcaa1b2a98009f0bfef2a61ab4a2
Headers show
Series [1/4] i2c: Make deblock delay and SCL clock configurable | expand

Commit Message

Marek Vasut Feb. 7, 2020, 3:57 p.m. UTC
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(-)

Comments

Heiko Schocher Feb. 18, 2020, 7:07 a.m. UTC | #1
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 <marex at denx.de>
> ---
>   drivers/i2c/i2c-uclass.c | 23 ++++++++++++++++++++---
>   include/i2c.h            |  4 +++-
>   2 files changed, 23 insertions(+), 4 deletions(-)

Reviewed-by: Heiko Schocher <hs at 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
Marek Vasut Feb. 18, 2020, 5:21 p.m. UTC | #2
On 2/18/20 8:07 AM, Heiko Schocher wrote:
> Hello Marek,

Hi,

> Am 07.02.2020 um 16:57 schrieb Marek Vasut:
>> 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(-)
> 
> Reviewed-by: Heiko Schocher <hs at 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.

Nope, if you add tab, the formatting starts to look real awful.
You can add a space if you feel very inclined to do so, but it would
still look ugly.
Heiko Schocher March 17, 2020, 5:11 a.m. UTC | #3
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 <marex at denx.de>
> ---
>   drivers/i2c/i2c-uclass.c | 23 ++++++++++++++++++++---
>   include/i2c.h            |  4 +++-
>   2 files changed, 23 insertions(+), 4 deletions(-)

Applied to u-boot-i2c next, thanks!

bye,
Heiko
diff mbox series

Patch

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