diff options
author | 2008-06-11 20:07:31 +0000 | |
---|---|---|
committer | 2008-06-11 20:07:31 +0000 | |
commit | 729569a711924315e034f85a8dbeb4d46a0b14bc (patch) | |
tree | d4b124a87331b466fe45bdd374a58e5267249328 | |
parent | regen (diff) | |
download | wireguard-openbsd-729569a711924315e034f85a8dbeb4d46a0b14bc.tar.xz wireguard-openbsd-729569a711924315e034f85a8dbeb4d46a0b14bc.zip |
When reading a GPIO pin, first determine if it is programmed for input
or output and then read the value from either the GPIO[x]_READ_BACK or
GPIO[x]_OUT_VAL register. This allows to read back LED (output) states
as well as input states (buttons).
Problem noticed by Rolf Sommerhalder, fix by me.
-rw-r--r-- | sys/arch/i386/pci/glxpcib.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/arch/i386/pci/glxpcib.c b/sys/arch/i386/pci/glxpcib.c index c1da8e981d5..0c2a3eb4bd0 100644 --- a/sys/arch/i386/pci/glxpcib.c +++ b/sys/arch/i386/pci/glxpcib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glxpcib.c,v 1.6 2007/11/17 17:02:47 mbalmer Exp $ */ +/* $OpenBSD: glxpcib.c,v 1.7 2008/06/11 20:07:31 mbalmer Exp $ */ /* * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org> @@ -19,7 +19,7 @@ */ /* - * AMD CS5536 series LPC bridge also containing timer, watchdog and GPIO. + * AMD CS5536 series LPC bridge also containing timer, watchdog, and GPIO. */ #include <sys/param.h> @@ -281,7 +281,7 @@ glxpcib_wdogctl_cb(void *v, int period) wrmsr(AMD5536_MFGPT_NR, rdmsr(AMD5536_MFGPT_NR) & ~AMD5536_MFGPT0_C2_RSTEN); - return (period); + return period; } int @@ -289,13 +289,21 @@ glxpcib_gpio_pin_read(void *arg, int pin) { struct glxpcib_softc *sc = arg; u_int32_t data; - int reg; + int reg, off = 0; - reg = AMD5536_GPIO_OUT_VAL; + reg = AMD5536_GPIO_IN_EN; if (pin > 15) { pin &= 0x0f; - reg += AMD5536_GPIOH_OFFSET; + off = AMD5536_GPIOH_OFFSET; } + reg += off; + data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); + + if (data & (1 << pin)) + reg = AMD5536_GPIO_READ_BACK + off; + else + reg = AMD5536_GPIO_OUT_VAL + off; + data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg); return data & 1 << pin ? GPIO_PIN_HIGH : GPIO_PIN_LOW; |