[PATCH v13 1/1] mux: Add driver for Renesas RZ/V2H VBENCTL VBUS_SEL mux

Tommaso Merciai <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel
Message-ID <34bd85766a9ef4df844fd20208b503177776b589.1786347402.git.tommaso.merciai.xr@bp.renesas.com>
As per the RZ/V2H(P) HW manual, VBUSEN can be controlled by the VBUS_SEL
bit of the VBENCTL Control Register. This register is mapped in the
reset framework. The reset driver expose this register as mux-controller
and instantiates this driver. The consumer will use the mux API to
control the VBUS_SEL bit.

Reviewed-by: Lad Prabhakar <[email protected]>
Reviewed-by: Alvin Šipraga <[email protected]>
Reviewed-by: Philipp Zabel <[email protected]>
Signed-off-by: Tommaso Merciai <[email protected]>
---
v12->v13
 - Renamed CONFIG_MUX_RZV2H_USB_VBENCTL to CONFIG_MUX_RZV2H_VBENCTL and
   propagated the rename to the source file and module name.
 - Dropped the unneeded "depends on OF".
 - Added the missing "To compile the driver as a module" paragraph to the
   Kconfig help text.
 - Used the REG_FIELD() macro instead of open-coding struct reg_field, and
   made it const to keep checkpatch --strict without warning.
 - Used dev->parent instead of adev->dev.parent in dev_get_regmap().
 - Collected Reviewed-by tags from Alvin and Prabhakar (the changes above are
   cosmetic, please let me know if you want them dropped).

v11->v12
 - No changes, just rebased on top of next-20260714

v10->v11:
 - No changes.

v9->v10:
 - No changes.

v8->v9:
 - Fixed driver comment year (2025 -> 2026)
 - Switch from devm_regmap_init_mmio() to dev_get_regmap().
 - Drop unnecessasry include bitops.h, of.h, property.h and
   drivers/reset/reset-rzv2h-usb2phy.h headers, driver is now based on regmap.
 - Collected PZabel tag.

v7->v8:
 - No changes.

v6->v7:
 - No changes.

v5->v6:
 - No changes.

v4->v5:
 - Changed file name to rzv2h-usb-vbenctl.c and Fixed
   Makefile, Kconfig, function names accordingly.
 - Changed driver .name to "vbenctl" and fix auxiliary_device_id name.
 - Updated commit msg.

v3->v4:
 - Removed mux_chip->dev.of_node not needed.

v2->v3:
 - Added mux_chip->dev.of_node = dev->of_node->child as the mux-controller
   is an internal node.
 - Fixed auxiliary_device_id name.
 - Get rdev using from platform_data.
 - Drop struct auxiliary_device adev from reset_rzv2h_usb2phy_adev
   as it is needed.
 - Drop to_reset_rzv2h_usb2phy_adev() as it is not needed.

v1->v2:
 - New patch

 drivers/mux/Kconfig         | 13 ++++++
 drivers/mux/Makefile        |  2 +
 drivers/mux/rzv2h-vbenctl.c | 81 +++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+)
 create mode 100644 drivers/mux/rzv2h-vbenctl.c

diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig
index 6d17dfa25dad..eb34457beaab 100644
--- a/drivers/mux/Kconfig
+++ b/drivers/mux/Kconfig
@@ -70,6 +70,19 @@ config MUX_MMIO
 	  To compile the driver as a module, choose M here: the module will
 	  be called mux-mmio.
 
+config MUX_RZV2H_VBENCTL
+	tristate "Renesas RZ/V2H VBENCTL VBUS_SEL mux driver"
+	depends on RESET_RZV2H_USB2PHY || COMPILE_TEST
+	select REGMAP
+	select AUXILIARY_BUS
+	default RESET_RZV2H_USB2PHY
+	help
+	  Support for the VBENCTL VBUS_SEL mux implemented on Renesas
+	  RZ/V2H SoCs.
+
+	  To compile the driver as a module, choose M here: the module will
+	  be called mux-rzv2h-vbenctl.
+
 endmenu
 
 endif # MULTIPLEXER
diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile
index 6e9fa47daf56..0854c04613b9 100644
--- a/drivers/mux/Makefile
+++ b/drivers/mux/Makefile
@@ -8,9 +8,11 @@ mux-adg792a-objs		:= adg792a.o
 mux-adgs1408-objs		:= adgs1408.o
 mux-gpio-objs			:= gpio.o
 mux-mmio-objs			:= mmio.o
+mux-rzv2h-vbenctl-objs		:= rzv2h-vbenctl.o
 
 obj-$(CONFIG_MULTIPLEXER)	+= mux-core.o
 obj-$(CONFIG_MUX_ADG792A)	+= mux-adg792a.o
 obj-$(CONFIG_MUX_ADGS1408)	+= mux-adgs1408.o
 obj-$(CONFIG_MUX_GPIO)		+= mux-gpio.o
 obj-$(CONFIG_MUX_MMIO)		+= mux-mmio.o
+obj-$(CONFIG_MUX_RZV2H_VBENCTL)	+= mux-rzv2h-vbenctl.o
diff --git a/drivers/mux/rzv2h-vbenctl.c b/drivers/mux/rzv2h-vbenctl.c
new file mode 100644
index 000000000000..2699458045f3
--- /dev/null
+++ b/drivers/mux/rzv2h-vbenctl.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/V2H(P) VBENCTL VBUS_SEL mux driver
+ *
+ * Copyright (C) 2026 Renesas Electronics Corp.
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/mux/driver.h>
+#include <linux/regmap.h>
+
+#define RZV2H_VBENCTL		0xf0c
+
+struct mux_rzv2h_vbenctl_priv {
+	struct regmap_field *field;
+};
+
+static int mux_rzv2h_vbenctl_set(struct mux_control *mux, int state)
+{
+	struct mux_rzv2h_vbenctl_priv *priv = mux_chip_priv(mux->chip);
+
+	return regmap_field_write(priv->field, state);
+}
+
+static const struct mux_control_ops mux_rzv2h_vbenctl_ops = {
+	.set = mux_rzv2h_vbenctl_set,
+};
+
+static int mux_rzv2h_vbenctl_probe(struct auxiliary_device *adev,
+				   const struct auxiliary_device_id *id)
+{
+	const struct reg_field reg_field = REG_FIELD(RZV2H_VBENCTL, 0, 0);
+	struct mux_rzv2h_vbenctl_priv *priv;
+	struct device *dev = &adev->dev;
+	struct mux_chip *mux_chip;
+	struct regmap *regmap;
+	int ret;
+
+	regmap = dev_get_regmap(dev->parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
+	mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*priv));
+	if (IS_ERR(mux_chip))
+		return PTR_ERR(mux_chip);
+
+	priv = mux_chip_priv(mux_chip);
+
+	priv->field = devm_regmap_field_alloc(dev, regmap, reg_field);
+	if (IS_ERR(priv->field))
+		return PTR_ERR(priv->field);
+
+	mux_chip->ops = &mux_rzv2h_vbenctl_ops;
+	mux_chip->mux[0].states = 2;
+	mux_chip->mux[0].idle_state = MUX_IDLE_AS_IS;
+
+	ret = devm_mux_chip_register(dev, mux_chip);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to register mux chip\n");
+
+	return 0;
+}
+
+static const struct auxiliary_device_id mux_rzv2h_vbenctl_ids[] = {
+	{ .name = "rzv2h_usb2phy_reset.vbenctl" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, mux_rzv2h_vbenctl_ids);
+
+static struct auxiliary_driver mux_rzv2h_vbenctl_driver = {
+	.name		= "vbenctl",
+	.probe		= mux_rzv2h_vbenctl_probe,
+	.id_table	= mux_rzv2h_vbenctl_ids,
+};
+module_auxiliary_driver(mux_rzv2h_vbenctl_driver);
+
+MODULE_DESCRIPTION("RZ/V2H VBENCTL VBUS_SEL mux driver");
+MODULE_AUTHOR("Tommaso Merciai <[email protected]>");
+MODULE_LICENSE("GPL");
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.