Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add a ga_flags field to the gpio_attach structure to hand dr...



details:   https://anonhg.NetBSD.org/src/rev/251f6990b4c5
branches:  trunk
changeset: 770047:251f6990b4c5
user:      mbalmer <mbalmer%NetBSD.org@localhost>
date:      Sun Oct 02 09:33:18 2011 +0000

description:
Add a ga_flags field to the gpio_attach structure to hand driver
specific flags to drivers being attached at gpio pins.  gpioiic(4)
uses this to reverse the SDA/SCL signal order.  gpioctl(8) accepts
the flag values as optional argument to the attach command.
While here, make sure we retain backwards compatability and wrap compat
code in #ifdef COMPAT_50/#endif.

diffstat:

 share/man/man4/gpio.4      |  13 ++++---
 share/man/man4/gpioiic.4   |  12 ++++---
 sys/dev/gpio/gpio.c        |  42 +++++++++++++++++++++----
 sys/dev/gpio/gpioiic.c     |  76 ++++++++++++++++++++++++++++++++++++++-------
 sys/dev/gpio/gpiovar.h     |   3 +-
 sys/sys/gpio.h             |  41 +++++++++++++++---------
 usr.sbin/gpioctl/gpioctl.8 |   5 +-
 usr.sbin/gpioctl/gpioctl.c |  28 +++++++++++++---
 8 files changed, 165 insertions(+), 55 deletions(-)

diffs (truncated from 591 to 300 lines):

diff -r 7d0f20359050 -r 251f6990b4c5 share/man/man4/gpio.4
--- a/share/man/man4/gpio.4     Sun Oct 02 01:51:00 2011 +0000
+++ b/share/man/man4/gpio.4     Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: gpio.4,v 1.19 2011/08/28 07:48:50 mbalmer Exp $
+.\" $NetBSD: gpio.4,v 1.20 2011/10/02 09:33:18 mbalmer Exp $
 .\"    $OpenBSD: gpio.4,v 1.5 2004/11/23 09:39:29 reyk Exp $
 .\"
 .\" Copyright (c) 2004 Alexander Yurchenko <grange%openbsd.org@localhost>
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd August 21, 2011
+.Dd October 2, 2011
 .Dt GPIO 4
 .Os
 .Sh NAME
@@ -216,18 +216,19 @@
 struct gpio_attach {
         char ga_dvname[16];     /* device name */
         int ga_offset;          /* pin number */
-        u_int32_t ga_mask;      /* binary mask */
+        uint32_t ga_mask;       /* binary mask */
+        uint32_t ga_flags;      /* driver dependent */
 };
 .Ed
-.Pp
 .It Dv GPIODETACH (struct gpio_attach)
 Detach a device from this gpio device that was previously attached using the
 .Dv GPIOATTACH
 .Xr ioctl 2 .
 The
-.Fa ga_offset
+.Fa ga_offset ,
+.Fa ga_mask ,
 and
-.Fa ga_mask
+.Fa ga_flags
 fields of the
 .Fa gpio_attach
 structure are ignored.
diff -r 7d0f20359050 -r 251f6990b4c5 share/man/man4/gpioiic.4
--- a/share/man/man4/gpioiic.4  Sun Oct 02 01:51:00 2011 +0000
+++ b/share/man/man4/gpioiic.4  Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: gpioiic.4,v 1.2 2009/08/09 08:44:30 wiz Exp $
+.\"    $NetBSD: gpioiic.4,v 1.3 2011/10/02 09:33:18 mbalmer Exp $
 .\"    $OpenBSD: gpioiic.4,v 1.6 2008/11/24 15:30:21 jmc Exp $
 .\"
 .\" Copyright (c) 2006 Alexander Yurchenko <grange%openbsd.org@localhost>
@@ -15,22 +15,24 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd August 8, 2009
+.Dd October 2, 2011
 .Dt GPIOIIC 4
 .Os
 .Sh NAME
 .Nm gpioiic
 .Nd GPIO I2C controller
 .Sh SYNOPSIS
-.Cd "gpioiic* at gpio? offset 0 mask 0x3"
+.Cd "gpioiic* at gpio? offset 0 mask 0x3 flags 0x0"
 .Cd "gpioiic* at gpio?"
 .Cd "iic* at gpioiic?"
 .Sh DESCRIPTION
 The
 .Nm
 driver allows bit-banging an I2C bus as a master using two GPIO pins.
-The first pin is used as a serial data (SDA) signal and the second as
-a serial clock (SCL).
+By default the first pin is used as a serial data (SDA) signal and the
+second as a serial clock (SCL).
+If the flags locator is set to 0x01, the order of the SDA and SCL signals
+is reversed.
 Both GPIO pins must be able to drive an output and the SDA pin must be
 also able to read an input.
 .Pp
