]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
i2c: i2c-gpio: add support for i2c-gpio,sda-output-only
authorAlex Shumsky <alexthreed@gmail.com>
Tue, 15 Oct 2024 20:29:31 +0000 (23:29 +0300)
committerHeiko Schocher <hs@denx.de>
Mon, 21 Oct 2024 04:32:40 +0000 (06:32 +0200)
Some I2C slave devices are read-only and don't even answer with NACK.
For example FD65x segment LED controllers.
Make them usable with i2c-gpio,sda-output-only that are already supported
by Linux 6.3+.

Signed-off-by: Alex Shumsky <alexthreed@gmail.com>
Reviewed-by: Heiko Schocher <hs@denx.de>
doc/device-tree-bindings/i2c/i2c-gpio.txt
drivers/i2c/i2c-gpio.c

index b06b829933746227387b4435a91f2035c191db85..bb00854f334291622ace909f3c2cc128a5f450da 100644 (file)
@@ -20,6 +20,8 @@ Optional:
    Run deblocking sequence when the driver gets probed.
 * i2c-gpio,scl-output-only;
    Set if SCL is an output only
+* i2c-gpio,sda-output-only;
+   Set if SDA is an output only
 
 Example:
 
index e0a575fb4a48d1fa5877b56c79c0873e1a039b0f..00aef40e3412b4ef99c18e2b09a4615ada88c883 100644 (file)
@@ -101,7 +101,7 @@ static int i2c_gpio_read_bit(struct i2c_gpio_bus *bus, int delay)
 
        bus->set_scl(bus, 1);
        udelay(delay);
-       value = bus->get_sda(bus);
+       value = bus->get_sda ? bus->get_sda(bus) : 0;
        udelay(delay);
        bus->set_scl(bus, 0);
        udelay(2 * delay);
@@ -256,6 +256,9 @@ static int i2c_gpio_read_data(struct i2c_gpio_bus *bus, uchar chip,
 {
        unsigned int delay = bus->udelay;
 
+       if (!bus->get_sda)
+               return -EOPNOTSUPP;
+
        debug("%s: chip %x buffer: %p len %d\n", __func__, chip, buffer, len);
 
        while (len-- > 0)
@@ -353,7 +356,10 @@ static int i2c_gpio_of_to_plat(struct udevice *dev)
        bus->udelay = dev_read_u32_default(dev, "i2c-gpio,delay-us",
                                           DEFAULT_UDELAY);
 
-       bus->get_sda = i2c_gpio_sda_get;
+       if (dev_read_bool(dev, "i2c-gpio,sda-output-only"))
+               bus->get_sda = NULL;
+       else
+               bus->get_sda = i2c_gpio_sda_get;
        bus->set_sda = i2c_gpio_sda_set;
        if (dev_read_bool(dev, "i2c-gpio,scl-output-only"))
                bus->set_scl = i2c_gpio_scl_set_output_only;