aboutsummaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
authorHarm Berntsen <harm.berntsen@nedap.com>2020-11-29 09:47:15 +0000
committerHeiko Schocher <hs@denx.de>2021-02-21 06:04:49 +0100
commit6befb51f349459c96ed64412070feda7472cf152 (patch)
tree3e5ed57f10ec7a7c0786bce9d2648df54efb389c /drivers/i2c
parentea966d24ef3a9f7f32712a518a07374f9ae43905 (diff)
downloadu-boot-6befb51f349459c96ed64412070feda7472cf152.zip
u-boot-6befb51f349459c96ed64412070feda7472cf152.tar.gz
u-boot-6befb51f349459c96ed64412070feda7472cf152.tar.bz2
i2c: i2c-gpio: Fix GPIO output
The dm_gpio_set_dir_flags function cannot be used to update the configuration of a GPIO pin because it does a bitwise OR with the existing flags. Looks like commit 788ea834124b ("gpio: add function _dm_gpio_set_dir_flags") has introduced this behaviour and the i2c-gpio driver has been broken since. Signed-off-by: Harm Berntsen <harm.berntsen@nedap.com> CC: Heiko Schocher <hs@denx.de> CC: Patrick Delaunay <patrick.delaunay@st.com>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/i2c-gpio.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
index 387f00b..a301a44 100644
--- a/drivers/i2c/i2c-gpio.c
+++ b/drivers/i2c/i2c-gpio.c
@@ -50,9 +50,10 @@ static void i2c_gpio_sda_set(struct i2c_gpio_bus *bus, int bit)
struct gpio_desc *sda = &bus->gpios[PIN_SDA];
if (bit)
- dm_gpio_set_dir_flags(sda, GPIOD_IS_IN);
+ sda->flags = (sda->flags & ~GPIOD_IS_OUT) | GPIOD_IS_IN;
else
- dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT);
+ sda->flags = (sda->flags & (~GPIOD_IS_IN & ~GPIOD_IS_OUT_ACTIVE)) | GPIOD_IS_OUT;
+ dm_gpio_set_dir(sda);
}
static void i2c_gpio_scl_set(struct i2c_gpio_bus *bus, int bit)
@@ -61,14 +62,16 @@ static void i2c_gpio_scl_set(struct i2c_gpio_bus *bus, int bit)
int count = 0;
if (bit) {
- dm_gpio_set_dir_flags(scl, GPIOD_IS_IN);
+ scl->flags = (scl->flags & ~GPIOD_IS_OUT) | GPIOD_IS_IN;
+ dm_gpio_set_dir(scl);
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);
+ scl->flags = (scl->flags & (~GPIOD_IS_IN & ~GPIOD_IS_OUT_ACTIVE)) | GPIOD_IS_OUT;
+ dm_gpio_set_dir(scl);
}
}
@@ -76,11 +79,11 @@ static void i2c_gpio_scl_set(struct i2c_gpio_bus *bus, int bit)
static void i2c_gpio_scl_set_output_only(struct i2c_gpio_bus *bus, int bit)
{
struct gpio_desc *scl = &bus->gpios[PIN_SCL];
- ulong flags = GPIOD_IS_OUT;
+ scl->flags = (scl->flags & (~GPIOD_IS_IN & ~GPIOD_IS_OUT_ACTIVE)) | GPIOD_IS_OUT;
if (bit)
- flags |= GPIOD_IS_OUT_ACTIVE;
- dm_gpio_set_dir_flags(scl, flags);
+ scl->flags |= GPIOD_IS_OUT_ACTIVE;
+ dm_gpio_set_dir(scl);
}
static void i2c_gpio_write_bit(struct i2c_gpio_bus *bus, int delay, uchar bit)