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