diff mbox series

[1/4] pinctrl: rockchip: Add gpio_request_enable() ops

Message ID 20240511112821.1156519-2-jonas@kwiboo.se
State New
Delegated to: Kever Yang
Headers show
Series rockchip: Add gpio request() ops and drop PCIe reset-gpios workaround | expand

Commit Message

Jonas Karlman May 11, 2024, 11:28 a.m. UTC
Some boards use pinctrl to set a non-gpio pinmux on a pin that is later
requested to be used for gpio output.

Add a pin_to_bank() helper and implement gpio_request_enable() ops so
that the gpio request() ops can be implemented and a gpio requested pin
automatically is pinmuxed for gpio use, similar to Linux kernel.

Reset ctrl->nr_pins to 0 so that pin_to_bank() can locate a bank after
the second probe in U-Boot proper.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
The pin_to_bank() helper will also be used in a follow up series adding
support for the pinmux status cmd.
---
 .../pinctrl/rockchip/pinctrl-rockchip-core.c  | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)
diff mbox series

Patch

diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
index 8ef089994f46..a423abcafb23 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
@@ -150,6 +150,23 @@  static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 	return ((val >> bit) & mask);
 }
 
+static struct rockchip_pin_bank *rockchip_pin_to_bank(struct udevice *dev,
+						      unsigned int pin)
+{
+	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
+	struct rockchip_pin_ctrl *ctrl = priv->ctrl;
+	struct rockchip_pin_bank *bank = ctrl->pin_banks;
+	int i;
+
+	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		if (pin >= bank->pin_base &&
+		    pin < bank->pin_base + bank->nr_pins)
+			return bank;
+	}
+
+	return NULL;
+}
+
 static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
 					 int index)
 {	struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
@@ -250,6 +267,18 @@  static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	return 0;
 }
 
+static int rockchip_pinctrl_gpio_request_enable(struct udevice *dev,
+						unsigned int selector)
+{
+	struct rockchip_pin_bank *bank;
+
+	bank = rockchip_pin_to_bank(dev, selector);
+	if (!bank)
+		return -EINVAL;
+
+	return rockchip_set_mux(bank, selector - bank->pin_base, RK_FUNC_GPIO);
+}
+
 static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
 	{ 2, 4, 8, 12, -1, -1, -1, -1 },
 	{ 3, 6, 9, 12, -1, -1, -1, -1 },
@@ -497,6 +526,7 @@  static int rockchip_pinctrl_set_state(struct udevice *dev,
 const struct pinctrl_ops rockchip_pinctrl_ops = {
 	.set_state			= rockchip_pinctrl_set_state,
 	.get_gpio_mux			= rockchip_pinctrl_get_gpio_mux,
+	.gpio_request_enable		= rockchip_pinctrl_gpio_request_enable,
 };
 
 /* retrieve the soc specific data */
@@ -513,6 +543,7 @@  static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
 	drv_pmu_offs = ctrl->pmu_drv_offset;
 	drv_grf_offs = ctrl->grf_drv_offset;
 	bank = ctrl->pin_banks;
+	ctrl->nr_pins = 0;
 
 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
 		int bank_pins = 0;