linux/include/linux/ptp_clock_kernel.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * PTP 1588 clock support
   4 *
   5 * Copyright (C) 2010 OMICRON electronics GmbH
   6 */
   7
   8#ifndef _PTP_CLOCK_KERNEL_H_
   9#define _PTP_CLOCK_KERNEL_H_
  10
  11#include <linux/device.h>
  12#include <linux/pps_kernel.h>
  13#include <linux/ptp_clock.h>
  14
  15
  16struct ptp_clock_request {
  17        enum {
  18                PTP_CLK_REQ_EXTTS,
  19                PTP_CLK_REQ_PEROUT,
  20                PTP_CLK_REQ_PPS,
  21        } type;
  22        union {
  23                struct ptp_extts_request extts;
  24                struct ptp_perout_request perout;
  25        };
  26};
  27
  28struct system_device_crosststamp;
  29
  30/**
  31 * struct ptp_system_timestamp - system time corresponding to a PHC timestamp
  32 */
  33struct ptp_system_timestamp {
  34        struct timespec64 pre_ts;
  35        struct timespec64 post_ts;
  36};
  37
  38/**
  39 * struct ptp_clock_info - decribes a PTP hardware clock
  40 *
  41 * @owner:     The clock driver should set to THIS_MODULE.
  42 * @name:      A short "friendly name" to identify the clock and to
  43 *             help distinguish PHY based devices from MAC based ones.
  44 *             The string is not meant to be a unique id.
  45 * @max_adj:   The maximum possible frequency adjustment, in parts per billon.
  46 * @n_alarm:   The number of programmable alarms.
  47 * @n_ext_ts:  The number of external time stamp channels.
  48 * @n_per_out: The number of programmable periodic signals.
  49 * @n_pins:    The number of programmable pins.
  50 * @pps:       Indicates whether the clock supports a PPS callback.
  51 * @pin_config: Array of length 'n_pins'. If the number of
  52 *              programmable pins is nonzero, then drivers must
  53 *              allocate and initialize this array.
  54 *
  55 * clock operations
  56 *
  57 * @adjfine:  Adjusts the frequency of the hardware clock.
  58 *            parameter scaled_ppm: Desired frequency offset from
  59 *            nominal frequency in parts per million, but with a
  60 *            16 bit binary fractional field.
  61 *
  62 * @adjfreq:  Adjusts the frequency of the hardware clock.
  63 *            This method is deprecated.  New drivers should implement
  64 *            the @adjfine method instead.
  65 *            parameter delta: Desired frequency offset from nominal frequency
  66 *            in parts per billion
  67 *
  68 * @adjtime:  Shifts the time of the hardware clock.
  69 *            parameter delta: Desired change in nanoseconds.
  70 *
  71 * @gettime64:  Reads the current time from the hardware clock.
  72 *              This method is deprecated.  New drivers should implement
  73 *              the @gettimex64 method instead.
  74 *              parameter ts: Holds the result.
  75 *
  76 * @gettimex64:  Reads the current time from the hardware clock and optionally
  77 *               also the system clock.
  78 *               parameter ts: Holds the PHC timestamp.
  79 *               parameter sts: If not NULL, it holds a pair of timestamps from
  80 *               the system clock. The first reading is made right before
  81 *               reading the lowest bits of the PHC timestamp and the second
  82 *               reading immediately follows that.
  83 *
  84 * @getcrosststamp:  Reads the current time from the hardware clock and
  85 *                   system clock simultaneously.
  86 *                   parameter cts: Contains timestamp (device,system) pair,
  87 *                   where system time is realtime and monotonic.
  88 *
  89 * @settime64:  Set the current time on the hardware clock.
  90 *              parameter ts: Time value to set.
  91 *
  92 * @enable:   Request driver to enable or disable an ancillary feature.
  93 *            parameter request: Desired resource to enable or disable.
  94 *            parameter on: Caller passes one to enable or zero to disable.
  95 *
  96 * @verify:   Confirm that a pin can perform a given function. The PTP
  97 *            Hardware Clock subsystem maintains the 'pin_config'
  98 *            array on behalf of the drivers, but the PHC subsystem
  99 *            assumes that every pin can perform every function. This
 100 *            hook gives drivers a way of telling the core about
 101 *            limitations on specific pins. This function must return
 102 *            zero if the function can be assigned to this pin, and
 103 *            nonzero otherwise.
 104 *            parameter pin: index of the pin in question.
 105 *            parameter func: the desired function to use.
 106 *            parameter chan: the function channel index to use.
 107 *
 108 * @do_work:  Request driver to perform auxiliary (periodic) operations
 109 *            Driver should return delay of the next auxiliary work scheduling
 110 *            time (>=0) or negative value in case further scheduling
 111 *            is not required.
 112 *
 113 * Drivers should embed their ptp_clock_info within a private
 114 * structure, obtaining a reference to it using container_of().
 115 *
 116 * The callbacks must all return zero on success, non-zero otherwise.
 117 */
 118
 119struct ptp_clock_info {
 120        struct module *owner;
 121        char name[16];
 122        s32 max_adj;
 123        int n_alarm;
 124        int n_ext_ts;
 125        int n_per_out;
 126        int n_pins;
 127        int pps;
 128        struct ptp_pin_desc *pin_config;
 129        int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm);
 130        int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
 131        int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
 132        int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
 133        int (*gettimex64)(struct ptp_clock_info *ptp, struct timespec64 *ts,
 134                          struct ptp_system_timestamp *sts);
 135        int (*getcrosststamp)(struct ptp_clock_info *ptp,
 136                              struct system_device_crosststamp *cts);
 137        int (*settime64)(struct ptp_clock_info *p, const struct timespec64 *ts);
 138        int (*enable)(struct ptp_clock_info *ptp,
 139                      struct ptp_clock_request *request, int on);
 140        int (*verify)(struct ptp_clock_info *ptp, unsigned int pin,
 141                      enum ptp_pin_function func, unsigned int chan);
 142        long (*do_aux_work)(struct ptp_clock_info *ptp);
 143};
 144
 145struct ptp_clock;
 146
 147enum ptp_clock_events {
 148        PTP_CLOCK_ALARM,
 149        PTP_CLOCK_EXTTS,
 150        PTP_CLOCK_PPS,
 151        PTP_CLOCK_PPSUSR,
 152};
 153
 154/**
 155 * struct ptp_clock_event - decribes a PTP hardware clock event
 156 *
 157 * @type:  One of the ptp_clock_events enumeration values.
 158 * @index: Identifies the source of the event.
 159 * @timestamp: When the event occurred (%PTP_CLOCK_EXTTS only).
 160 * @pps_times: When the event occurred (%PTP_CLOCK_PPSUSR only).
 161 */
 162
 163struct ptp_clock_event {
 164        int type;
 165        int index;
 166        union {
 167                u64 timestamp;
 168                struct pps_event_time pps_times;
 169        };
 170};
 171
 172#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
 173
 174/**
 175 * ptp_clock_register() - register a PTP hardware clock driver
 176 *
 177 * @info:   Structure describing the new clock.
 178 * @parent: Pointer to the parent device of the new clock.
 179 *
 180 * Returns a valid pointer on success or PTR_ERR on failure.  If PHC
 181 * support is missing at the configuration level, this function
 182 * returns NULL, and drivers are expected to gracefully handle that
 183 * case separately.
 184 */
 185
 186extern struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
 187                                            struct device *parent);
 188
 189/**
 190 * ptp_clock_unregister() - unregister a PTP hardware clock driver
 191 *
 192 * @ptp:  The clock to remove from service.
 193 */
 194
 195extern int ptp_clock_unregister(struct ptp_clock *ptp);
 196
 197/**
 198 * ptp_clock_event() - notify the PTP layer about an event
 199 *
 200 * @ptp:    The clock obtained from ptp_clock_register().
 201 * @event:  Message structure describing the event.
 202 */
 203
 204extern void ptp_clock_event(struct ptp_clock *ptp,
 205                            struct ptp_clock_event *event);
 206
 207/**
 208 * ptp_clock_index() - obtain the device index of a PTP clock
 209 *
 210 * @ptp:    The clock obtained from ptp_clock_register().
 211 */
 212
 213extern int ptp_clock_index(struct ptp_clock *ptp);
 214
 215/**
 216 * ptp_find_pin() - obtain the pin index of a given auxiliary function
 217 *
 218 * @ptp:    The clock obtained from ptp_clock_register().
 219 * @func:   One of the ptp_pin_function enumerated values.
 220 * @chan:   The particular functional channel to find.
 221 * Return:  Pin index in the range of zero to ptp_clock_caps.n_pins - 1,
 222 *          or -1 if the auxiliary function cannot be found.
 223 */
 224
 225int ptp_find_pin(struct ptp_clock *ptp,
 226                 enum ptp_pin_function func, unsigned int chan);
 227
 228/**
 229 * ptp_schedule_worker() - schedule ptp auxiliary work
 230 *
 231 * @ptp:    The clock obtained from ptp_clock_register().
 232 * @delay:  number of jiffies to wait before queuing
 233 *          See kthread_queue_delayed_work() for more info.
 234 */
 235
 236int ptp_schedule_worker(struct ptp_clock *ptp, unsigned long delay);
 237
 238#else
 239static inline struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
 240                                                   struct device *parent)
 241{ return NULL; }
 242static inline int ptp_clock_unregister(struct ptp_clock *ptp)
 243{ return 0; }
 244static inline void ptp_clock_event(struct ptp_clock *ptp,
 245                                   struct ptp_clock_event *event)
 246{ }
 247static inline int ptp_clock_index(struct ptp_clock *ptp)
 248{ return -1; }
 249static inline int ptp_find_pin(struct ptp_clock *ptp,
 250                               enum ptp_pin_function func, unsigned int chan)
 251{ return -1; }
 252static inline int ptp_schedule_worker(struct ptp_clock *ptp,
 253                                      unsigned long delay)
 254{ return -EOPNOTSUPP; }
 255
 256#endif
 257
 258static inline void ptp_read_system_prets(struct ptp_system_timestamp *sts)
 259{
 260        if (sts)
 261                ktime_get_real_ts64(&sts->pre_ts);
 262}
 263
 264static inline void ptp_read_system_postts(struct ptp_system_timestamp *sts)
 265{
 266        if (sts)
 267                ktime_get_real_ts64(&sts->post_ts);
 268}
 269
 270#endif
 271