Skip to content

Commit 39bdc7d

Browse files
committed
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
1 parent e4eba4b commit 39bdc7d

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

sys/dev/gpio/gpiobus.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,56 @@ gpiobus_pin_toggle(device_t dev, device_t child, uint32_t pin)
10151015
return (GPIO_PIN_TOGGLE(sc->sc_dev, devi->pins[pin]));
10161016
}
10171017

1018+
/*
1019+
* Verify that a child has all the pins they are requesting
1020+
* to access in their ivars.
1021+
*/
1022+
static bool
1023+
gpiobus_pin_verify_32(struct gpiobus_ivar *devi, uint32_t first_pin,
1024+
uint32_t num_pins)
1025+
{
1026+
if (first_pin + num_pins > devi->npins)
1027+
return (false);
1028+
1029+
/* Make sure the pins are consecutive. */
1030+
for (uint32_t pin = first_pin; pin < first_pin + num_pins - 1; pin++) {
1031+
if (devi->pins[pin] + 1 != devi->pins[pin + 1])
1032+
return (false);
1033+
}
1034+
1035+
return (true);
1036+
}
1037+
1038+
static int
1039+
gpiobus_pin_access_32(device_t dev, device_t child, uint32_t first_pin,
1040+
uint32_t clear_pins, uint32_t change_pins, uint32_t *orig_pins)
1041+
{
1042+
struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
1043+
struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
1044+
1045+
if (!gpiobus_pin_verify_32(devi, first_pin, 32))
1046+
return (EINVAL);
1047+
1048+
return (GPIO_PIN_ACCESS_32(sc->sc_dev, devi->pins[first_pin],
1049+
clear_pins, change_pins, orig_pins));
1050+
}
1051+
1052+
static int
1053+
gpiobus_pin_config_32(device_t dev, device_t child, uint32_t first_pin,
1054+
uint32_t num_pins, uint32_t *pin_flags)
1055+
{
1056+
struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
1057+
struct gpiobus_ivar *devi = GPIOBUS_IVAR(child);
1058+
1059+
if (num_pins > 32)
1060+
return (EINVAL);
1061+
if (!gpiobus_pin_verify_32(devi, first_pin, num_pins))
1062+
return (EINVAL);
1063+
1064+
return (GPIO_PIN_CONFIG_32(sc->sc_dev,
1065+
devi->pins[first_pin], num_pins, pin_flags));
1066+
}
1067+
10181068
static int
10191069
gpiobus_pin_getname(device_t dev, uint32_t pin, char *name)
10201070
{
@@ -1093,6 +1143,8 @@ static device_method_t gpiobus_methods[] = {
10931143
DEVMETHOD(gpiobus_pin_get, gpiobus_pin_get),
10941144
DEVMETHOD(gpiobus_pin_set, gpiobus_pin_set),
10951145
DEVMETHOD(gpiobus_pin_toggle, gpiobus_pin_toggle),
1146+
DEVMETHOD(gpiobus_pin_access_32,gpiobus_pin_access_32),
1147+
DEVMETHOD(gpiobus_pin_config_32,gpiobus_pin_config_32),
10961148
DEVMETHOD(gpiobus_pin_getname, gpiobus_pin_getname),
10971149
DEVMETHOD(gpiobus_pin_setname, gpiobus_pin_setname),
10981150

sys/dev/gpio/gpiobus_if.m

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,36 @@
106106
uint32_t flags;
107107
};
108108

109+
#
110+
# Simultaneously read and/or change up to 32 adjacent pins.
111+
# If the device cannot change the pins simultaneously, returns EOPNOTSUPP.
112+
#
113+
# More details about using this interface can be found in sys/gpio.h
114+
#
115+
METHOD int pin_access_32 {
116+
device_t dev;
117+
device_t child;
118+
uint32_t first_pin;
119+
uint32_t clear_pins;
120+
uint32_t change_pins;
121+
uint32_t *orig_pins;
122+
};
123+
124+
#
125+
# Simultaneously configure up to 32 adjacent pins.
126+
# This is intended to change the configuration of all the pins simultaneously,
127+
# but unlike pin_access_32, this will not fail if the hardware can't do so.
128+
#
129+
# More details about using this interface can be found in sys/gpio.h
130+
#
131+
METHOD int pin_config_32 {
132+
device_t dev;
133+
device_t child;
134+
uint32_t first_pin;
135+
uint32_t num_pins;
136+
uint32_t *pin_flags;
137+
};
138+
109139
#
110140
# Get the pin name
111141
#

0 commit comments

Comments
 (0)