1 /* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * 9 * $FreeBSD: src/sys/sys/timepps.h,v 1.12 1999/12/29 04:24:48 peter Exp $ 10 * $DragonFly: src/sys/sys/timepps.h,v 1.3 2003/08/20 07:31:21 rob Exp $ 11 * 12 * The is a FreeBSD protype version of the "draft-mogul-pps-api-05.txt" 13 * specification for Pulse Per Second timing interfaces. 14 */ 15 16 #ifndef _SYS_TIMEPPS_H_ 17 #define _SYS_TIMEPPS_H_ 18 19 #include <sys/ioccom.h> 20 21 #define PPS_API_VERS_1 1 22 23 typedef int pps_handle_t; 24 25 typedef unsigned pps_seq_t; 26 27 typedef struct ntp_fp { 28 unsigned int integral; 29 unsigned int fractional; 30 } ntp_fp_t; 31 32 typedef union pps_timeu { 33 struct timespec tspec; 34 ntp_fp_t ntpfp; 35 unsigned long longpad[3]; 36 } pps_timeu_t; 37 38 typedef struct { 39 pps_seq_t assert_sequence; /* assert event seq # */ 40 pps_seq_t clear_sequence; /* clear event seq # */ 41 pps_timeu_t assert_tu; 42 pps_timeu_t clear_tu; 43 int current_mode; /* current mode bits */ 44 } pps_info_t; 45 46 #define assert_timestamp assert_tu.tspec 47 #define clear_timestamp clear_tu.tspec 48 49 #define assert_timestamp_ntpfp assert_tu.ntpfp 50 #define clear_timestamp_ntpfp clear_tu.ntpfp 51 52 typedef struct { 53 int api_version; /* API version # */ 54 int mode; /* mode bits */ 55 pps_timeu_t assert_off_tu; 56 pps_timeu_t clear_off_tu; 57 } pps_params_t; 58 59 #define assert_offset assert_off_tu.tspec 60 #define clear_offset clear_off_tu.tspec 61 62 #define assert_offset_ntpfp assert_off_tu.ntpfp 63 #define clear_offset_ntpfp clear_off_tu.ntpfp 64 65 66 #define PPS_CAPTUREASSERT 0x01 67 #define PPS_CAPTURECLEAR 0x02 68 #define PPS_CAPTUREBOTH 0x03 69 70 #define PPS_OFFSETASSERT 0x10 71 #define PPS_OFFSETCLEAR 0x20 72 73 #define PPS_ECHOASSERT 0x40 74 #define PPS_ECHOCLEAR 0x80 75 76 #define PPS_CANWAIT 0x100 77 #define PPS_CANPOLL 0x200 78 79 #define PPS_TSFMT_TSPEC 0x1000 80 #define PPS_TSFMT_NTPFP 0x2000 81 82 #define PPS_KC_HARDPPS 0 83 #define PPS_KC_HARDPPS_PLL 1 84 #define PPS_KC_HARDPPS_FLL 2 85 86 struct pps_fetch_args { 87 int tsformat; 88 pps_info_t pps_info_buf; 89 struct timespec timeout; 90 }; 91 92 struct pps_kcbind_args { 93 int kernel_consumer; 94 int edge; 95 int tsformat; 96 }; 97 98 #define PPS_IOC_CREATE _IO('1', 1) 99 #define PPS_IOC_DESTROY _IO('1', 2) 100 #define PPS_IOC_SETPARAMS _IOW('1', 3, pps_params_t) 101 #define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t) 102 #define PPS_IOC_GETCAP _IOR('1', 5, int) 103 #define PPS_IOC_FETCH _IOWR('1', 6, struct pps_fetch_args) 104 #define PPS_IOC_KCBIND _IOW('1', 7, struct pps_kcbind_args) 105 106 #ifdef _KERNEL 107 struct pps_state { 108 pps_params_t ppsparam; 109 pps_info_t ppsinfo; 110 int kcmode; 111 int ppscap; 112 struct timecounter *ppstc; 113 unsigned ppscount[3]; 114 }; 115 116 void pps_event (struct pps_state *pps, struct timecounter *tc, unsigned count, int event); 117 void pps_init (struct pps_state *pps); 118 int pps_ioctl (u_long cmd, caddr_t data, struct pps_state *pps); 119 void hardpps (struct timespec *tsp, long nsec); 120 121 #else /* !_KERNEL */ 122 123 static __inline int 124 time_pps_create(int filedes, pps_handle_t *handle) 125 { 126 int error; 127 128 *handle = -1; 129 error = ioctl(filedes, PPS_IOC_CREATE, 0); 130 if (error < 0) 131 return (-1); 132 *handle = filedes; 133 return (0); 134 } 135 136 static __inline int 137 time_pps_destroy(pps_handle_t handle) 138 { 139 return (ioctl(handle, PPS_IOC_DESTROY, 0)); 140 } 141 142 static __inline int 143 time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams) 144 { 145 return (ioctl(handle, PPS_IOC_SETPARAMS, ppsparams)); 146 } 147 148 static __inline int 149 time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams) 150 { 151 return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams)); 152 } 153 154 static __inline int 155 time_pps_getcap(pps_handle_t handle, int *mode) 156 { 157 return (ioctl(handle, PPS_IOC_GETCAP, mode)); 158 } 159 160 static __inline int 161 time_pps_fetch(pps_handle_t handle, const int tsformat, 162 pps_info_t *ppsinfobuf, const struct timespec *timeout) 163 { 164 int error; 165 struct pps_fetch_args arg; 166 167 arg.tsformat = tsformat; 168 if (timeout == NULL) { 169 arg.timeout.tv_sec = -1; 170 arg.timeout.tv_nsec = -1; 171 } else 172 arg.timeout = *timeout; 173 error = ioctl(handle, PPS_IOC_FETCH, &arg); 174 *ppsinfobuf = arg.pps_info_buf; 175 return (error); 176 } 177 178 static __inline int 179 time_pps_kcbind(pps_handle_t handle, const int kernel_consumer, 180 const int edge, const int tsformat) 181 { 182 struct pps_kcbind_args arg; 183 184 arg.kernel_consumer = kernel_consumer; 185 arg.edge = edge; 186 arg.tsformat = tsformat; 187 return (ioctl(handle, PPS_IOC_KCBIND, &arg)); 188 } 189 190 #endif /* !_KERNEL */ 191 #endif /* _SYS_TIMEPPS_H_ */ 192