Author: gonzo
Date: Fri Mar 11 21:05:16 2016
New Revision: 296682
URL: https://svnweb.freebsd.org/changeset/base/296682

Log:
  Make it possible for operations to refer to GPIO pins by name
  
  - Try to guess what is provided as a pin spec for -t or for get/set
      operation: number or name. Fails in case of ambiguity.
  - Add -p and -N switches to force pin specification interpretation:
      -p forces spec to be pin number, -N forces it to be name
  
  Submitted by: Emmanuel Vadot <m...@bidouilliste.com>
  Differential Revision:        https://reviews.freebsd.org/D5201

Modified:
  head/usr.sbin/gpioctl/gpioctl.8
  head/usr.sbin/gpioctl/gpioctl.c

Modified: head/usr.sbin/gpioctl/gpioctl.8
==============================================================================
--- head/usr.sbin/gpioctl/gpioctl.8     Fri Mar 11 21:00:14 2016        
(r296681)
+++ head/usr.sbin/gpioctl/gpioctl.8     Fri Mar 11 21:05:16 2016        
(r296682)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 8, 2015
+.Dd March 11, 2016
 .Dt GPIOCTL 1
 .Os
 .Sh NAME
@@ -40,21 +40,25 @@
 .Op Fl v
 .Nm
 .Op Fl f Ar ctldev
+.Op Fl pN
 .Cm -t
 .Ar pin
 .Nm
 .Op Fl f Ar ctldev
+.Op Fl pN
 .Cm -c
 .Ar pin
 .Ar flag
 .Op flag ...
 .Nm
 .Op Fl f Ar ctldev
+.Op Fl pN
 .Cm -n
 .Ar pin
 .Ar pin-name
 .Nm
 .Op Cm -f Ar ctldev
+.Op Fl pN
 .Ar pin
 .Ar [0|1]
 .Sh DESCRIPTION
@@ -62,6 +66,20 @@ The
 .Nm
 utility could be used to manage GPIO pins from userland and list available 
pins.
 .Pp
+The
+.Pa pin
+argument can either be a
+.Pa pin-number
+or a
+.Pa pin-name .
+If it is a number and a pin has this number as its name and you did not use
+.Fl N
+or
+.Fl p
+, then
+.Nm
+exits.
+.Pp
 The options are as follows:
 .Bl -tag -width ".Fl f Ar ctldev"
 .It Fl c Ar pin Ar flag Op flag ...
@@ -96,9 +114,17 @@ list available pins
 .It Fl n Ar pin Ar pin-name
 set the name used to describe the pin
 .It Fl t Ar pin
-toggle value of provided pin number
+toggle value of provided pin
 .It Fl v
 be verbose: for each listed pin print current configuration
+.It Fl p
+Force
+.Pa pin
+to be interpreted as a pin number
+.It Fl N
+Force
+.Pa pin
+to be interpreted as a pin name
 .El
 .Sh EXAMPLES
 .Bl -bullet
@@ -114,6 +140,18 @@ gpioctl -f /dev/gpioc0 12 1
 Configure pin 12 to be input pin
 .Pp
 gpioctl -f /dev/gpioc0 -c 12 IN
+.It
+Set the name of pin 12 to test
+.Pp
+gpioctl -f /dev/gpioc0 -n 12 test
+.It
+Toggle the value the pin named test
+.Pp
+gpioctl -f /dev/gpioc0 -t test
+.It
+Toggle the value of pin number 12 even if another pin has the name 12
+.Pp
+gpioctl -f /dev/gpioc0 -pt 12
 .El
 .Sh SEE ALSO
 .Xr gpio 4 ,

