diff options
author | Marc Balmer <mbalmer@cvs.openbsd.org> | 2008-11-24 14:11:59 +0000 |
---|---|---|
committer | Marc Balmer <mbalmer@cvs.openbsd.org> | 2008-11-24 14:11:59 +0000 |
commit | 11f9b2865a5705043bc12b64cdb14e23ccdc9f9b (patch) | |
tree | e82373c18490ba8afc96a6e654a800a802e3cd79 | |
parent | 9302f1dc9cf9c0cbff967941b7a3cf8a198d6940 (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.8 | 37 | ||||
-rw-r--r-- | usr.sbin/gpioctl/gpioctl.c | 72 |
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); } |