Module Name:    src
Committed By:   mbalmer
Date:           Sun Oct  2 09:33:19 UTC 2011

Modified Files:
        src/share/man/man4: gpio.4 gpioiic.4
        src/sys/dev/gpio: gpio.c gpioiic.c gpiovar.h
        src/sys/sys: gpio.h
        src/usr.sbin/gpioctl: gpioctl.8 gpioctl.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/share/man/man4/gpio.4
cvs rdiff -u -r1.2 -r1.3 src/share/man/man4/gpioiic.4
cvs rdiff -u -r1.41 -r1.42 src/sys/dev/gpio/gpio.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/gpio/gpioiic.c
cvs rdiff -u -r1.13 -r1.14 src/sys/dev/gpio/gpiovar.h
cvs rdiff -u -r1.9 -r1.10 src/sys/sys/gpio.h
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/gpioctl/gpioctl.8
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/gpioctl/gpioctl.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man4/gpio.4
diff -u src/share/man/man4/gpio.4:1.19 src/share/man/man4/gpio.4:1.20
--- src/share/man/man4/gpio.4:1.19	Sun Aug 28 07:48:50 2011
+++ src/share/man/man4/gpio.4	Sun Oct  2 09:33:18 2011
@@ -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 <gra...@openbsd.org>
@@ -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 @@ structure on this gpio device.
 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.

Index: src/share/man/man4/gpioiic.4
diff -u src/share/man/man4/gpioiic.4:1.2 src/share/man/man4/gpioiic.4:1.3
--- src/share/man/man4/gpioiic.4:1.2	Sun Aug  9 08:44:30 2009
+++ src/share/man/man4/gpioiic.4	Sun Oct  2 09:33:18 2011
@@ -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 <gra...@openbsd.org>
@@ -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

Index: src/sys/dev/gpio/gpio.c
diff -u src/sys/dev/gpio/gpio.c:1.41 src/sys/dev/gpio/gpio.c:1.42
--- src/sys/dev/gpio/gpio.c:1.41	Fri Sep  2 06:50:20 2011
+++ src/sys/dev/gpio/gpio.c	Sun Oct  2 09:33:19 2011
@@ -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 void	gpio_pulse(void *);
 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 @@ gpio_search(device_t parent, cfdata_t cf
 	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 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 	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 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 		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 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 			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 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 		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 @@ gpio_ioctl(struct gpio_softc *sc, u_long
 		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 @@ gpio_ioctl_oapi(struct gpio_softc *sc, u
 	}
 	return 0;
 }
+#endif	/* COMPAT_50 */
 
 MODULE(MODULE_CLASS_DRIVER, gpio, NULL);
 

Index: src/sys/dev/gpio/gpioiic.c
diff -u src/sys/dev/gpio/gpioiic.c:1.4 src/sys/dev/gpio/gpioiic.c:1.5
--- src/sys/dev/gpio/gpioiic.c:1.4	Wed Aug 31 12:25:05 2011
+++ src/sys/dev/gpio/gpioiic.c	Sun Oct  2 09:33:19 2011
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: gpioiic.c,v 
 #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 @@ __KERNEL_RCSID(0, "$NetBSD: gpioiic.c,v 
 #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 @@ struct gpioiic_softc {
 	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 @@ gpioiic_attach(struct device *parent, st
 	/* 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 @@ gpioiic_attach(struct device *parent, st
 		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 @@ gpioiic_attach(struct device *parent, st
 		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 */
-	caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SCL);
+	caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, sc->sc_pin_scl);
 	if (!(caps & GPIO_PIN_OUTPUT)) {
 		aprint_error(": SCL pin is unable to drive output\n");
 		goto fail;
 	}
-	aprint_normal(", SCL[%d]", sc->sc_map.pm_map[GPIOIIC_PIN_SCL]);
+	aprint_normal(", SCL[%d]", sc->sc_map.pm_map[sc->sc_pin_scl]);
 	sc->sc_scl = GPIO_PIN_OUTPUT;
 	if (caps & GPIO_PIN_OPENDRAIN) {
 		aprint_normal(" open-drain");
@@ -164,7 +180,7 @@ gpioiic_attach(struct device *parent, st
 		aprint_normal(" push-pull");
 		sc->sc_scl |= GPIO_PIN_PUSHPULL;
 	}
-	gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SCL, sc->sc_scl);
+	gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, sc->sc_pin_scl, sc->sc_scl);
 
 	aprint_normal("\n");
 
