Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Jan 2012 21:52:55 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r229885 - stable/9/sys/arm/xscale/ixp425
Message-ID:  <201201092152.q09LqtXH060947@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201092152.q09LqtXH060947>