i2c: Add option to send start condition after deblocking

Add option to send start condition after deblocking SDA.

Signed-off-by: Marek Vasut <marex@denx.de>
Reviewed-by: Heiko Schocher <hs@denx.de>
This commit is contained in:
Marek Vasut 2020-02-07 16:57:51 +01:00 committed by Heiko Schocher
parent 7231522a5e
commit a191728633
2 changed files with 23 additions and 4 deletions

View file

@ -504,9 +504,10 @@ static int i2c_gpio_get_pin(struct gpio_desc *pin)
int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin, int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
struct gpio_desc *scl_pin, struct gpio_desc *scl_pin,
unsigned int scl_count, unsigned int scl_count,
unsigned int start_count,
unsigned int delay) unsigned int delay)
{ {
int ret = 0; int i, ret = -EREMOTEIO;
i2c_gpio_set_pin(sda_pin, 1); i2c_gpio_set_pin(sda_pin, 1);
i2c_gpio_set_pin(scl_pin, 1); i2c_gpio_set_pin(scl_pin, 1);
@ -518,9 +519,25 @@ int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
udelay(delay); udelay(delay);
i2c_gpio_set_pin(scl_pin, 0); i2c_gpio_set_pin(scl_pin, 0);
udelay(delay); udelay(delay);
if (i2c_gpio_get_pin(sda_pin)) if (i2c_gpio_get_pin(sda_pin)) {
ret = 0;
break; 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 */ /* Then, send I2C stop */
i2c_gpio_set_pin(sda_pin, 0); i2c_gpio_set_pin(sda_pin, 0);
@ -562,7 +579,7 @@ static int i2c_deblock_gpio(struct udevice *bus)
goto out_no_pinctrl; 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"); ret = pinctrl_select_state(bus, "default");
if (ret) { if (ret) {

View file

@ -339,12 +339,14 @@ int i2c_deblock(struct udevice *bus);
* @sda_pin: SDA GPIO * @sda_pin: SDA GPIO
* @scl_pin: SCL GPIO * @scl_pin: SCL GPIO
* @scl_count: Number of SCL clock cycles generated to deblock SDA * @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 * @delay: Delay between SCL clock line changes
* @return 0 if OK, -ve on error * @return 0 if OK, -ve on error
*/ */
struct gpio_desc; struct gpio_desc;
int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin, struct gpio_desc *scl_pin, 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 * struct dm_i2c_ops - driver operations for I2C uclass