From patchwork Thu Jan 23 22:30:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Auchter X-Patchwork-Id: 240027 List-Id: U-Boot discussion From: michael.auchter at ni.com (Michael Auchter) Date: Thu, 23 Jan 2020 22:30:20 +0000 Subject: [PATCH] dm: i2c-gpio: add support for clock stretching Message-ID: <20200123223009.213180-1-michael.auchter@ni.com> This adds support for clock stretching to the i2c-gpio driver. This is accomplished by switching the GPIO used for the SCL line to an input when it should be driven high, and polling on the SCL line value until it goes high (indicating that the I2C slave is no longer pulling it low). Signed-off-by: Michael Auchter Cc: Heiko Schocher --- drivers/i2c/i2c-gpio.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c index 4e8fa21473..80ac26e583 100644 --- a/drivers/i2c/i2c-gpio.c +++ b/drivers/i2c/i2c-gpio.c @@ -49,11 +49,18 @@ static void i2c_gpio_sda_set(struct gpio_desc *sda, int bit) static void i2c_gpio_scl_set(struct gpio_desc *scl, int bit) { - ulong flags = GPIOD_IS_OUT; + int count = 0; - if (bit) - flags |= GPIOD_IS_OUT_ACTIVE; - dm_gpio_set_dir_flags(scl, flags); + if (bit) { + dm_gpio_set_dir_flags(scl, GPIOD_IS_IN); + while (!dm_gpio_get_value(scl) && count++ < 100000) + udelay(1); + + if (!dm_gpio_get_value(scl)) + pr_err("timeout waiting on slave to release scl\n"); + } else { + dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT); + } } static void i2c_gpio_write_bit(struct gpio_desc *scl, struct gpio_desc *sda,