@@ -268,10 +284,10 @@ gpioiic_bb_set_bits(void *cookie, uint32
 {
 	struct gpioiic_softc *sc = cookie;
 
-	gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA,
+	gpio_pin_write(sc->sc_gpio, &sc->sc_map, sc->sc_pin_sda,
 	    bits & GPIOIIC_SDA ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
 	gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SCL,
-	    bits & GPIOIIC_SCL ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
+	    bits & GPIOIIC_SCL ? GPIO_PIN_HIGH : sc->sc_pin_scl);
 }
 
 void
@@ -286,7 +302,7 @@ gpioiic_bb_set_dir(void *cookie, uint32_
 		sda |= GPIO_PIN_TRISTATE;
 	if (sc->sc_sda != sda) {
 		sc->sc_sda = sda;
-		gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA,
+		gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, sc->sc_pin_sda,
 		    sc->sc_sda);
 	}
 }
@@ -298,11 +314,45 @@ gpioiic_bb_read_bits(void *cookie)
 	uint32_t bits = 0;
 
 	if (gpio_pin_read(sc->sc_gpio, &sc->sc_map,
-	    GPIOIIC_PIN_SDA) == GPIO_PIN_HIGH)
+	    sc->sc_pin_sda) == GPIO_PIN_HIGH)
 		bits |= GPIOIIC_SDA;
 	if (gpio_pin_read(sc->sc_gpio, &sc->sc_map,
-	    GPIOIIC_PIN_SCL) == GPIO_PIN_HIGH)
+	    sc->sc_pin_scl) == GPIO_PIN_HIGH)
 		bits |= GPIOIIC_SCL;
 
 	return bits;
 }
+
+MODULE(MODULE_CLASS_DRIVER, gpioiic, "gpio,iic");
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+gpioiic_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error;
+
+	error = 0;
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+#ifdef _MODULE
+		error = config_init_component(cfdriver_ioconf_gpioiic,
+		    cfattach_ioconf_gpioiic, cfdata_ioconf_gpioiic);
+		if (error)
+			aprint_error("%s: unable to init component\n",
+			    gpioiic_cd.cd_name);
+#endif
+		break;
+	case MODULE_CMD_FINI:
+#ifdef _MODULE
+		config_fini_component(cfdriver_ioconf_gpioiic,
+		    cfattach_ioconf_gpioiic, cfdata_ioconf_gpioiic);
+#endif
+		break;
+	default:
+		error = ENOTTY;
+	}
+	return error;
+}

Index: src/sys/dev/gpio/gpiovar.h
diff -u src/sys/dev/gpio/gpiovar.h:1.13 src/sys/dev/gpio/gpiovar.h:1.14
--- src/sys/dev/gpio/gpiovar.h:1.13	Wed Aug 31 12:20:35 2011
+++ src/sys/dev/gpio/gpiovar.h	Sun Oct  2 09:33:19 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: gpiovar.h,v 1.13 2011/08/31 12:20:35 mbalmer Exp $ */
+/* $NetBSD: gpiovar.h,v 1.14 2011/10/02 09:33:19 mbalmer Exp $ */
 /*	$OpenBSD: gpiovar.h,v 1.3 2006/01/14 12:33:49 grange Exp $	*/
 
 /*
@@ -73,6 +73,7 @@ struct gpio_attach_args {
 	int		 ga_offset;
 	uint32_t	 ga_mask;
 	char		*ga_dvname;
+	uint32_t	 ga_flags;
 };
 
 /* GPIO pin map */

Index: src/sys/sys/gpio.h
diff -u src/sys/sys/gpio.h:1.9 src/sys/sys/gpio.h:1.10
--- src/sys/sys/gpio.h:1.9	Sun Aug 28 07:48:50 2011
+++ src/sys/sys/gpio.h	Sun Oct  2 09:33:19 2011
@@ -1,7 +1,7 @@
-/* $NetBSD: gpio.h,v 1.9 2011/08/28 07:48:50 mbalmer Exp $ */
+/* $NetBSD: gpio.h,v 1.10 2011/10/02 09:33:19 mbalmer Exp $ */
 /*	$OpenBSD: gpio.h,v 1.7 2008/11/26 14:51:20 mbalmer Exp $	*/
 /*
- * Copyright (c) 2009 Marc Balmer <m...@msys.ch>
+ * Copyright (c) 2009, 2011 Marc Balmer <m...@msys.ch>
  * Copyright (c) 2004 Alexander Yurchenko <gra...@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -81,6 +81,26 @@ struct gpio_attach {
 	char		ga_dvname[16];	/* device name */
 	int		ga_offset;	/* pin number */
 	uint32_t	ga_mask;	/* binary mask */
