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