[PATCH v7 0/2] add gpio-line-mux

Jonas Jelonek posted 2 patches 1 month, 1 week ago
.../bindings/gpio/gpio-line-mux.yaml          | 107 +++++++++++++++
MAINTAINERS                                   |   6 +
drivers/gpio/Kconfig                          |   9 ++
drivers/gpio/Makefile                         |   1 +
drivers/gpio/gpio-line-mux.c                  | 126 ++++++++++++++++++
5 files changed, 249 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/gpio-line-mux.yaml
create mode 100644 drivers/gpio/gpio-line-mux.c
[PATCH v7 0/2] add gpio-line-mux
Posted by Jonas Jelonek 1 month, 1 week ago
This proposes a new type of virtual GPIO controller and corresponding
driver to provide a 1-to-many mapping between virtual GPIOs and a single
real GPIO in combination with a multiplexer. Existing drivers apparently
do not serve the purpose for what I need.

I came across an issue with a switch device from Zyxel which has two
SFP+ cages. Most similar switches either wire up the SFP signals
(RX_LOS, MOD_ABS, TX_FAULT, TX_DISABLE) directly to the SoC (if it has
enough GPIOs) or two a GPIO expander (for which a driver usually
exists). However, Zyxel decided to do it differently in the following
way:
  The signals RX_LOS, MOD_ABS and TX_FAULT share a single GPIO line to
  the SoC. Which one is actually connected to that GPIO line at a time
  is controlled by a separate multiplexer, a GPIO multiplexer in this
  case (which uses two other GPIOs). Only the TX_DISABLE is separate.

The SFP core/driver doesn't seem to support such a usecase for now, for
each signal one needs to specify a separate GPIO like:

  los-gpio = <&gpio0 0 GPIO_ACTIVE_HIGH>;
  mod-def0-gpio = <&gpio0 1 GPIO_ACTIVE_LOW>;
  ...

But for my device, I actually need to directly specify multiplexing
behavior in the SFP node or provide a mux-controller with 'mux-controls'.

To fill this gap, I created a dt-schema and a working driver which
exactly does what is needed. It takes a phandle to a mux-controller and
the 'shared' gpio, and provides several virtual GPIOs based on the
gpio-line-mux-states property.

This virtual gpio-controller can then be referenced in the '-gpio'
properties of the SFP node (or other nodes depending on the usecase) as
usual and do not require any modification to the SFP core/driver.

---
Changelog:

v7: - dt-bindings fixes:
      - dropped unneeded reference
      - adjusted presumably confusing example
      - added missing colon

Link to v6:
https://lore.kernel.org/linux-gpio/20251111092705.196465-1-jelonek.jonas@gmail.com/

v6: - added count member + __counted_by attribute for gpio_mux_states
    - included Reviewed-by tags

Link to v5:
https://lore.kernel.org/linux-gpio/20251105163610.610793-1-jelonek.jonas@gmail.com/

v5: - renamed "shared" to "muxed" to avoid confusion with Bartosz' work
    - dropped Reviewed-by of Krzysztof due to binding change
    - use GPIOD_IN in devm_gpiod_get instead of calling
      gpiod_direction_input explicitly afterwards

Link to v4:
https://lore.kernel.org/linux-gpio/20251105103607.393353-1-jelonek.jonas@gmail.com/

v4: - dropped useless cast (as suggested by Thomas)
    - dropped unneeded locking (as suggested by Peter)
    - fixed wording in commit message
    - included Reviewed-by of Krzysztof

Link to v3:
https://lore.kernel.org/linux-gpio/20251104210021.247476-1-jelonek.jonas@gmail.com/