+	uint32_t	ga_flags;	/* driver dependent flags */
+};
+
+/* gpio(4) API */
+#define GPIOINFO		_IOR('G', 0, struct gpio_info)
+#define GPIOSET			_IOWR('G', 5, struct gpio_set)
+#define GPIOUNSET		_IOWR('G', 6, struct gpio_set)
+#define GPIOREAD		_IOWR('G', 7, struct gpio_req)
+#define GPIOWRITE		_IOWR('G', 8, struct gpio_req)
+#define GPIOTOGGLE		_IOWR('G', 9, struct gpio_req)
+#define GPIOATTACH		_IOWR('G', 10, struct gpio_attach)
+#define GPIODETACH		_IOWR('G', 11, struct gpio_attach)
+#define GPIOPULSE		_IOWR('G', 12, struct gpio_pulse)
+
+#ifdef COMPAT_50
+/* Old structure to attach/detach devices */
+struct gpio_attach50 {
+	char		ga_dvname[16];	/* device name */
+	int		ga_offset;	/* pin number */
+	uint32_t	ga_mask;	/* binary mask */
 };
 
 /* GPIO pin control (old API) */
@@ -96,22 +116,13 @@ struct gpio_pin_op {
 	int gp_value;		/* value */
 };
 
-#define GPIOINFO		_IOR('G', 0, struct gpio_info)
-
-/* the old API, kept for backwards compatibility */
+/* the old API */
 #define GPIOPINREAD		_IOWR('G', 1, struct gpio_pin_op)
 #define GPIOPINWRITE		_IOWR('G', 2, struct gpio_pin_op)
 #define GPIOPINTOGGLE		_IOWR('G', 3, struct gpio_pin_op)
 #define GPIOPINCTL		_IOWR('G', 4, struct gpio_pin_ctl)
-
-/* the new API */
-#define GPIOSET			_IOWR('G', 5, struct gpio_set)
-#define GPIOUNSET		_IOWR('G', 6, struct gpio_set)
-#define GPIOREAD		_IOWR('G', 7, struct gpio_req)
-#define GPIOWRITE		_IOWR('G', 8, struct gpio_req)
-#define GPIOTOGGLE		_IOWR('G', 9, struct gpio_req)
-#define GPIOATTACH		_IOWR('G', 10, struct gpio_attach)
-#define GPIODETACH		_IOWR('G', 11, struct gpio_attach)
-#define GPIOPULSE		_IOWR('G', 12, struct gpio_pulse)
+#define GPIOATTACH50		_IOWR('G', 10, struct gpio_attach50)
+#define GPIODETACH50		_IOWR('G', 11, struct gpio_attach50)
+#endif	/* COMPAT_50 */
 
 #endif	/* !_SYS_GPIO_H_ */

Index: src/usr.sbin/gpioctl/gpioctl.8
diff -u src/usr.sbin/gpioctl/gpioctl.8:1.10 src/usr.sbin/gpioctl/gpioctl.8:1.11
--- src/usr.sbin/gpioctl/gpioctl.8:1.10	Sun Aug 28 17:10:37 2011
+++ src/usr.sbin/gpioctl/gpioctl.8	Sun Oct  2 09:33:19 2011
@@ -1,4 +1,4 @@
-.\" $NetBSD: gpioctl.8,v 1.10 2011/08/28 17:10:37 wiz Exp $
+.\" $NetBSD: gpioctl.8,v 1.11 2011/10/02 09:33:19 mbalmer Exp $
 .\"
 .\" Copyright (c) 2009, 2010, 2011 Marc Balmer <m...@msys.ch>
 .\" Copyright (c) 2004 Alexander Yurchenko <gra...@openbsd.org>
@@ -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 GPIOCTL 8
 .Os
 .Sh NAME
@@ -29,6 +29,7 @@
 .Ar device
 .Ar offset
 .Ar mask
+.Op Ar flags
 .Nm gpioctl
 .Op Fl q
 .Ar device

