summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Balmer <mbalmer@cvs.openbsd.org>2008-11-24 14:11:59 +0000
committerMarc Balmer <mbalmer@cvs.openbsd.org>2008-11-24 14:11:59 +0000
commit11f9b2865a5705043bc12b64cdb14e23ccdc9f9b (patch)
treee82373c18490ba8afc96a6e654a800a802e3cd79
parent9302f1dc9cf9c0cbff967941b7a3cf8a198d6940 (diff)
Add and document -A and -D options to attach or detach devices at
runtime to a gpio bus. ok uwe, drahn
-rw-r--r--usr.sbin/gpioctl/gpioctl.837
-rw-r--r--usr.sbin/gpioctl/gpioctl.c72
2 files changed, 103 insertions, 6 deletions
diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8
index 193e1e7bc6c..143478fb234 100644
--- a/usr.sbin/gpioctl/gpioctl.8
+++ b/usr.sbin/gpioctl/gpioctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: gpioctl.8,v 1.12 2007/11/17 16:55:05 mbalmer Exp $
+.\" $OpenBSD: gpioctl.8,v 1.13 2008/11/24 14:11:58 mbalmer Exp $
.\"
.\" Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: November 17 2007 $
+.Dd $Mdocdate: November 24 2008 $
.Dt GPIOCTL 8
.Os
.Sh NAME
@@ -32,6 +32,12 @@
.Fl c
.Ar pin
.Op Ar flags
+.Nm gpioctl
+.Op Fl A Ar device
+.Fl o Ar offset
+.Fl m Ar mask
+.Nm gpioctl
+.Op Fl D Ar device
.Sh DESCRIPTION
The
.Nm
@@ -141,6 +147,22 @@ file can be specified with the
option in order to access a particular
.Tn GPIO
device.
+.It Fl A Ar device
+attach
+.Ar device
+at this gpiobus.
+You must also specify
+.Fl o Ar offset
+(a pin number) and
+.Fl m Ar mask
+(a binary mask).
+.It Fl D Ar device
+detach
+.Ar device
+from this gpiobus.
+Only devices that have been attached using the
+.Fl a
+option can be detached.
.It Fl q
Operate quietly i.e. nothing is printed to stdout.
.El
@@ -159,6 +181,14 @@ Configure pin 20 to have push-pull output:
Write logical 1 to pin 20:
.Pp
.Dl # gpioctl 20 1
+.Pp
+Attach a onewire(4) bus on a gpioow(4) device on pin 4:
+.Pp
+.Dl # gpioctl -A gpioow -o 4 -m 0x01
+.Pp
+Detach the gpioow0 device:
+.Pp
+.Dl # gpioctl -D gpioow0
.Sh SEE ALSO
.Xr gpio 4
.Sh HISTORY
@@ -171,3 +201,6 @@ The
.Nm
program was written by
.An Alexander Yurchenko Aq grange@openbsd.org .
+Device attachment was added by
+.An Marc Balmer Aq mbalmer@openbsd.org .
+
diff --git a/usr.sbin/gpioctl/gpioctl.c b/usr.sbin/gpioctl/gpioctl.c
index 3b92c6f3f51..bc638155a50 100644
--- a/usr.sbin/gpioctl/gpioctl.c
+++ b/usr.sbin/gpioctl/gpioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gpioctl.c,v 1.7 2007/11/17 16:55:05 mbalmer Exp $ */
+/* $OpenBSD: gpioctl.c,v 1.8 2008/11/24 14:11:58 mbalmer Exp $ */
/*
* Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
*
@@ -25,6 +25,7 @@
#include <sys/limits.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -41,6 +42,8 @@ void getinfo(void);
void pinread(int);
void pinwrite(int, int);
void pinctl(int, char *[], int);
+void devattach(char *, int, u_int32_t);
+void devdetach(char *);
__dead void usage(void);
@@ -66,17 +69,46 @@ main(int argc, char *argv[])
{
int ch;
const char *errstr;
+ char *ga_dvname = NULL, *ep;
int do_ctl = 0;
- int pin = 0, value = 0;
+ int pin = 0, value = 0, attach = 0, detach = 0;
+ u_int32_t ga_mask = 0, ga_offset = -1;
+ long lval;
- while ((ch = getopt(argc, argv, "cd:q")) != -1)
+ while ((ch = getopt(argc, argv, "A:cd:D:m:o:q")) != -1)
switch (ch) {
+ case 'A':
+ if (detach)
+ errx(1, "-A and -D are mutual exclusive");
+ ga_dvname = optarg;
+ attach = 1;
+ break;
case 'c':
do_ctl = 1;
break;
case 'd':
device = optarg;
break;
+ case 'D':
+ if (attach)
+ errx(1, "-D and -A are mutual exclusive");
+ ga_dvname = optarg;
+ detach = 1;
+ break;
+ case 'm':
+ lval = strtol(optarg, &ep, 0);
+ if (*optarg == '\0' || *ep != '\0')
+ errx(1, "invalid mask (not a number)");
+ if ((errno == ERANGE && (lval == LONG_MAX
+ || lval == LONG_MIN)) || lval > UINT_MAX)
+ errx(1, "mask out of range");
+ ga_mask = lval;
+ break;
+ case 'o':
+ ga_offset = strtonum(optarg, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(1, "offset is %s: %s", errstr, optarg);
+ break;
case 'q':
quiet = 1;
break;
@@ -96,7 +128,13 @@ main(int argc, char *argv[])
if ((devfd = open(device, O_RDWR)) == -1)
err(1, "%s", device);
- if (argc == 0 && !do_ctl) {
+ if (attach) {
+ if (ga_offset == -1 || ga_mask == 0)
+ errx(1, "gpio attach needs an offset and a mask");
+ devattach(ga_dvname, ga_offset, ga_mask);
+ } else if (detach) {
+ devdetach(ga_dvname);
+ } else if (argc == 0 && !do_ctl) {
getinfo();
} else if (argc == 1) {
if (do_ctl)
@@ -220,6 +258,29 @@ pinctl(int pin, char *flags[], int nflags)
}
void
+devattach(char *dvname, int offset, u_int32_t mask)
+{
+ struct gpio_attach attach;
+
+ bzero(&attach, sizeof(attach));
+ strlcpy(attach.ga_dvname, dvname, sizeof(attach.ga_dvname));
+ attach.ga_offset = offset;
+ attach.ga_mask = mask;
+ if (ioctl(devfd, GPIOATTACH, &attach) == -1)
+ err(1, "GPIOATTACH");
+}
+
+void
+devdetach(char *dvname)
+{
+ struct gpio_attach attach;
+
+ bzero(&attach, sizeof(attach));
+ strlcpy(attach.ga_dvname, dvname, sizeof(attach.ga_dvname));
+ if (ioctl(devfd, GPIODETACH, &attach) == -1)
+ err(1, "GPIODETACH");
+}
+void
usage(void)
{
extern char *__progname;
@@ -228,6 +289,9 @@ usage(void)
__progname);
fprintf(stderr, " %s [-q] [-d device] -c pin [flags]\n",
__progname);
+ fprintf(stderr, " %s [-A device] -o offset -m mask\n",
+ __progname);
+ fprintf(stderr, " %s [-D device]\n", __progname);
exit(1);
}