On Tue, Nov 23, 2021 at 02:14:21AM +0200, Vladimir Oltean wrote:
> This API was introduced for 2 reasons:
>
> 1. Some hardware can emit PPS signals but not starting from arbitrary
>absolute times, but rather just emit at a certain phase offset from
>the beginning of each second. We _could_ patch ts2phc to always
>specify a start time of 0.0 to PTP_PEROUT_REQUEST, and in
>theory that should then become the kernel's responsibility to advance
>that time in the past by an integer number of seconds while keeping
>the phase untouched, but in practice, we would never know whether
>that would actually work with all in-kernel PHC drivers, since it
>wasn't enforced as a requirement before. So there was a need for a
>new flag that only specifies the phase of the periodic signal, and
>not the absolute start time.
>
> 2. Some hardware can, rather unfortunately, not distinguish between a
>rising and a falling extts edge. And, since whatever rises also has
>to fall before rising again, the strategy in ts2phc is to set a
>'large' pulse width (half the period) and ignore the extts event
>corresponding to the mid-way between one second and another. This is
>all fine, but currently, ts2phc.pulsewidth is a read-only property in
>the config file. The kernel is not instructed in any way to use this
>value, it is simply that must be configured based on prior knowledge
>of the PHC's implementation. This API changes that.
>
> The introduction of a phase adjustment for the PHC kind of PPS sources
> means we have to adjust our approximation of the precise perout
It is not an approximation. It is exact, but the correct association
of event to ToD is implicit.
> timestamp. We put that code into a common function and convert all call
> sites to call that. We also need to do the same thing for the edge
> ignoring logic.
>
> Signed-off-by: Vladimir Oltean
> ---
> v4->v5: rebase on top of variable renames
> v3->v4: patch is new.
>
> config.c| 1 +
> missing.h | 52 +
> ts2phc.8| 17 +++-
> ts2phc.c| 86 +++--
> ts2phc.h| 1 +
> ts2phc_phc_pps_source.c | 44 ++---
> ts2phc_pps_sink.c | 16 +++-
> 7 files changed, 180 insertions(+), 37 deletions(-)
>
> diff --git a/config.c b/config.c
> index f3c52baff765..760d0e12b0b6 100644
> --- a/config.c
> +++ b/config.c
> @@ -321,6 +321,7 @@ struct config_item config_tab[] = {
> GLOB_ITEM_STR("ts2phc.nmea_remote_host", ""),
> GLOB_ITEM_STR("ts2phc.nmea_remote_port", ""),
> GLOB_ITEM_STR("ts2phc.nmea_serialport", "/dev/ttyS0"),
> + PORT_ITEM_INT("ts2phc.perout_phase", -1, 0, 9),
> PORT_ITEM_INT("ts2phc.pin_index", 0, 0, INT_MAX),
> GLOB_ITEM_INT("ts2phc.pulsewidth", 5, 100, 99900),
> PORT_ITEM_ENU("tsproc_mode", TSPROC_FILTER, tsproc_enu),
> diff --git a/missing.h b/missing.h
> index 89cb51360ef7..7f06da3220f2 100644
> --- a/missing.h
> +++ b/missing.h
> @@ -97,6 +97,58 @@ struct compat_ptp_clock_caps {
>
> #endif /*LINUX_VERSION_CODE < 5.8*/
>
> +/*
> + * Bits of the ptp_perout_request.flags field:
> + */
> +
> +#ifndef PTP_PEROUT_ONE_SHOT
> +#define PTP_PEROUT_ONE_SHOT (1<<0)
> +#endif
> +
> +#ifndef PTP_PEROUT_DUTY_CYCLE
> +#define PTP_PEROUT_DUTY_CYCLE(1<<1)
> +#endif
> +
> +#ifndef PTP_PEROUT_PHASE
> +#define PTP_PEROUT_PHASE (1<<2)
> +#endif
> +
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0)
> +
> +struct compat_ptp_perout_request {
> + union {
> + /*
> + * Absolute start time.
> + * Valid only if (flags & PTP_PEROUT_PHASE) is unset.
> + */
> + struct ptp_clock_time start;
> + /*
> + * Phase offset. The signal should start toggling at an
> + * unspecified integer multiple of the period, plus this value.
> + * The start time should be "as soon as possible".
> + * Valid only if (flags & PTP_PEROUT_PHASE) is set.
> + */
> + struct ptp_clock_time phase;
> + };
> + struct ptp_clock_time period; /* Desired period, zero means disable. */
> + unsigned int index; /* Which channel to configure. */
> + unsigned int flags;
> + union {
> + /*
> + * The "on" time of the signal.
> + * Must be lower than the period.
> + * Valid only if (flags & PTP_PEROUT_DUTY_CYCLE) is set.
> + */
> + struct ptp_clock_time on;
> + /* Reserved for future use. */
> + unsigned int rsv[4];
> + };
> +};
> +
> +#define ptp_perout_request compat_ptp_perout_request
> +
> +#endif /* LINUX_VERSION_CODE < 5.9 */
> +
> #ifndef PTP_MAX_SAMPLES
> #define PTP_MAX_SAMPLES 25 /* Maximum allowed