From owner-svn-src-stable-9@FreeBSD.ORG Mon Jan 9 21:52:56 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EC3A11065673; Mon, 9 Jan 2012 21:52:55 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D68A48FC12; Mon, 9 Jan 2012 21:52:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q09Lqth0060949; Mon, 9 Jan 2012 21:52:55 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q09LqtXH060947; Mon, 9 Jan 2012 21:52:55 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <201201092152.q09LqtXH060947@svn.freebsd.org> From: Andrew Thompson Date: Mon, 9 Jan 2012 21:52:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r229885 - stable/9/sys/arm/xscale/ixp425 X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Jan 2012 21:52:56 -0000 Author: thompsa Date: Mon Jan 9 21:52:55 2012 New Revision: 229885 URL: http://svn.freebsd.org/changeset/base/229885 Log: MFC r226324 Dont just set the pin high when turning on output, use the current value. Also let this value be set when in input mode. Modified: stable/9/sys/arm/xscale/ixp425/cambria_gpio.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/amd64/include/xen/ (props changed) stable/9/sys/boot/ (props changed) stable/9/sys/boot/i386/efi/ (props changed) stable/9/sys/boot/ia64/efi/ (props changed) stable/9/sys/boot/ia64/ski/ (props changed) stable/9/sys/boot/powerpc/boot1.chrp/ (props changed) stable/9/sys/boot/powerpc/ofw/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) stable/9/sys/conf/ (props changed) stable/9/sys/contrib/dev/acpica/ (props changed) stable/9/sys/contrib/octeon-sdk/ (props changed) stable/9/sys/contrib/pf/ (props changed) stable/9/sys/contrib/x86emu/ (props changed) Modified: stable/9/sys/arm/xscale/ixp425/cambria_gpio.c ============================================================================== --- stable/9/sys/arm/xscale/ixp425/cambria_gpio.c Mon Jan 9 21:51:50 2012 (r229884) +++ stable/9/sys/arm/xscale/ixp425/cambria_gpio.c Mon Jan 9 21:52:55 2012 (r229885) @@ -84,6 +84,7 @@ struct cambria_gpio_softc { struct mtx sc_mtx; struct gpio_pin sc_pins[GPIO_PINS]; uint8_t sc_latch; + uint8_t sc_val; }; struct cambria_gpio_pin { @@ -309,6 +310,9 @@ cambria_gpio_pin_setflags(device_t dev, { struct cambria_gpio_softc *sc = device_get_softc(dev); int error; + uint8_t mask; + + mask = 1 << pin; if (pin >= GPIO_PINS) return (EINVAL); @@ -325,7 +329,16 @@ cambria_gpio_pin_setflags(device_t dev, GPIO_LOCK(sc); sc->sc_pins[pin].gp_flags = flags; - sc->sc_latch |= (1 << pin); + /* + * Writing a logical one sets the signal high and writing a logical + * zero sets the signal low. To configure a digital I/O signal as an + * input, a logical one must first be written to the data bit to + * three-state the associated output. + */ + if (flags & GPIO_PIN_INPUT || sc->sc_val & mask) + sc->sc_latch |= mask; /* input or output & high */ + else + sc->sc_latch &= ~mask; error = cambria_gpio_write(sc); GPIO_UNLOCK(sc); @@ -337,15 +350,28 @@ cambria_gpio_pin_set(device_t dev, uint3 { struct cambria_gpio_softc *sc = device_get_softc(dev); int error; + uint8_t mask; - if (pin >= GPIO_PINS || sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) - return (EINVAL); + mask = 1 << pin; + if (pin >= GPIO_PINS) + return (EINVAL); GPIO_LOCK(sc); if (value) - sc->sc_latch |= (1 << pin); + sc->sc_val |= mask; else - sc->sc_latch &= ~(1 << pin); + sc->sc_val &= ~mask; + + if (sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) { + /* just save, altering the latch will disable input */ + GPIO_UNLOCK(sc); + return (0); + } + + if (value) + sc->sc_latch |= mask; + else + sc->sc_latch &= ~mask; error = cambria_gpio_write(sc); GPIO_UNLOCK(sc); @@ -375,14 +401,17 @@ static int cambria_gpio_pin_toggle(device_t dev, uint32_t pin) { struct cambria_gpio_softc *sc = device_get_softc(dev); - int error; + int error = 0; - if (pin >= GPIO_PINS || sc->sc_pins[pin].gp_flags != GPIO_PIN_OUTPUT) + if (pin >= GPIO_PINS) return (EINVAL); GPIO_LOCK(sc); - sc->sc_latch ^= (1 << pin); - error = cambria_gpio_write(sc); + sc->sc_val ^= (1 << pin); + if (sc->sc_pins[pin].gp_flags == GPIO_PIN_OUTPUT) { + sc->sc_latch ^= (1 << pin); + error = cambria_gpio_write(sc); + } GPIO_UNLOCK(sc); return (error);