gpiobus: setting output value while in input mode

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Thu, 24 Oct 2019 17:04:53 +0300
For a lack of a more specific mailing list (or my not being aware of it), asking
here.

gpioiic, a very simple driver, has this code:
===========================================================================
static void
gpioiic_setsda(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->sda_pin, 0);
                GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sda_pin,
                    GPIO_PIN_OUTPUT);
        } else {
                GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sda_pin,
                    GPIO_PIN_INPUT);
        }
}
===========================================================================

The interesting case is val == 0.

I know that there are GPIO controllers where input and output values are
represented by different bits, so it is possible to set a future output value
while the pin is in input mode.
At the same time, there are controllers where there is a single bit per pin and
while the pin is input mode the bit is read-only.  So, it is impossible to
preset the pin.

How should controllers of the second type handle GPIOBUS_PIN_SET when the pin is
in input mode?
I see three options:
1) just silently ignore GPIOBUS_PIN_SET or do it in a more glorious way: go all
the way to the hardware without caring if that does anything;
2) return an error that would hint that the operation is not possible at this time;
3) try to emulate the first class of controllers; that is, stash the value to
apply it when the pin is switched to output mode.

I personally prefer 2, it's not hard to do (unlike 3) and there would be at
least some visibility into the problem.

-- 
Andriy Gapon
Received on Thu Oct 24 2019 - 12:04:59 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:22 UTC