diff -r 7d0f20359050 -r 251f6990b4c5 sys/dev/gpio/gpio.c
--- a/sys/dev/gpio/gpio.c       Sun Oct 02 01:51:00 2011 +0000
+++ b/sys/dev/gpio/gpio.c       Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpio.c,v 1.41 2011/09/02 06:50:20 mbalmer Exp $ */
+/* $NetBSD: gpio.c,v 1.42 2011/10/02 09:33:19 mbalmer Exp $ */
 /*     $OpenBSD: gpio.c,v 1.6 2006/01/14 12:33:49 grange Exp $ */
 
 /*
@@ -19,7 +19,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.41 2011/09/02 06:50:20 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpio.c,v 1.42 2011/10/02 09:33:19 mbalmer Exp $");
 
 /*
  * General Purpose Input/Output framework.
@@ -83,9 +83,11 @@
 static int     gpio_ioctl(struct gpio_softc *, u_long, void *, int,
     struct lwp *);
 
+#ifdef COMPAT_50
 /* Old API */
 static int     gpio_ioctl_oapi(struct gpio_softc *, u_long, void *, int,
     kauth_cred_t);
+#endif
 
 CFATTACH_DECL3_NEW(gpio, sizeof(struct gpio_softc),
     gpio_match, gpio_attach, gpio_detach, NULL, gpio_rescan,
@@ -255,6 +257,7 @@
        ga.ga_gpio = aux;
        ga.ga_offset = cf->cf_loc[GPIOCF_OFFSET];
        ga.ga_mask = cf->cf_loc[GPIOCF_MASK];
+       ga.ga_flags = cf->cf_loc[GPIOCF_FLAG];
 
        if (config_match(parent, cf, &ga) > 0)
                config_attach(parent, cf, &ga, gpio_print);
@@ -516,6 +519,7 @@
        int error, pin, value, flags, npins;
 
        gc = sc->sc_gc;
+       ga.ga_flags = 0;
 
        if (cmd != GPIOINFO && !device_is_active(sc->sc_dev)) {
                DPRINTF(("%s: device is not active\n",
@@ -667,12 +671,24 @@
                sc->sc_pins[pin].pin_state = value;
                break;
        case GPIOATTACH:
+               attach = (struct gpio_attach *)data;
+               ga.ga_flags = attach->ga_flags;
+#ifdef COMPAT_50
+               /* FALLTHROUGH */
+       case GPIOATTACH50:
+               /*
+                * The double assignment to 'attach' in case of GPIOATTACH
+                * and COMPAT_50 is on purpose. It ensures backward
+                * compatability in case we are called through the old
+                * GPIOATTACH50 ioctl(2), which had not the ga_flags field
+                * in struct gpio_attach.
+                */
+               attach = (struct gpio_attach *)data;
+#endif
                if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
                    NULL, NULL, NULL, NULL))
                        return EPERM;
 
-               attach = (struct gpio_attach *)data;
-
                /* do not try to attach if the pins are already mapped */
                if (!gpio_pin_can_map(sc, attach->ga_offset, attach->ga_mask))
                        return EBUSY;
@@ -691,15 +707,17 @@
                        return EBUSY;
 
                ga.ga_gpio = sc;
+               /* Don't access attach->ga_flags here. */
                ga.ga_dvname = attach->ga_dvname;
                ga.ga_offset = attach->ga_offset;
                ga.ga_mask = attach->ga_mask;
-               DPRINTF(("%s: attach %s with offset %d and mask "
-                   "0x%02x\n", device_xname(sc->sc_dev), ga.ga_dvname,
-                   ga.ga_offset, ga.ga_mask));
+               DPRINTF(("%s: attach %s with offset %d, mask "
+                   "0x%02x, and flags 0x%02x\n", device_xname(sc->sc_dev),
+                   ga.ga_dvname, ga.ga_offset, ga.ga_mask, ga.ga_flags));
 
                locs[GPIOCF_OFFSET] = ga.ga_offset;
                locs[GPIOCF_MASK] = ga.ga_mask;
+               locs[GPIOCF_FLAG] = ga.ga_flags;
 
                cf = config_search_loc(NULL, sc->sc_dev, "gpio", locs, &ga);
                if (cf != NULL) {
@@ -719,6 +737,10 @@
                cv_signal(&sc->sc_attach);
                mutex_exit(&sc->sc_mtx);
                return error;
+#ifdef COMPAT_50
+       case GPIODETACH50:
+               /* FALLTHOUGH */
+#endif
        case GPIODETACH:
                if (kauth_authorize_device(cred, KAUTH_DEVICE_GPIO_PINSET,
                    NULL, NULL, NULL, NULL))
@@ -841,13 +863,18 @@
                sc->sc_pins[pin].pin_flags &= ~GPIO_PIN_SET;
                break;
        default:
+#ifdef COMPAT_50
                /* Try the old API */
                DPRINTF(("%s: trying the old API\n", device_xname(sc->sc_dev)));
                return gpio_ioctl_oapi(sc, cmd, data, flag, cred);
+#else
+               return ENOTTY;
+#endif
        }
        return 0;
 }
 
+#ifdef COMPAT_50
 static int
 gpio_ioctl_oapi(struct gpio_softc *sc, u_long cmd, void *data, int flag,
     kauth_cred_t cred)
@@ -965,6 +992,7 @@
        }
        return 0;
 }
