[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20251105-add-external-mux-enable-gpio-v1-2-e59cba6f9e47@vaisala.com>
Date: Wed, 05 Nov 2025 14:49:13 +0000
From: Tapio Reijonen <tapio.reijonen@...sala.com>
To: Peter Rosin <peda@...ntia.se>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>
Cc: devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
Tapio Reijonen <tapio.reijonen@...sala.com>
Subject: [PATCH 2/2] mux: gpio: Add external mux enable gpio
Add optional gpio to control gpio-controlled multiplexer
gpio pins, according to the state of the mux.
When the gpio mux controller transitions state,
it first configures all required gpio mux pins,
and then sets optional enable gpio pin to logic high.
When gpio mux controller sets "MUX_IDLE_DISCONNECT",
the optional enable gpio pin is set low.
Signed-off-by: Tapio Reijonen <tapio.reijonen@...sala.com>
---
drivers/mux/gpio.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/mux/gpio.c b/drivers/mux/gpio.c
index 4cc3202c58f364e80ad9f632763f568d184d4173..ee2bca1214d67feb3031fe60556b68b59293f0e3 100644
--- a/drivers/mux/gpio.c
+++ b/drivers/mux/gpio.c
@@ -19,6 +19,7 @@
struct mux_gpio {
struct gpio_descs *gpios;
+ struct gpio_desc *enable_gpio;
};
static int mux_gpio_set(struct mux_control *mux, int state)
@@ -27,10 +28,18 @@ static int mux_gpio_set(struct mux_control *mux, int state)
DECLARE_BITMAP(values, BITS_PER_TYPE(state));
u32 value = state;
+ if (mux_gpio->enable_gpio && state == MUX_IDLE_DISCONNECT) {
+ gpiod_set_value_cansleep(mux_gpio->enable_gpio, 0);
+ return 0;
+ }
+
bitmap_from_arr32(values, &value, BITS_PER_TYPE(value));
gpiod_multi_set_value_cansleep(mux_gpio->gpios, values);
+ if (mux_gpio->enable_gpio)
+ gpiod_set_value_cansleep(mux_gpio->enable_gpio, 1);
+
return 0;
}
@@ -71,14 +80,23 @@ static int mux_gpio_probe(struct platform_device *pdev)
WARN_ON(pins != mux_gpio->gpios->ndescs);
mux_chip->mux->states = BIT(pins);
+ mux_gpio->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(mux_gpio->enable_gpio))
+ return dev_err_probe(dev, PTR_ERR(mux_gpio->enable_gpio),
+ "failed to get optional enable gpio\n");
+
ret = device_property_read_u32(dev, "idle-state", (u32 *)&idle_state);
- if (ret >= 0 && idle_state != MUX_IDLE_AS_IS) {
- if (idle_state < 0 || idle_state >= mux_chip->mux->states) {
- dev_err(dev, "invalid idle-state %u\n", idle_state);
- return -EINVAL;
+ if (ret >= 0) {
+ if (idle_state == MUX_IDLE_DISCONNECT)
+ mux_chip->mux->idle_state = MUX_IDLE_DISCONNECT;
+ else if (idle_state != MUX_IDLE_AS_IS) {
+ if (idle_state < 0 || idle_state >= mux_chip->mux->states) {
+ return dev_err_probe(dev, -EINVAL,
+ "invalid idle-state %d\n",
+ idle_state);
+ }
+ mux_chip->mux->idle_state = idle_state;
}
-
- mux_chip->mux->idle_state = idle_state;
}
ret = devm_regulator_get_enable_optional(dev, "mux");
--
2.47.3
Powered by blists - more mailing lists