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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
+ * Copyright (c) 2009, 2011 Marc Balmer <[email protected]>
* Copyright (c) 2004 Alexander Yurchenko <[email protected]>
*
* 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 <[email protected]>
.\" Copyright (c) 2004 Alexander Yurchenko <[email protected]>
@@ -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 <[email protected]>
@@ -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);