* [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
@ 2026-05-11 16:25 Markus Stockhausen
2026-05-11 16:25 ` [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio Markus Stockhausen
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Markus Stockhausen @ 2026-05-11 16:25 UTC (permalink / raw)
To: brgl, wsa+renesas, andi.shyti, robh, krzk+dt, conor+dt, linux-i2c,
devicetree
Cc: Markus Stockhausen
This series adds support for hardware designs where multiple I2C
gpio based busses are realized with dedicated SDA lines and a
shared SCL line. This way N busses can be realized with N+1 gpios.
Currently there are several Realtek switches that make use of
this design. Samples are:
HPE 1920-48G
Linksys LGS310C
Zyxel GS1920-24
Engenius EWS2910
D-Link DGS-1250
While at first glance this might be a usecase for the new shared
gpio architecture, discussion and testing shows that this is not
trivial at all. A shared gpio is handled by a voting system. If
there at least one user that votes for the GPIO to be "high",
it stays high.
So the implementation manages several classic bitbang buses with
locking/unlocking in the pre_xfer/post_xfer handlers.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
v1 -> v2:
- Adapted the dts so that all SDA/SCL gpios are defined in the
parent node. This way the i2c child nodes are kept clean.
Their <reg> property is used as an index into the parent SDA
list.
- Adapted the driver to make use of the new dts structure.
- Hardened the driver by adding multiple consistency checks
during probing (number of busses, duplicate dts nodes, ...).
- Added recovery handlers that are synchronized via the central
mutex like normal bus transfers.
v1: https://lore.kernel.org/linux-i2c/20260507181711.2696783-1-markus.stockhausen@gmx.de/
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio
2026-05-11 16:25 [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Markus Stockhausen
@ 2026-05-11 16:25 ` Markus Stockhausen
2026-05-11 17:36 ` Rob Herring (Arm)
2026-05-11 16:25 ` [PATCH v2 2/2] i2c: Add driver for gpio based busses with shared SCL Markus Stockhausen
2026-05-12 11:00 ` [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Bartosz Golaszewski
2 siblings, 1 reply; 12+ messages in thread
From: Markus Stockhausen @ 2026-05-11 16:25 UTC (permalink / raw)
To: brgl, wsa+renesas, andi.shyti, robh, krzk+dt, conor+dt, linux-i2c,
devicetree
Cc: Markus Stockhausen
Document the driver for bitbanged gpio I2C busses
with shared SCL lines.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
.../bindings/i2c/i2c-gpio-shared.yaml | 105 ++++++++++++++++++
1 file changed, 105 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio-shared.yaml
diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio-shared.yaml b/Documentation/devicetree/bindings/i2c/i2c-gpio-shared.yaml
new file mode 100644
index 000000000000..4a21638bd842
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-gpio-shared.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/i2c-gpio-shared.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Multiple GPIO bitbanged I2C buses with shared SCL
+
+maintainers:
+ - Markus Stockhausen <markus.stockhausen@gmx.de>
+
+description:
+ Bitbanging I2C bus driver that supports multiple independent I2C buses
+ sharing a single SCL line. Each child node represents one I2C bus with
+ its own SDA line. The index of each entry in the parent's sda-gpios
+ property must match the reg value of the corresponding child bus node.
+
+properties:
+ compatible:
+ const: i2c-gpio-shared
+
+ scl-gpios:
+ maxItems: 1
+ description:
+ GPIO used for the shared SCL signal. Must be configured as open-drain.
+
+ sda-gpios:
+ minItems: 2
+ maxItems: 32
+ description:
+ GPIOs used for the SDA signals of the individual I2C buses. The index
+ of the GPIO in this list corresponds to the 'reg' property of the
+ child bus nodes (e.g., the first GPIO is for the child with reg = <0>).
+ Must be configured as open-drain.
+
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
+required:
+ - compatible
+ - scl-gpios
+ - sda-gpios
+ - "#address-cells"
+ - "#size-cells"
+
+patternProperties:
+ "^i2c@[0-9a-f]+$":
+ type: object
+ $ref: /schemas/i2c/i2c-controller.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ reg:
+ items:
+ - minimum: 0
+ maximum: 31
+ description:
+ Index into the sda-gpios array used by this specific bus.
+
+ clock-frequency:
+ minimum: 1
+ maximum: 400000
+ default: 100000
+ description:
+ Desired I2C bus clock frequency in Hz.
+
+ required:
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ compatible = "i2c-gpio-shared";
+ scl-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>,
+ <&gpio1 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ reg = <0>;
+ clock-frequency = <100000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@1 {
+ reg = <1>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/2] i2c: Add driver for gpio based busses with shared SCL
2026-05-11 16:25 [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Markus Stockhausen
2026-05-11 16:25 ` [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio Markus Stockhausen
@ 2026-05-11 16:25 ` Markus Stockhausen
2026-05-12 11:00 ` [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Bartosz Golaszewski
2 siblings, 0 replies; 12+ messages in thread
From: Markus Stockhausen @ 2026-05-11 16:25 UTC (permalink / raw)
To: brgl, wsa+renesas, andi.shyti, robh, krzk+dt, conor+dt, linux-i2c,
devicetree
Cc: Markus Stockhausen
Some lower end hardware (especially Realtek based switches) are
designed with multiple I2C busses that share a single clock
(SCL) line. E.g. the D-Link DGS-1250-28X realizes 4 I2C SFP busses
with 5 gpios.
Provide a i2c-gpio-shared driver that handles such hardware designs.
It manages up to 32 buses that share a single SCL line. All data
transfers (including recovery) are synchronized with a central mutex.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/i2c/busses/Kconfig | 10 ++
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-gpio-shared.c | 257 +++++++++++++++++++++++++++
3 files changed, 268 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-gpio-shared.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 8c935f867a37..fa05db759b15 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -691,6 +691,16 @@ config I2C_GPIO
This is a very simple bitbanging I2C driver utilizing the
arch-neutral GPIO API to control the SCL and SDA lines.
+config I2C_GPIO_SHARED
+ tristate "multiple GPIO-based bitbanging I2C with shared SCL"
+ depends on GPIOLIB || COMPILE_TEST
+ select I2C_ALGOBIT
+ help
+ This is an alternative of the I2C GPIO driver for devices with only
+ few GPIO pins where multiple busses with dedicated SDA lines share
+ a single SCL line. It can handle up to 32 buses, where N shared I2C
+ buses are implemented with N+1 GPIO.
+
config I2C_GPIO_FAULT_INJECTOR
bool "GPIO-based fault injector"
depends on I2C_GPIO
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 547123ab351f..724b09e613cb 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o
obj-$(CONFIG_I2C_EMEV2) += i2c-emev2.o
obj-$(CONFIG_I2C_EXYNOS5) += i2c-exynos5.o
obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
+obj-$(CONFIG_I2C_GPIO_SHARED) += i2c-gpio-shared.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_HISI) += i2c-hisi.o
obj-$(CONFIG_I2C_HIX5HD2) += i2c-hix5hd2.o
diff --git a/drivers/i2c/busses/i2c-gpio-shared.c b/drivers/i2c/busses/i2c-gpio-shared.c
new file mode 100644
index 000000000000..4c2e4011fcbf
--- /dev/null
+++ b/drivers/i2c/busses/i2c-gpio-shared.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Bitbanging driver for up to 32 I2C buses that share a single SCL pin */
+
+#include <linux/gpio/consumer.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+#define MAX_BUSES 32
+
+struct gpio_shared_ctx;
+
+struct gpio_shared_bus {
+ struct gpio_desc *sda;
+ struct i2c_adapter adap;
+ struct i2c_algo_bit_data bit_data;
+ struct i2c_bus_recovery_info recovery_info;
+ struct gpio_shared_ctx *ctx;
+};
+
+struct gpio_shared_ctx {
+ struct gpio_desc *scl;
+ struct mutex lock;
+ struct gpio_shared_bus bus[];
+};
+
+static struct gpio_shared_bus *adap_to_bus(struct i2c_adapter *adap)
+{
+ return container_of(adap, struct gpio_shared_bus, adap);
+}
+
+static struct gpio_shared_ctx *adap_to_ctx(struct i2c_adapter *adap)
+{
+ return adap_to_bus(adap)->ctx;
+}
+
+static void gpio_shared_setsda(void *data, int state)
+{
+ struct gpio_shared_bus *bus = data;
+
+ gpiod_set_value_cansleep(bus->sda, state);
+}
+
+static void gpio_shared_setscl(void *data, int state)
+{
+ struct gpio_shared_bus *bus = data;
+
+ gpiod_set_value_cansleep(bus->ctx->scl, state);
+}
+
+static int gpio_shared_getsda(void *data)
+{
+ struct gpio_shared_bus *bus = data;
+
+ return gpiod_get_value_cansleep(bus->sda);
+}
+
+static int gpio_shared_getscl(void *data)
+{
+ struct gpio_shared_bus *bus = data;
+
+ return gpiod_get_value_cansleep(bus->ctx->scl);
+}
+
+static int gpio_shared_pre_xfer(struct i2c_adapter *adap)
+{
+ return mutex_lock_interruptible(&adap_to_ctx(adap)->lock);
+}
+
+static void gpio_shared_recovery_set_scl(struct i2c_adapter *adap, int val)
+{
+ gpiod_set_value_cansleep(adap_to_ctx(adap)->scl, val);
+}
+
+static int gpio_shared_recovery_get_scl(struct i2c_adapter *adap)
+{
+ return gpiod_get_value_cansleep(adap_to_ctx(adap)->scl);
+}
+
+static void gpio_shared_recovery_set_sda(struct i2c_adapter *adap, int val)
+{
+ gpiod_set_value_cansleep(adap_to_bus(adap)->sda, val);
+}
+
+static int gpio_shared_recovery_get_sda(struct i2c_adapter *adap)
+{
+ return gpiod_get_value_cansleep(adap_to_bus(adap)->sda);
+}
+
+static void gpio_shared_prepare_recovery(struct i2c_adapter *adap)
+{
+ mutex_lock(&adap_to_ctx(adap)->lock);
+}
+
+static void gpio_shared_unlock(struct i2c_adapter *adap)
+{
+ mutex_unlock(&adap_to_ctx(adap)->lock);
+}
+
+static void gpio_shared_del_adapter(void *data)
+{
+ i2c_del_adapter(data);
+}
+
+static int gpio_shared_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int bus_count, sda_count, ret;
+ struct gpio_shared_ctx *ctx;
+ u32 used_buses = 0;
+
+ bus_count = device_get_child_node_count(dev);
+ if (!bus_count)
+ return dev_err_probe(dev, -EINVAL, "no buses defined\n");
+
+ if (bus_count > MAX_BUSES)
+ return dev_err_probe(dev, -EINVAL, "maximum of %d buses allowed\n", MAX_BUSES);
+
+ sda_count = gpiod_count(dev, "sda");
+ if (sda_count < 0)
+ return dev_err_probe(dev, sda_count, "sda-gpios missing\n");
+
+ if (sda_count != bus_count)
+ return dev_err_probe(dev, -EINVAL,
+ "sda-gpios count (%d) must match child node count (%d)\n",
+ sda_count, bus_count);
+
+ ctx = devm_kzalloc(dev, struct_size(ctx, bus, bus_count), GFP_KERNEL);
+ if (!ctx)
+ return dev_err_probe(dev, -ENOMEM, "memory allocation failed\n");
+
+ ret = devm_mutex_init(dev, &ctx->lock);
+ if (ret)
+ return dev_err_probe(dev, ret, "mutex initialization failed\n");
+
+ platform_set_drvdata(pdev, ctx);
+
+ ctx->scl = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN);
+ if (IS_ERR(ctx->scl))
+ return dev_err_probe(dev, PTR_ERR(ctx->scl), "shared SCL GPIO not found\n");
+
+ device_for_each_child_node_scoped(dev, child) {
+ struct i2c_algo_bit_data *bit_data;
+ struct i2c_bus_recovery_info *ri;
+ struct gpio_shared_bus *bus;
+ struct i2c_adapter *adap;
+ u32 bus_num, clock_freq;
+
+ /* Use the child's reg value as the index into the sda-gpios array. */
+ ret = fwnode_property_read_u32(child, "reg", &bus_num);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "missing reg property in child node\n");
+
+ if (bus_num >= sda_count)
+ return dev_err_probe(dev, -EINVAL,
+ "reg value %u out of range (max %d)\n",
+ bus_num, sda_count - 1);
+
+ if (used_buses & BIT(bus_num))
+ return dev_err_probe(dev, -EINVAL,
+ "duplicate definition of bus %d\n", bus_num);
+
+ bus = &ctx->bus[bus_num];
+ bit_data = &bus->bit_data;
+ ri = &bus->recovery_info;
+ adap = &bus->adap;
+
+ bus->sda = devm_gpiod_get_index(dev, "sda", bus_num,
+ GPIOD_OUT_HIGH_OPEN_DRAIN);
+ if (IS_ERR(bus->sda))
+ return dev_err_probe(dev, PTR_ERR(bus->sda),
+ "SDA GPIO for bus %u not found\n", bus_num);
+ /*
+ * Data transfer synchronization between multiple busses is realized by mutex
+ * locking/unlocking within pre_xfer and post_xfer helpers.
+ */
+ bus->ctx = ctx;
+ bit_data->data = bus;
+ bit_data->setsda = gpio_shared_setsda;
+ bit_data->setscl = gpio_shared_setscl;
+ bit_data->getsda = gpio_shared_getsda;
+ bit_data->getscl = gpio_shared_getscl;
+ bit_data->pre_xfer = gpio_shared_pre_xfer;
+ bit_data->post_xfer = gpio_shared_unlock;
+ bit_data->timeout = msecs_to_jiffies(100);
+ /*
+ * clock-frequency specifies the I2C bus frequency. Convert to the half-period
+ * delay in microseconds that i2c-algo-bit expects. Default to 5 us (~100 kHz)
+ * if not specified. This is usually lower than the configured frequency,
+ * especially near the 400 kHz limit.
+ */
+ if (!fwnode_property_read_u32(child, "clock-frequency", &clock_freq) &&
+ clock_freq > 0)
+ bit_data->udelay = max(1u, DIV_ROUND_UP(1000000, 2 * clock_freq));
+ else
+ bit_data->udelay = 5;
+ /*
+ * i2c_recover_bus() is called by the I2C core without going through pre_xfer
+ * and post_xfer. So the shared SCL mutex is NOT held at that point. Provide
+ * prepare_recovery/unprepare_recovery to explicitly prevent concurrent SCL
+ * access from another bus.
+ */
+ ri->recover_bus = i2c_generic_scl_recovery;
+ ri->set_scl = gpio_shared_recovery_set_scl;
+ ri->get_scl = gpio_shared_recovery_get_scl;
+ ri->set_sda = gpio_shared_recovery_set_sda;
+ ri->get_sda = gpio_shared_recovery_get_sda;
+ ri->prepare_recovery = gpio_shared_prepare_recovery;
+ ri->unprepare_recovery = gpio_shared_unlock;
+
+ adap->dev.parent = dev;
+ adap->owner = THIS_MODULE;
+ adap->algo_data = bit_data;
+ adap->bus_recovery_info = ri;
+ device_set_node(&adap->dev, child);
+ snprintf(adap->name, sizeof(adap->name), "i2c-gpio-shared:%u", bus_num);
+
+ ret = devm_add_action_or_reset(dev, gpio_shared_del_adapter, adap);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "bus %u cleanup registration failed\n", bus_num);
+
+ ret = i2c_bit_add_bus(adap);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register bus %u\n", bus_num);
+
+ dev_info(dev, "registered I2C bus %u with shared SCL (udelay %d us)\n",
+ bus_num, bit_data->udelay);
+
+ used_buses |= BIT(bus_num);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id gpio_shared_of_match[] = {
+ { .compatible = "i2c-gpio-shared" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, gpio_shared_of_match);
+
+static struct platform_driver gpio_shared_driver = {
+ .probe = gpio_shared_probe,
+ .driver = {
+ .name = "i2c-gpio-shared",
+ .of_match_table = gpio_shared_of_match,
+ },
+};
+
+module_platform_driver(gpio_shared_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Markus Stockhausen <markus.stockhausen@gmx.de>");
+MODULE_DESCRIPTION("bitbanging multi I2C driver for shared SCL");
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio
2026-05-11 16:25 ` [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio Markus Stockhausen
@ 2026-05-11 17:36 ` Rob Herring (Arm)
0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring (Arm) @ 2026-05-11 17:36 UTC (permalink / raw)
To: Markus Stockhausen
Cc: linux-i2c, brgl, devicetree, krzk+dt, wsa+renesas, andi.shyti,
conor+dt
On Mon, 11 May 2026 18:25:27 +0200, Markus Stockhausen wrote:
> Document the driver for bitbanged gpio I2C busses
> with shared SCL lines.
>
> Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> ---
> .../bindings/i2c/i2c-gpio-shared.yaml | 105 ++++++++++++++++++
> 1 file changed, 105 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio-shared.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/i2c/i2c-gpio-shared.example.dtb: i2c (i2c-gpio-shared): sda-gpios: [[4294967295, 6, 6], [4294967295, 7, 6]] is too long
from schema $id: http://devicetree.org/schemas/i2c/i2c-controller.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260511162528.84508-2-markus.stockhausen@gmx.de
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-11 16:25 [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Markus Stockhausen
2026-05-11 16:25 ` [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio Markus Stockhausen
2026-05-11 16:25 ` [PATCH v2 2/2] i2c: Add driver for gpio based busses with shared SCL Markus Stockhausen
@ 2026-05-12 11:00 ` Bartosz Golaszewski
2026-05-13 5:33 ` AW: " markus.stockhausen
2026-05-13 12:11 ` Rob Herring
2 siblings, 2 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2026-05-12 11:00 UTC (permalink / raw)
To: Markus Stockhausen
Cc: wsa+renesas, andi.shyti, robh, krzk+dt, conor+dt, linux-i2c,
devicetree, Marek Vasut
On Mon, May 11, 2026 at 6:25 PM Markus Stockhausen
<markus.stockhausen@gmx.de> wrote:
>
> This series adds support for hardware designs where multiple I2C
> gpio based busses are realized with dedicated SDA lines and a
> shared SCL line. This way N busses can be realized with N+1 gpios.
>
> Currently there are several Realtek switches that make use of
> this design. Samples are:
>
> HPE 1920-48G
> Linksys LGS310C
> Zyxel GS1920-24
> Engenius EWS2910
> D-Link DGS-1250
>
> While at first glance this might be a usecase for the new shared
> gpio architecture, discussion and testing shows that this is not
> trivial at all. A shared gpio is handled by a voting system. If
> there at least one user that votes for the GPIO to be "high",
> it stays high.
>
> So the implementation manages several classic bitbang buses with
> locking/unlocking in the pre_xfer/post_xfer handlers.
>
> Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
>
Hi!
A couple high-level issues. You'll soon hear from the DT maintainers
and they'll ask if the i2c-shared-gpio compatible corresponds with an
actual piece of hardware on the board. It does not, so the bindings
will be rejected.
A virtual device doing the mediation is fine but it probably needs to
be an auxiliary device instantiated dynamically from C code.
It just so happens that at the same time as you submitting this, Marek
Vasut wants to enable shared write-protect GPIOs for EEPROMs. This
seems to be a similar situation where the default is to keep the line
high and drive it low if there's at least one consumer that wants it.
I will rework the gpio-shared-proxy driver with that logic in mind.
Would that be enough to address the issue here?
Bart
^ permalink raw reply [flat|nested] 12+ messages in thread
* AW: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-12 11:00 ` [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Bartosz Golaszewski
@ 2026-05-13 5:33 ` markus.stockhausen
2026-05-13 7:12 ` Wolfram Sang
2026-05-13 12:11 ` Rob Herring
1 sibling, 1 reply; 12+ messages in thread
From: markus.stockhausen @ 2026-05-13 5:33 UTC (permalink / raw)
To: 'Bartosz Golaszewski'
Cc: wsa+renesas, andi.shyti, robh, krzk+dt, conor+dt, linux-i2c,
devicetree, 'Marek Vasut'
> Von: Bartosz Golaszewski <brgl@kernel.org>
> Gesendet: Dienstag, 12. Mai 2026 13:00
> An: Markus Stockhausen <markus.stockhausen@gmx.de>
> Betreff: Re: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
> ...
> Hi!
>
> A couple high-level issues. You'll soon hear from the DT maintainers
> and they'll ask if the i2c-shared-gpio compatible corresponds with an
> actual piece of hardware on the board. It does not, so the bindings
> will be rejected.
>
> A virtual device doing the mediation is fine but it probably needs to
> be an auxiliary device instantiated dynamically from C code.
This whole I2C coding is totally new to me. Can you please
elaborate what this means. Do I need to move over into some
other folder?
> It just so happens that at the same time as you submitting this, Marek
> Vasut wants to enable shared write-protect GPIOs for EEPROMs. This
> seems to be a similar situation where the default is to keep the line
> high and drive it low if there's at least one consumer that wants it.
> I will rework the gpio-shared-proxy driver with that logic in mind.
> Would that be enough to address the issue here?
I'm unsure if this helps. From my understanding SCL gets toggled
high/low for each transferred bit during an operation. This data block
may not be intercepted by other consumers
Markus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AW: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-13 5:33 ` AW: " markus.stockhausen
@ 2026-05-13 7:12 ` Wolfram Sang
2026-05-13 7:26 ` Bartosz Golaszewski
0 siblings, 1 reply; 12+ messages in thread
From: Wolfram Sang @ 2026-05-13 7:12 UTC (permalink / raw)
To: markus.stockhausen
Cc: 'Bartosz Golaszewski', andi.shyti, robh, krzk+dt,
conor+dt, linux-i2c, devicetree, 'Marek Vasut'
[-- Attachment #1: Type: text/plain, Size: 1015 bytes --]
> > It just so happens that at the same time as you submitting this, Marek
> > Vasut wants to enable shared write-protect GPIOs for EEPROMs. This
> > seems to be a similar situation where the default is to keep the line
> > high and drive it low if there's at least one consumer that wants it.
> > I will rework the gpio-shared-proxy driver with that logic in mind.
> > Would that be enough to address the issue here?
>
> I'm unsure if this helps. From my understanding SCL gets toggled
> high/low for each transferred bit during an operation. This data block
> may not be intercepted by other consumers
I agree. SCL is shared between the busses but if one bus uses it, the
bus needs exclusive access to generate the desired clock rate. The other
busses have to wait until the on-going transfer is over. This is
different from the shared-GPIO examples Bart gave which need all the
input ANDed together which would result in a chaos clock rate here.
But thanks for the explanations, Bart!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AW: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-13 7:12 ` Wolfram Sang
@ 2026-05-13 7:26 ` Bartosz Golaszewski
2026-05-13 7:47 ` Wolfram Sang
0 siblings, 1 reply; 12+ messages in thread
From: Bartosz Golaszewski @ 2026-05-13 7:26 UTC (permalink / raw)
To: Wolfram Sang
Cc: markus.stockhausen, andi.shyti, robh, krzk+dt, conor+dt,
linux-i2c, devicetree, Marek Vasut
On Wed, May 13, 2026 at 9:12 AM Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
>
> > > It just so happens that at the same time as you submitting this, Marek
> > > Vasut wants to enable shared write-protect GPIOs for EEPROMs. This
> > > seems to be a similar situation where the default is to keep the line
> > > high and drive it low if there's at least one consumer that wants it.
> > > I will rework the gpio-shared-proxy driver with that logic in mind.
> > > Would that be enough to address the issue here?
> >
> > I'm unsure if this helps. From my understanding SCL gets toggled
> > high/low for each transferred bit during an operation. This data block
> > may not be intercepted by other consumers
>
> I agree. SCL is shared between the busses but if one bus uses it, the
> bus needs exclusive access to generate the desired clock rate. The other
> busses have to wait until the on-going transfer is over. This is
> different from the shared-GPIO examples Bart gave which need all the
> input ANDed together which would result in a chaos clock rate here.
>
> But thanks for the explanations, Bart!
>
Yes, in that case it seems to me it needs a separate virtual device
driving it. In general, the idea Markus presented is fine but it must
not be described in DT. Instead, you need to create an auxiliary
device from subsystem code. For instance: if you see the `scl-gpios`
property, you create an auxiliary device, assign it the GPIO as a
software node reference and make the bus use it somehow. I don't have
an exact solution because I'd need to sit down and figure it out
precisely but that's the high-level idea I think may work.
Bart
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AW: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-13 7:26 ` Bartosz Golaszewski
@ 2026-05-13 7:47 ` Wolfram Sang
2026-05-13 7:50 ` Bartosz Golaszewski
0 siblings, 1 reply; 12+ messages in thread
From: Wolfram Sang @ 2026-05-13 7:47 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: markus.stockhausen, andi.shyti, robh, krzk+dt, conor+dt,
linux-i2c, devicetree, Marek Vasut
[-- Attachment #1: Type: text/plain, Size: 662 bytes --]
Hi Bart,
> Yes, in that case it seems to me it needs a separate virtual device
> driving it. In general, the idea Markus presented is fine but it must
> not be described in DT. Instead, you need to create an auxiliary
> device from subsystem code.
Okay, I get it that it should not be described in DT. DT should only
have standard i2c-gpio busses and the OS needs to figure the details,
right?
I wonder about the subsystem involvement, though. The I2C core doesn't
care about the scl-gpios property (except for GPIO recovery which is
moot with the i2c-gpio driver). So, maybe this should be handled in the
i2c-gpio driver instead?
All the best,
Wolfram
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: AW: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-13 7:47 ` Wolfram Sang
@ 2026-05-13 7:50 ` Bartosz Golaszewski
0 siblings, 0 replies; 12+ messages in thread
From: Bartosz Golaszewski @ 2026-05-13 7:50 UTC (permalink / raw)
To: Wolfram Sang
Cc: markus.stockhausen, andi.shyti, robh, krzk+dt, conor+dt,
linux-i2c, devicetree, Marek Vasut
On Wed, May 13, 2026 at 9:47 AM Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
> Hi Bart,
>
> > Yes, in that case it seems to me it needs a separate virtual device
> > driving it. In general, the idea Markus presented is fine but it must
> > not be described in DT. Instead, you need to create an auxiliary
> > device from subsystem code.
>
> Okay, I get it that it should not be described in DT. DT should only
> have standard i2c-gpio busses and the OS needs to figure the details,
> right?
>
> I wonder about the subsystem involvement, though. The I2C core doesn't
> care about the scl-gpios property (except for GPIO recovery which is
> moot with the i2c-gpio driver). So, maybe this should be handled in the
> i2c-gpio driver instead?
>
Sure, the driver can live under drivers/gpio/ and still be
instantiated in i2c core, no problem with that.
Bartosz
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-12 11:00 ` [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Bartosz Golaszewski
2026-05-13 5:33 ` AW: " markus.stockhausen
@ 2026-05-13 12:11 ` Rob Herring
2026-05-13 12:25 ` AW: " markus.stockhausen
1 sibling, 1 reply; 12+ messages in thread
From: Rob Herring @ 2026-05-13 12:11 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Markus Stockhausen, wsa+renesas, andi.shyti, krzk+dt, conor+dt,
linux-i2c, devicetree, Marek Vasut
On Tue, May 12, 2026 at 01:00:08PM +0200, Bartosz Golaszewski wrote:
> On Mon, May 11, 2026 at 6:25 PM Markus Stockhausen
> <markus.stockhausen@gmx.de> wrote:
> >
> > This series adds support for hardware designs where multiple I2C
> > gpio based busses are realized with dedicated SDA lines and a
> > shared SCL line. This way N busses can be realized with N+1 gpios.
> >
> > Currently there are several Realtek switches that make use of
> > this design. Samples are:
> >
> > HPE 1920-48G
> > Linksys LGS310C
> > Zyxel GS1920-24
> > Engenius EWS2910
> > D-Link DGS-1250
> >
> > While at first glance this might be a usecase for the new shared
> > gpio architecture, discussion and testing shows that this is not
> > trivial at all. A shared gpio is handled by a voting system. If
> > there at least one user that votes for the GPIO to be "high",
> > it stays high.
> >
> > So the implementation manages several classic bitbang buses with
> > locking/unlocking in the pre_xfer/post_xfer handlers.
> >
> > Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> >
>
> Hi!
>
> A couple high-level issues. You'll soon hear from the DT maintainers
> and they'll ask if the i2c-shared-gpio compatible corresponds with an
> actual piece of hardware on the board. It does not, so the bindings
> will be rejected.
Perhaps you missed I've already commented on this. I'm actually fine
with the binding at a high level.
But if we want to model it as N i2c-gpio nodes I'm fine with that as
well.
Rob
^ permalink raw reply [flat|nested] 12+ messages in thread
* AW: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
2026-05-13 12:11 ` Rob Herring
@ 2026-05-13 12:25 ` markus.stockhausen
0 siblings, 0 replies; 12+ messages in thread
From: markus.stockhausen @ 2026-05-13 12:25 UTC (permalink / raw)
To: 'Rob Herring', 'Bartosz Golaszewski'
Cc: wsa+renesas, andi.shyti, krzk+dt, conor+dt, linux-i2c, devicetree,
'Marek Vasut'
> Von: Rob Herring <robh@kernel.org>
> Gesendet: Mittwoch, 13. Mai 2026 14:12
> Betreff: Re: [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver
> ...
> > > So the implementation manages several classic bitbang buses with
> > > locking/unlocking in the pre_xfer/post_xfer handlers.
> > >
> > > Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
> > >
> >
> > Hi!
> >
> > A couple high-level issues. You'll soon hear from the DT maintainers
> > and they'll ask if the i2c-shared-gpio compatible corresponds with an
> > actual piece of hardware on the board. It does not, so the bindings
> > will be rejected.
>
> Perhaps you missed I've already commented on this. I'm actually fine
> with the binding at a high level.
>
> But if we want to model it as N i2c-gpio nodes I'm fine with that as
> well.
Thanks for all your feedback on this. If it helps the dts and the end
user I can offer to convert the driver into a simple drop-in replacement
for i2c-gpio. Enhancing the existing i2c-gpio driver is beyond my
current knowledge.
Markus
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-05-13 12:25 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11 16:25 [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Markus Stockhausen
2026-05-11 16:25 ` [PATCH v2 1/2] dt-bindings: i2c: Add i2c-shared-gpio Markus Stockhausen
2026-05-11 17:36 ` Rob Herring (Arm)
2026-05-11 16:25 ` [PATCH v2 2/2] i2c: Add driver for gpio based busses with shared SCL Markus Stockhausen
2026-05-12 11:00 ` [PATCH v2 0/2] i2c: Add i2c-shared-gpio driver Bartosz Golaszewski
2026-05-13 5:33 ` AW: " markus.stockhausen
2026-05-13 7:12 ` Wolfram Sang
2026-05-13 7:26 ` Bartosz Golaszewski
2026-05-13 7:47 ` Wolfram Sang
2026-05-13 7:50 ` Bartosz Golaszewski
2026-05-13 12:11 ` Rob Herring
2026-05-13 12:25 ` AW: " markus.stockhausen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox