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.4 2004/01/30 05:42:18 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 #include <sys/ioccom.h> 20 #include <sys/systimer.h> 21 22 #define PPS_API_VERS_1 1 23 24 typedef int pps_handle_t; 25 26 typedef unsigned pps_seq_t; 27 28 typedef struct ntp_fp { 29 unsigned int integral; 30 unsigned int fractional; 31 } ntp_fp_t; 32 33 typedef union pps_timeu { 34 struct timespec tspec; 35 ntp_fp_t ntpfp; 36 unsigned long longpad[3]; 37 } pps_timeu_t; 38 39 typedef struct { 40 pps_seq_t assert_sequence; /* assert event seq # */ 41 pps_seq_t clear_sequence; /* clear event seq # */ 42 pps_timeu_t assert_tu; 43 pps_timeu_t clear_tu; 44 int current_mode; /* current mode bits */ 45 } pps_info_t; 46 47 #define assert_timestamp assert_tu.tspec 48 #define clear_timestamp clear_tu.tspec 49 50 #define assert_timestamp_ntpfp assert_tu.ntpfp 51 #define clear_timestamp_ntpfp clear_tu.ntpfp 52 53 typedef struct { 54 int api_version; /* API version # */ 55 int mode; /* mode bits */ 56 pps_timeu_t assert_off_tu; 57 pps_timeu_t clear_off_tu; 58 } pps_params_t; 59 60 #define assert_offset assert_off_tu.tspec 61 #define clear_offset clear_off_tu.tspec 62 63 #define assert_offset_ntpfp assert_off_tu.ntpfp 64 #define clear_offset_ntpfp clear_off_tu.ntpfp 65 66 67 #define PPS_CAPTUREASSERT 0x01 68 #define PPS_CAPTURECLEAR 0x02 69 #define PPS_CAPTUREBOTH 0x03 70 71 #define PPS_OFFSETASSERT 0x10 72 #define PPS_OFFSETCLEAR 0x20 73 74 #define PPS_ECHOASSERT 0x40 75 #define PPS_ECHOCLEAR 0x80 76 77 #define PPS_CANWAIT 0x100 78 #define PPS_CANPOLL 0x200 79 80 #define PPS_TSFMT_TSPEC 0x1000 81 #define PPS_TSFMT_NTPFP 0x2000 82 83 #define PPS_KC_HARDPPS 0 84 #define PPS_KC_HARDPPS_PLL 1 85 #define PPS_KC_HARDPPS_FLL 2 86 87 struct pps_fetch_args { 88 int tsformat; 89 pps_info_t pps_info_buf; 90 struct timespec timeout; 91 }; 92 93 struct pps_kcbind_args { 94 int kernel_consumer; 95 int edge; 96 int tsformat; 97 }; 98 99 #define PPS_IOC_CREATE _IO('1', 1) 100 #define PPS_IOC_DESTROY _IO('1', 2) 101 #define PPS_IOC_SETPARAMS _IOW('1', 3, pps_params_t) 102 #define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t) 103 #define PPS_IOC_GETCAP _IOR('1', 5, int) 104 #define PPS_IOC_FETCH _IOWR('1', 6, struct pps_fetch_args) 105 #define PPS_IOC_KCBIND _IOW('1', 7, struct pps_kcbind_args) 106 107 #ifdef _KERNEL 108 struct pps_state { 109 pps_params_t ppsparam; 110 pps_info_t ppsinfo; 111 int kcmode; 112 int ppscap; 113 sysclock_t ppscount[3]; 114 }; 115 116 void pps_event (struct pps_state *pps, sysclock_t 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