v3: - fixed dt_binding_check errors in DT schema
    - as requested by Rob (for DT schema):
      - removed example from gpio-mux.yaml
      - added '|' to preserve formatting
      - 'shared-gpio' --> 'shared-gpios'
    - general fixes to DT schema
    - use mux_control_select_delay (as suggested by Peter) with
      hopefully reasonable delay of 100us
    - gpiochip ops implementation changes:
      - drop '.set' implementation (as suggested by Peter)
      - new '.set' implementation just returning -EOPNOTSUPP
      - '.direction_output' and '.direction_input' dropped
      - '.get_direction' returns fixed value for 'input'
    - direction of shared gpio set to input during probe
    - as suggested by Thomas
      - usage of dev_err_probe
      - further simplifications

    Since the consensus was that this should be input-only,
    '.direction_output' and '.direction_input' have been dropped
    completely, as suggested in the docs of struct gpio_chip. '.set' is
    kept but returns -ENOTSUPP.

    The shared GPIO is set to input during probe, thus '.direction_input'
    doesn't need to be implemented. '.get_direction' is kept (as
    suggested in docs of struct gpio_chip) but always returns
    GPIO_LINE_DIRECTION_IN.

Link to v2:
https://lore.kernel.org/linux-gpio/20251026231754.2368904-1-jelonek.jonas@gmail.com/

v2: - as requested by Linus:
      - renamed from 'gpio-split' to 'gpio-line-mux'
      - added better description and examples to DT bindings
    - simplified driver
    - added missing parts to DT bindings
    - dropped RFC tag
    - renamed patchset

Link to v1 (in case it isn't linked properly due to changed title):
https://lore.kernel.org/linux-gpio/20251009223501.570949-1-jelonek.jonas@gmail.com/

---
Jonas Jelonek (2):
  dt-bindings: gpio: add gpio-line-mux controller
  gpio: add gpio-line-mux driver

 .../bindings/gpio/gpio-line-mux.yaml          | 107 +++++++++++++++
 MAINTAINERS                                   |   6 +
 drivers/gpio/Kconfig                          |   9 ++
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-line-mux.c                  | 126 ++++++++++++++++++
 5 files changed, 249 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-line-mux.yaml
 create mode 100644 drivers/gpio/gpio-line-mux.c


base-commit: 48befae0d6eee275c3e30d1cd45f39d6ba011e19
-- 
2.48.1
Re: [PATCH v7 0/2] add gpio-line-mux
Posted by Linus Walleij 1 month ago
On Sat, Dec 27, 2025 at 7:01 PM Jonas Jelonek <jelonek.jonas@gmail.com> wrote:

> This proposes a new type of virtual GPIO controller and corresponding
> driver to provide a 1-to-many mapping between virtual GPIOs and a single
> real GPIO in combination with a multiplexer. Existing drivers apparently
> do not serve the purpose for what I need.

Thanks for persisting and doing this the right way all the way through,
Jonas!

This driver will probably be helpful for other users with the same
quirk in the future.

Yours,
Linus Walleij
Re: [PATCH v7 0/2] add gpio-line-mux
Posted by Bartosz Golaszewski 1 month ago
On Sat, 27 Dec 2025 18:01:32 +0000, Jonas Jelonek wrote:
> This proposes a new type of virtual GPIO controller and corresponding
> driver to provide a 1-to-many mapping between virtual GPIOs and a single
> real GPIO in combination with a multiplexer. Existing drivers apparently
> do not serve the purpose for what I need.
> 
> I came across an issue with a switch device from Zyxel which has two
> SFP+ cages. Most similar switches either wire up the SFP signals
> (RX_LOS, MOD_ABS, TX_FAULT, TX_DISABLE) directly to the SoC (if it has
> enough GPIOs) or two a GPIO expander (for which a driver usually
> exists). However, Zyxel decided to do it differently in the following
> way:
>   The signals RX_LOS, MOD_ABS and TX_FAULT share a single GPIO line to
>   the SoC. Which one is actually connected to that GPIO line at a time
>   is controlled by a separate multiplexer, a GPIO multiplexer in this
>   case (which uses two other GPIOs). Only the TX_DISABLE is separate.
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: gpio: add gpio-line-mux controller
      commit: 2a7618ba8698874e9871a8ec5453e0068e94d9e5
[2/2] gpio: add gpio-line-mux driver
      commit: 2b03d9a40cd1fea42fd65d2b66df80edc0f374c8

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>