git: 39bdc7d19b1a - main - gpiobus: add pin_config_32 and pin_access_32
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 27 Aug 2025 21:57:08 UTC
The branch main has been updated by vexeduxr:
URL: https://cgit.FreeBSD.org/src/commit/?id=39bdc7d19b1ac1443b1fb7adf81cfa3715625717
commit 39bdc7d19b1ac1443b1fb7adf81cfa3715625717
Author: Ahmad Khalifa <vexeduxr@FreeBSD.org>
AuthorDate: 2025-08-27 21:24:28 +0000
Commit: Ahmad Khalifa <vexeduxr@FreeBSD.org>
CommitDate: 2025-08-27 21:38:31 +0000
gpiobus: add pin_config_32 and pin_access_32
Add pin_config_32 and pin_access_32 to the gpiobus interface. These work
like the rest of the gpiobus interface. For example, if a child has the
following pins in it's ivars: {2, 7 ... 38} calling these functions with
pin 1 will configure/access pins 7 - 38 on the controller.
Reviewed by: mmel
Approved by: imp (mentor)
Differential Revision: https://reviews.freebsd.org/D51931
---
sys/dev/gpio/gpiobus.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
sys/dev/gpio/gpiobus_if.m | 30 +++++++++++++++++++++++++++
2 files changed, 82 insertions(+)
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index 650e662e4d86..5723c487e36b 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -1015,6 +1015,56 @@ gpiobus_pin_toggle(device_t dev, device_t child, uint32_t pin)
return (GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin]));
}
+/*
+ * Verify that a child has all the pins they are requesting
+ * to access in their ivars.
+ */
+static bool
+gpiobus_pin_verify_32(struct gpiobus_ivar *devi, uint32_t first_pin,
+ uint32_t num_pins)
+{
+ if (first_pin + num_pins > devi->npins)
+ return (false);
+
+ /* Make sure the pins are consecutive. */
+ for (uint32_t pin = first_pin; pin < first_pin + num_pins - 1; pin++) {
+ if (devi->pins[pin] + 1 != devi->pins[pin + 1])
+ return (false);
+ }
+
+ return (true);
+}
+
+static int
+gpiobus_pin_access_32(device_t dev, device_t child, uint32_t first_pin,
+ uint32_t clear_pins, uint32_t change_pins, uint32_t *orig_pins)
+{
+ struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
+ struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
+
+ if (!gpiobus_pin_verify_32(devi, first_pin, 32))
+ return (EINVAL);
+
+ return (GPIO_PIN_ACCESS_32(sc->sc_dev, devi->pins[first_pin],
+ clear_pins, change_pins, orig_pins));
+}
+
+static int
+gpiobus_pin_config_32(device_t dev, device_t child, uint32_t first_pin,
+ uint32_t num_pins, uint32_t *pin_flags)
+{
+ struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
+ struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
+
+ if (num_pins > 32)
+ return (EINVAL);
+ if (!gpiobus_pin_verify_32(devi, first_pin, num_pins))
+ return (EINVAL);
+
+ return (GPIO_PIN_CONFIG_32(sc->sc_dev,
+ devi->pins[first_pin], num_pins, pin_flags));
+}
+
static int
gpiobus_pin_getname(device_t dev, uint32_t pin, char *name)
{
@@ -1093,6 +1143,8 @@ static device_method_t gpiobus_methods[] = {
DEVMETHOD(gpiobus_pin_get, gpiobus_pin_get),
DEVMETHOD(gpiobus_pin_set, gpiobus_pin_set),
DEVMETHOD(gpiobus_pin_toggle, gpiobus_pin_toggle),
+ DEVMETHOD(gpiobus_pin_access_32,gpiobus_pin_access_32),
+ DEVMETHOD(gpiobus_pin_config_32,gpiobus_pin_config_32),
DEVMETHOD(gpiobus_pin_getname, gpiobus_pin_getname),
DEVMETHOD(gpiobus_pin_setname, gpiobus_pin_setname),
diff --git a/sys/dev/gpio/gpiobus_if.m b/sys/dev/gpio/gpiobus_if.m
index 8bf29839ef4e..890738c4e809 100644
--- a/sys/dev/gpio/gpiobus_if.m
+++ b/sys/dev/gpio/gpiobus_if.m
@@ -106,6 +106,36 @@ METHOD int pin_setflags {
uint32_t flags;
};
+#
+# Simultaneously read and/or change up to 32 adjacent pins.
+# If the device cannot change the pins simultaneously, returns EOPNOTSUPP.
+#
+# More details about using this interface can be found in sys/gpio.h
+#
+METHOD int pin_access_32 {
+ device_t dev;
+ device_t child;
+ uint32_t first_pin;
+ uint32_t clear_pins;
+ uint32_t change_pins;
+ uint32_t *orig_pins;
+};
+
+#
+# Simultaneously configure up to 32 adjacent pins.
+# This is intended to change the configuration of all the pins simultaneously,
+# but unlike pin_access_32, this will not fail if the hardware can't do so.
+#
+# More details about using this interface can be found in sys/gpio.h
+#
+METHOD int pin_config_32 {
+ device_t dev;
+ device_t child;
+ uint32_t first_pin;
+ uint32_t num_pins;
+ uint32_t *pin_flags;
+};
+
#
# Get the pin name
#