Modified: head/usr.sbin/gpioctl/gpioctl.c
==============================================================================
--- head/usr.sbin/gpioctl/gpioctl.c     Fri Mar 11 21:00:14 2016        
(r296681)
+++ head/usr.sbin/gpioctl/gpioctl.c     Fri Mar 11 21:05:16 2016        
(r296682)
@@ -1,6 +1,7 @@
 /*-
  * Copyright (c) 2009, Oleksandr Tymoshenko <go...@freebsd.org>
  * Copyright (c) 2014, Rui Paulo <rpa...@freebsd.org>
+ * Copyright (c) 2015, Emmanuel Vadot <m...@bidouilliste.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,6 +41,10 @@ __FBSDID("$FreeBSD$");
 
 #include <libgpio.h>
 
+#define PIN_TYPE_UNKNOWN       0
+#define PIN_TYPE_NUMBER                1
+#define PIN_TYPE_NAME          2
+
 struct flag_desc {
        const char *name;
        uint32_t flag;
@@ -66,10 +71,10 @@ usage(void)
 {
        fprintf(stderr, "Usage:\n");
        fprintf(stderr, "\tgpioctl [-f ctldev] -l [-v]\n");
-       fprintf(stderr, "\tgpioctl [-f ctldev] -t pin\n");
-       fprintf(stderr, "\tgpioctl [-f ctldev] -c pin flag ...\n");
-       fprintf(stderr, "\tgpioctl [-f ctldev] -n pin pin-name\n");
-       fprintf(stderr, "\tgpioctl [-f ctldev] pin [0|1]\n");
+       fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -t pin\n");
+       fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -c pin flag ...\n");
+       fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -n pin pin-name\n");
+       fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] pin [0|1]\n");
        exit(1);
 }
 
@@ -163,6 +168,32 @@ dump_pins(gpio_handle_t handle, int verb
        free(cfgs);
 }
 
+static int
+get_pinnum_by_name(gpio_handle_t handle, const char *name) {
+       int i, maxpin, pinn;
+       gpio_config_t *cfgs;
+       gpio_config_t *pin;
+
+       pinn = -1;
+       maxpin = gpio_pin_list(handle, &cfgs);
+       if (maxpin < 0) {
+               perror("gpio_pin_list");
+               exit(1);
+       }
+
+       for (i = 0; i <= maxpin; i++) {
+               pin = cfgs + i;
+               gpio_pin_get(handle, pin->g_pin);
+               if (!strcmp(name, pin->g_name)) {
+                       pinn = i;
+                       break;
+               }
+       }
+       free(cfgs);
+
+       return pinn;
+}
+
 static void
 fail(const char *fmt, ...)
 {
@@ -181,19 +212,16 @@ main(int argc, char **argv)
        gpio_config_t pin;
        gpio_handle_t handle;
        char *ctlfile = NULL;
-       int pinn, pinv, ch;
+       int pinn, pinv, pin_type, ch;
        int flags, flag, ok;
        int config, list, name, toggle, verbose;
 
-       config = toggle = verbose = list = name = pinn = 0;
+       config = toggle = verbose = list = name = pin_type = 0;
 
-       while ((ch = getopt(argc, argv, "c:f:ln:t:v")) != -1) {
+       while ((ch = getopt(argc, argv, "cf:lntvNp")) != -1) {
                switch (ch) {
                case 'c':
                        config = 1;
-                       pinn = str2int(optarg, &ok);
-                       if (!ok)
-                               fail("Invalid pin number: %s\n", optarg);
                        break;
                case 'f':
                        ctlfile = optarg;
@@ -203,15 +231,15 @@ main(int argc, char **argv)
                        break;
                case 'n':
                        name = 1;
-                       pinn = str2int(optarg, &ok);
-                       if (!ok)
-                               fail("Invalid pin number: %s\n", optarg);
+                       break;
+               case 'N':
+                       pin_type = PIN_TYPE_NAME;
+                       break;
+               case'p':
+                       pin_type = PIN_TYPE_NUMBER;
                        break;
                case 't':
                        toggle = 1;
-                       pinn = str2int(optarg, &ok);
-                       if (!ok)
-                               fail("Invalid pin number: %s\n", optarg);
                        break;
                case 'v':
                        verbose = 1;
@@ -232,33 +260,58 @@ main(int argc, char **argv)
                exit(1);
        }
 
+       if (list) {
+               dump_pins(handle, verbose);
+               gpio_close(handle);
+               exit(0);
+       }
+
+       if (argc == 0)
+               usage();
+
+       /* Find the pin number by the name */
+       switch (pin_type) {
+       case PIN_TYPE_UNKNOWN:
+               /* First test if it is a pin number */
+               pinn = str2int(argv[0], &ok);
+               if (ok) {
+                       /* Test if we have any pin named by this number and 
tell the user */
+                       if (get_pinnum_by_name(handle, argv[0]) != -1)
+                               fail("%s is also a pin name, use -p or -N\n", 
argv[0]);
+               } else {
+                       /* Test if it is a name */
+                       if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
+                               fail("Can't find pin named \"%s\"\n", argv[0]);
+               }
+               break;
+       case PIN_TYPE_NUMBER:
+               pinn = str2int(argv[0], &ok);
+               if (!ok)
+                       fail("Invalid pin number: %s\n", argv[0]);
+               break;
+       case PIN_TYPE_NAME:
+               if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
+                       fail("Can't find pin named \"%s\"\n", argv[0]);
+               break;
+       }
+
        /* Set the pin name. */
        if (name) {
-               if (argc == 0) {
+               if (argc != 2)
                        usage();
-                       exit(1);
-               }
-               if (gpio_pin_set_name(handle, pinn, argv[0]) < 0) {
+               if (gpio_pin_set_name(handle, pinn, argv[1]) < 0) {
                        perror("gpio_pin_set_name");
                        exit(1);
                }
                exit(0);
        }
 
-       if (list) {
-               dump_pins(handle, verbose);
-               gpio_close(handle);
-               exit(0);
-       }
-
        if (toggle) {
                /*
-                * -t pin assumes no additional arguments
-                */
-               if (argc > 0) {
+                * -t pin assumes no additional arguments
+                */
+               if (argc > 1)
                        usage();
-                       exit(1);
-               }
                if (gpio_pin_toggle(handle, pinn) < 0) {
                        perror("gpio_pin_toggle");
                        exit(1);
@@ -269,7 +322,7 @@ main(int argc, char **argv)
 
        if (config) {
                flags = 0;
-               for (i = 0; i < argc; i++) {
+               for (i = 1; i < argc; i++) {
                        flag =  str2cap(argv[i]);
                        if (flag < 0)
                                fail("Invalid flag: %s\n", argv[i]);
@@ -287,14 +340,8 @@ main(int argc, char **argv)
        /*
         * Last two cases - set value or print value
         */
-       if ((argc == 0) || (argc > 2)) {
+       if ((argc == 0) || (argc > 2))
                usage();
-               exit(1);
-       }
-
-       pinn = str2int(argv[0], &ok);
-       if (!ok)
-               fail("Invalid pin number: %s\n", argv[0]);
 
        /*
         * Read pin value
@@ -311,7 +358,7 @@ main(int argc, char **argv)
 
        /* Is it valid number (0 or 1) ? */
        pinv = str2int(argv[1], &ok);
-       if (!ok || ((pinv != 0) && (pinv != 1)))
+       if (ok == 0 || ((pinv != 0) && (pinv != 1)))
                fail("Invalid pin value: %s\n", argv[1]);
 
        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to