Index: src/usr.sbin/gpioctl/gpioctl.c
diff -u src/usr.sbin/gpioctl/gpioctl.c:1.13 src/usr.sbin/gpioctl/gpioctl.c:1.14
--- src/usr.sbin/gpioctl/gpioctl.c:1.13	Thu Sep 15 11:46:32 2011
+++ src/usr.sbin/gpioctl/gpioctl.c	Sun Oct  2 09:33:19 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: gpioctl.c,v 1.13 2011/09/15 11:46:32 mbalmer Exp $ */
+/* $NetBSD: gpioctl.c,v 1.14 2011/10/02 09:33:19 mbalmer Exp $ */
 
 /*
  * Copyright (c) 2008, 2010, 2011 Marc Balmer <mbal...@netbsd.org>
@@ -46,7 +46,7 @@ static void gpiowrite(int, char *, int);
 static void gpiopulse(int, char *, double, double);
 static void gpioset(int pin, char *name, int flags, char *alias);
 static void gpiounset(int pin, char *name);
-static void devattach(char *, int, uint32_t);
+static void devattach(char *, int, uint32_t, uint32_t);
 static void devdetach(char *);
 __dead static void usage(void);
 
@@ -81,8 +81,10 @@ main(int argc, char *argv[])
 	char *ep;
 	int ga_offset = -1;
 	uint32_t ga_mask = 0;
+	uint32_t ga_flags = 0;
 	long lval;
 	char *nam = NULL;
+	char *flags;
 	char devn[32];
 
 	while ((ch = getopt(argc, argv, "q")) != -1)
@@ -119,12 +121,13 @@ main(int argc, char *argv[])
 	if (!strcmp(argv[1], "attach")) {
 		char *driver, *offset, *mask;
 
-		if (argc != 5)
+		if (argc != 5 && argc != 6)
 			usage();
 
 		driver = argv[2];
 		offset = argv[3];
 		mask = argv[4];
+		flags = argc == 6 ? argv[5] : NULL;
 
 		ga_offset = strtonum(offset, 0, INT_MAX, &errstr);
 		if (errstr)
@@ -136,7 +139,18 @@ main(int argc, char *argv[])
 		    || lval == LONG_MIN)) || (unsigned long)lval > UINT_MAX)
 			errx(EXIT_FAILURE, "mask out of range");
 		ga_mask = lval;
-		devattach(driver, ga_offset, ga_mask);
+		if (flags != NULL) {
+			lval = strtol(flags, &ep, 0);
+			if (*flags == '\0' || *ep != '\0')
+				errx(EXIT_FAILURE,
+				    "invalid flags (not a number)");
+			if ((errno == ERANGE && (lval == LONG_MAX
+			    || lval == LONG_MIN))
+			    || (unsigned long)lval > UINT_MAX)
+				errx(EXIT_FAILURE, "flags out of range");
+			ga_flags = lval;
+		}
+		devattach(driver, ga_offset, ga_mask, ga_flags);
 		return EXIT_SUCCESS;
 	} else if (!strcmp(argv[1], "detach")) {
 		if (argc != 3)
@@ -385,7 +399,7 @@ gpiounset(int pin, char *name)
 }
 
 static void
-devattach(char *dvname, int offset, uint32_t mask)
+devattach(char *dvname, int offset, uint32_t mask, uint32_t flags)
 {
 	struct gpio_attach attach;
 
@@ -393,6 +407,7 @@ devattach(char *dvname, int offset, uint
 	strlcpy(attach.ga_dvname, dvname, sizeof(attach.ga_dvname));
 	attach.ga_offset = offset;
 	attach.ga_mask = mask;
+	attach.ga_flags = flags;
 	if (ioctl(devfd, GPIOATTACH, &attach) == -1)
 		err(EXIT_FAILURE, "GPIOATTACH");
 }
@@ -421,7 +436,8 @@ usage(void)
 	fprintf(stderr, "       %s [-q] device pin set [flags] [name]\n",
 	    progname);
 	fprintf(stderr, "       %s [-q] device pin unset\n", progname);
-	fprintf(stderr, "       %s [-q] device attach device offset mask\n",
+	fprintf(stderr, "       %s [-q] device attach device offset mask "
+	    "[flags]\n",
 	    progname);
 	fprintf(stderr, "       %s [-q] device detach device\n", progname);
 

Reply via email to