diff options
Diffstat (limited to 'tools/testing/selftests/ptp/testptp.c')
-rw-r--r-- | tools/testing/selftests/ptp/testptp.c | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c index c0dd10257df5..198ad5f32187 100644 --- a/tools/testing/selftests/ptp/testptp.c +++ b/tools/testing/selftests/ptp/testptp.c @@ -35,6 +35,8 @@ #define CLOCK_INVALID -1 #endif +#define NSEC_PER_SEC 1000000000LL + /* clock_adjtime is not available in GLIBC < 2.14 */ #if !__GLIBC_PREREQ(2, 14) #include <sys/syscall.h> @@ -131,7 +133,10 @@ static void usage(char *progname) " 0 - none\n" " 1 - external time stamp\n" " 2 - periodic output\n" + " -n val shift the ptp clock time by 'val' nanoseconds\n" " -p val enable output with a period of 'val' nanoseconds\n" + " -H val set output phase to 'val' nanoseconds (requires -p)\n" + " -w val set output pulse width to 'val' nanoseconds (requires -p)\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" " -S set the system time from the ptp clock time\n" @@ -161,6 +166,7 @@ int main(int argc, char *argv[]) clockid_t clkid; int adjfreq = 0x7fffffff; int adjtime = 0; + int adjns = 0; int capabilities = 0; int extts = 0; int flagtest = 0; @@ -169,7 +175,6 @@ int main(int argc, char *argv[]) int list_pins = 0; int pct_offset = 0; int n_samples = 0; - int perout = -1; int pin_index = -1, pin_func; int pps = -1; int seconds = 0; @@ -177,10 +182,13 @@ int main(int argc, char *argv[]) int64_t t1, t2, tp; int64_t interval, offset; + int64_t perout_phase = -1; + int64_t pulsewidth = -1; + int64_t perout = -1; progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; - while (EOF != (c = getopt(argc, argv, "cd:e:f:ghi:k:lL:p:P:sSt:T:z"))) { + while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:p:P:sSt:T:w:z"))) { switch (c) { case 'c': capabilities = 1; @@ -197,6 +205,9 @@ int main(int argc, char *argv[]) case 'g': gettime = 1; break; + case 'H': + perout_phase = atoll(optarg); + break; case 'i': index = atoi(optarg); break; @@ -214,8 +225,11 @@ int main(int argc, char *argv[]) return -1; } break; + case 'n': + adjns = atoi(optarg); + break; case 'p': - perout = atoi(optarg); + perout = atoll(optarg); break; case 'P': pps = atoi(optarg); @@ -233,6 +247,9 @@ int main(int argc, char *argv[]) settime = 3; seconds = atoi(optarg); break; + case 'w': + pulsewidth = atoi(optarg); + break; case 'z': flagtest = 1; break; @@ -269,14 +286,16 @@ int main(int argc, char *argv[]) " %d programmable periodic signals\n" " %d pulse per second\n" " %d programmable pins\n" - " %d cross timestamping\n", + " %d cross timestamping\n" + " %d adjust_phase\n", caps.max_adj, caps.n_alarm, caps.n_ext_ts, caps.n_per_out, caps.pps, caps.n_pins, - caps.cross_timestamping); + caps.cross_timestamping, + caps.adjust_phase); } } @@ -291,11 +310,16 @@ int main(int argc, char *argv[]) } } - if (adjtime) { + if (adjtime || adjns) { memset(&tx, 0, sizeof(tx)); - tx.modes = ADJ_SETOFFSET; + tx.modes = ADJ_SETOFFSET | ADJ_NANO; tx.time.tv_sec = adjtime; - tx.time.tv_usec = 0; + tx.time.tv_usec = adjns; + while (tx.time.tv_usec < 0) { + tx.time.tv_sec -= 1; + tx.time.tv_usec += 1000000000; + } + if (clock_adjtime(clkid, &tx) < 0) { perror("clock_adjtime"); } else { @@ -340,6 +364,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 (extts) { memset(&extts_request, 0, sizeof(extts_request)); extts_request.index = index; @@ -389,6 +425,16 @@ int main(int argc, char *argv[]) } } + if (pulsewidth >= 0 && perout < 0) { + puts("-w can only be specified together with -p"); + return -1; + } + + if (perout_phase >= 0 && perout < 0) { + puts("-H can only be specified together with -p"); + return -1; + } + if (perout >= 0) { if (clock_gettime(clkid, &ts)) { perror("clock_gettime"); @@ -396,26 +442,27 @@ int main(int argc, char *argv[]) } memset(&perout_request, 0, sizeof(perout_request)); perout_request.index = index; - perout_request.start.sec = ts.tv_sec + 2; - perout_request.start.nsec = 0; - perout_request.period.sec = 0; - perout_request.period.nsec = perout; - if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) { - perror("PTP_PEROUT_REQUEST"); + perout_request.period.sec = perout / NSEC_PER_SEC; + perout_request.period.nsec = perout % NSEC_PER_SEC; + perout_request.flags = 0; + if (pulsewidth >= 0) { + perout_request.flags |= PTP_PEROUT_DUTY_CYCLE; + perout_request.on.sec = pulsewidth / NSEC_PER_SEC; + perout_request.on.nsec = pulsewidth % NSEC_PER_SEC; + } + if (perout_phase >= 0) { + perout_request.flags |= PTP_PEROUT_PHASE; + perout_request.phase.sec = perout_phase / NSEC_PER_SEC; + perout_request.phase.nsec = perout_phase % NSEC_PER_SEC; } else { - puts("periodic output request okay"); + perout_request.start.sec = ts.tv_sec + 2; + perout_request.start.nsec = 0; } - } - 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"); + if (ioctl(fd, PTP_PEROUT_REQUEST2, &perout_request)) { + perror("PTP_PEROUT_REQUEST"); } else { - puts("set pin function okay"); + puts("periodic output request okay"); } } |