svn commit: r354065 - head/sys/dev/gpio
Andriy Gapon
avg at FreeBSD.org
Fri Oct 25 09:37:55 UTC 2019
Author: avg
Date: Fri Oct 25 09:37:54 2019
New Revision: 354065
URL: https://svnweb.freebsd.org/changeset/base/354065
Log:
gpioiic: set output after switching to output mode if presetting it failed
Some controllers cannot preset future output value while the pin is in
input mode. This adds a fallback for those controllers. The new code
assumes that a controller reports an error in that case.
For example, all hardware supported by nctgpio behaves in that way.
This is a temporary measure. In the future we will use
GPIO_PIN_PRESET_LOW / GPIO_PIN_PRESET_HIGH to preset the output either
in hardware, if supported, or in software (e.g., in
gpiobus_pin_setflags).
While here, I extracted common functionality of gpioiic_set{sda,scl} and
gpioiic_get{sda,scl} to gpioiic_setpin and gpioiic_getpin respectively.
MFC after: 2 weeks
Modified:
head/sys/dev/gpio/gpioiic.c
Modified: head/sys/dev/gpio/gpioiic.c
==============================================================================
--- head/sys/dev/gpio/gpioiic.c Fri Oct 25 09:24:41 2019 (r354064)
+++ head/sys/dev/gpio/gpioiic.c Fri Oct 25 09:37:54 2019 (r354065)
@@ -168,59 +168,67 @@ gpioiic_reset_bus(device_t dev)
}
static void
-gpioiic_setsda(device_t dev, int val)
+gpioiic_setpin(struct gpioiic_softc *sc, int pin, int val)
{
- struct gpioiic_softc *sc = device_get_softc(dev);
+ int err;
if (val == 0) {
- GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, sc->sda_pin, 0);
- GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sda_pin,
+ err = GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, pin, 0);
+ GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, pin,
GPIO_PIN_OUTPUT);
+
+ /*
+ * Some controllers cannot set output value while a pin is in
+ * input mode.
+ */
+ if (err != 0)
+ GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, pin, 0);
} else {
- GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sda_pin,
+ GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, pin,
GPIO_PIN_INPUT);
}
}
static void
+gpioiic_setsda(device_t dev, int val)
+{
+ struct gpioiic_softc *sc = device_get_softc(dev);
+
+ gpioiic_setpin(sc, sc->sda_pin, val);
+}
+
+static void
gpioiic_setscl(device_t dev, int val)
{
struct gpioiic_softc *sc = device_get_softc(dev);
- if (val == 0) {
- GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev, sc->scl_pin, 0);
- GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->scl_pin,
- GPIO_PIN_OUTPUT);
- } else {
- GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->scl_pin,
- GPIO_PIN_INPUT);
- }
+ gpioiic_setpin(sc, sc->scl_pin, val);
}
static int
-gpioiic_getscl(device_t dev)
+gpioiic_getpin(struct gpioiic_softc *sc, int pin)
{
- struct gpioiic_softc *sc = device_get_softc(dev);
unsigned int val;
- GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->scl_pin,
- GPIO_PIN_INPUT);
- GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev, sc->scl_pin, &val);
-
+ GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, pin, GPIO_PIN_INPUT);
+ GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev, pin, &val);
return ((int)val);
}
static int
-gpioiic_getsda(device_t dev)
+gpioiic_getscl(device_t dev)
{
struct gpioiic_softc *sc = device_get_softc(dev);
- unsigned int val;
- GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sda_pin,
- GPIO_PIN_INPUT);
- GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev, sc->sda_pin, &val);
+ return (gpioiic_getpin(sc, sc->scl_pin));
+}
- return ((int)val);
+static int
+gpioiic_getsda(device_t dev)
+{
+ struct gpioiic_softc *sc = device_get_softc(dev);
+
+ return (gpioiic_getpin(sc, sc->sda_pin));
}
static int
More information about the svn-src-all
mailing list