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