diff mbox series

[RFC,2/3] pinctrl: starfive: jh7110: support forcing inputs to low/high

Message ID 20250422162250.436169-3-uwu@icenowy.me
State New
Headers show
Series pinctrl: starfive: jh7110: support force inputs | expand

Commit Message

Icenowy Zheng April 22, 2025, 4:22 p.m. UTC
The internal input signals inside JH7110 SoC (output of the pin
controller) could be routed to fixed low/high level instead of external
GPIOs.

Support this feature in the pinctrl driver, which is quite useful for
some peripherals (e.g. USB) because of the low GPIO count of JH7110.

Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
 .../starfive/pinctrl-starfive-jh7110.c        | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)
diff mbox series

Patch

diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
index 1d0d6c224c104..5652f9bb658a2 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
@@ -837,6 +837,41 @@  static void jh7110_disable_clock(void *data)
 	clk_disable_unprepare(data);
 }
 
+static int jh7110_force_input_pins(struct jh7110_pinctrl *sfp,
+				   const char *property, u32 forced_input)
+{
+	int i, nforce;
+	int ret;
+	u32 pin, val;
+	unsigned int offset, shift;
+	struct device *dev = sfp->dev;
+	const struct jh7110_pinctrl_soc_info *info = sfp->info;
+
+	nforce = of_property_count_u32_elems(dev->of_node, property);
+
+	if (nforce > 0) {
+		for (i = 0; i < nforce; i++) {
+			ret = of_property_read_u32_index(dev->of_node, property,
+							 i, &pin);
+			if (ret)
+				return ret;
+
+			offset = 4 * (pin / 4);
+			shift  = 8 * (pin % 4);
+
+			val = readl_relaxed(sfp->base +
+					    info->gpi_reg_base + offset);
+			val &= info->gpi_mask << shift;
+			val |= (forced_input & info->gpi_mask) << shift;
+
+			writel_relaxed(val, sfp->base +
+					    info->gpi_reg_base + offset);
+		}
+	}
+
+	return 0;
+}
+
 int jh7110_pinctrl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -964,6 +999,14 @@  int jh7110_pinctrl_probe(struct platform_device *pdev)
 
 	dev_info(dev, "StarFive GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
 
+	ret = jh7110_force_input_pins(sfp, "starfive,force-low-inputs", 0);
+	if (ret)
+		return ret;
+
+	ret = jh7110_force_input_pins(sfp, "starfive,force-high-inputs", 1);
+	if (ret)
+		return ret;
+
 	return pinctrl_enable(sfp->pctl);
 }
 EXPORT_SYMBOL_GPL(jh7110_pinctrl_probe);