ptp: add the pin GET/SETFUNC ioctls to the testptp program.
authorRichard Cochran <richardcochran@gmail.com>
Thu, 20 Mar 2014 21:21:53 +0000 (22:21 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 21 Mar 2014 18:21:14 +0000 (14:21 -0400)
This patch adds a option to the test program that lists the
programmable pins on a PTP Hardware Clock device, assuming there
are any such pins. A second option lets the user reprogram the
auxiliary function of a single pin.

Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/ptp/testptp.c

index 4aba0436da65c309c167028cfa70d7058cbf7fd0..e9eaee622032c7a0682bbccacccb6013745e11af 100644 (file)
@@ -120,6 +120,13 @@ static void usage(char *progname)
                " -i val     index for event/trigger\n"
                " -k val     measure the time offset between system and phc clock\n"
                "            for 'val' times (Maximum 25)\n"
+               " -l         list the current pin configuration\n"
+               " -L pin,val configure pin index 'pin' with function 'val'\n"
+               "            the channel index is taken from the '-i' option\n"
+               "            'val' specifies the auxiliary function:\n"
+               "            0 - none\n"
+               "            1 - external time stamp\n"
+               "            2 - periodic output\n"
                " -p val     enable output with a period of 'val' nanoseconds\n"
                " -P val     enable or disable (val=1|0) the system clock PPS\n"
                " -s         set the ptp clock time from the system time\n"
@@ -134,6 +141,7 @@ int main(int argc, char *argv[])
        struct ptp_extts_event event;
        struct ptp_extts_request extts_request;
        struct ptp_perout_request perout_request;
+       struct ptp_pin_desc desc;
        struct timespec ts;
        struct timex tx;
 
@@ -156,11 +164,13 @@ int main(int argc, char *argv[])
        int extts = 0;
        int gettime = 0;
        int index = 0;
+       int list_pins = 0;
        int oneshot = 0;
        int pct_offset = 0;
        int n_samples = 0;
        int periodic = 0;
        int perout = -1;
+       int pin_index = -1, pin_func;
        int pps = -1;
        int settime = 0;
 
@@ -169,7 +179,7 @@ int main(int argc, char *argv[])
 
        progname = strrchr(argv[0], '/');
        progname = progname ? 1+progname : argv[0];
-       while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:p:P:sSt:v"))) {
+       while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghi:k:lL:p:P:sSt:v"))) {
                switch (c) {
                case 'a':
                        oneshot = atoi(optarg);
@@ -199,6 +209,16 @@ int main(int argc, char *argv[])
                        pct_offset = 1;
                        n_samples = atoi(optarg);
                        break;
+               case 'l':
+                       list_pins = 1;
+                       break;
+               case 'L':
+                       cnt = sscanf(optarg, "%d,%d", &pin_index, &pin_func);
+                       if (cnt != 2) {
+                               usage(progname);
+                               return -1;
+                       }
+                       break;
                case 'p':
                        perout = atoi(optarg);
                        break;
@@ -245,12 +265,14 @@ int main(int argc, char *argv[])
                               "  %d programmable alarms\n"
                               "  %d external time stamp channels\n"
                               "  %d programmable periodic signals\n"
-                              "  %d pulse per second\n",
+                              "  %d pulse per second\n"
+                              "  %d programmable pins\n",
                               caps.max_adj,
                               caps.n_alarm,
                               caps.n_ext_ts,
                               caps.n_per_out,
-                              caps.pps);
+                              caps.pps,
+                              caps.n_pins);
                }
        }
 
@@ -331,6 +353,24 @@ int main(int argc, char *argv[])
                }
        }
 
+       if (list_pins) {
+               int n_pins = 0;
+               if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
+                       perror("PTP_CLOCK_GETCAPS");
+               } else {
+                       n_pins = caps.n_pins;
+               }
+               for (i = 0; i < n_pins; i++) {
+                       desc.index = i;
+                       if (ioctl(fd, PTP_PIN_GETFUNC, &desc)) {
+                               perror("PTP_PIN_GETFUNC");
+                               break;
+                       }
+                       printf("name %s index %u func %u chan %u\n",
+                              desc.name, desc.index, desc.func, desc.chan);
+               }
+       }
+
        if (oneshot) {
                install_handler(SIGALRM, handle_alarm);
                /* Create a timer. */
@@ -392,6 +432,18 @@ int main(int argc, char *argv[])
                }
        }
 
+       if (pin_index >= 0) {
+               memset(&desc, 0, sizeof(desc));
+               desc.index = pin_index;
+               desc.func = pin_func;
+               desc.chan = index;
+               if (ioctl(fd, PTP_PIN_SETFUNC, &desc)) {
+                       perror("PTP_PIN_SETFUNC");
+               } else {
+                       puts("set pin function okay");
+               }
+       }
+
        if (pps != -1) {
                int enable = pps ? 1 : 0;
                if (ioctl(fd, PTP_ENABLE_PPS, enable)) {