+#endif /* COMPAT_50 */
 
 MODULE(MODULE_CLASS_DRIVER, gpio, NULL);
 
diff -r 7d0f20359050 -r 251f6990b4c5 sys/dev/gpio/gpioiic.c
--- a/sys/dev/gpio/gpioiic.c    Sun Oct 02 01:51:00 2011 +0000
+++ b/sys/dev/gpio/gpioiic.c    Sun Oct 02 09:33:18 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpioiic.c,v 1.4 2011/08/31 12:25:05 mbalmer Exp $ */
+/* $NetBSD: gpioiic.c,v 1.5 2011/10/02 09:33:19 mbalmer Exp $ */
 /*     $OpenBSD: gpioiic.c,v 1.8 2008/11/24 12:12:12 mbalmer Exp $     */
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpioiic.c,v 1.4 2011/08/31 12:25:05 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpioiic.c,v 1.5 2011/10/02 09:33:19 mbalmer Exp $");
 
 /*
  * I2C bus bit-banging through GPIO pins.
@@ -29,6 +29,7 @@
 #include <sys/device.h>
 #include <sys/gpio.h>
 #include <sys/rwlock.h>
+#include <sys/module.h>
 
 #include <dev/gpio/gpiovar.h>
 
@@ -42,6 +43,8 @@
 #define GPIOIIC_SDA            0x01
 #define GPIOIIC_SCL            0x02
 
+#define GPIOIIC_PIN_REVERSE    0x01
+
 struct gpioiic_softc {
        void *                  sc_gpio;
        struct gpio_pinmap      sc_map;
@@ -51,6 +54,9 @@
        device_t                sc_i2c_dev;
        krwlock_t               sc_i2c_lock;
 
+       int                     sc_pin_sda;
+       int                     sc_pin_scl;
+
        int                     sc_sda;
        int                     sc_scl;
 };
@@ -114,14 +120,24 @@
        /* Map pins */
        sc->sc_gpio = ga->ga_gpio;
        sc->sc_map.pm_map = sc->_map;
+
+
        if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
            &sc->sc_map)) {
                aprint_error(": can't map pins\n");
                return;
        }
 
+       if (ga->ga_flags & GPIOIIC_PIN_REVERSE) {
+               sc->sc_pin_sda = GPIOIIC_PIN_SCL;
+               sc->sc_pin_scl = GPIOIIC_PIN_SDA;
+       } else {
+               sc->sc_pin_sda = GPIOIIC_PIN_SDA;
+               sc->sc_pin_scl = GPIOIIC_PIN_SCL;
+       }
+
        /* Configure SDA pin */
-       caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA);
+       caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, sc->sc_pin_sda);
        if (!(caps & GPIO_PIN_OUTPUT)) {
                aprint_error(": SDA pin is unable to drive output\n");
                goto fail;
@@ -130,7 +146,7 @@
                aprint_error(": SDA pin is unable to read input\n");
                goto fail;
        }
-       aprint_normal(": SDA[%d]", sc->sc_map.pm_map[GPIOIIC_PIN_SDA]);
+       aprint_normal(": SDA[%d]", sc->sc_map.pm_map[sc->sc_pin_sda]);
        sc->sc_sda = GPIO_PIN_OUTPUT;
        if (caps & GPIO_PIN_OPENDRAIN) {
                aprint_normal(" open-drain");
@@ -143,15 +159,15 @@
                aprint_normal(" pull-up");
                sc->sc_sda |= GPIO_PIN_PULLUP;
        }
-       gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA, sc->sc_sda);
+       gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, sc->sc_pin_sda, sc->sc_sda);
 
        /* Configure SCL pin */



Home | Main Index | Thread Index | Old Index