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.5 2004/12/30 07:01:52 cpressey 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 108 #include <sys/systimer.h> 109 110 struct pps_state { 111 pps_params_t ppsparam; 112 pps_info_t ppsinfo; 113 int kcmode; 114 int ppscap; 115 sysclock_t ppscount[3]; 116 }; 117 118 void pps_event (struct pps_state *pps, sysclock_t count, int event); 119 void pps_init (struct pps_state *pps); 120 int pps_ioctl (u_long cmd, caddr_t data, struct pps_state *pps); 121 void hardpps (struct timespec *tsp, long nsec); 122 123 #else /* !_KERNEL */ 124 125 static __inline int 126 time_pps_create(int filedes, pps_handle_t *handle) 127 { 128 int error; 129 130 *handle = -1; 131 error = ioctl(filedes, PPS_IOC_CREATE, 0); 132 if (error < 0) 133 return (-1); 134 *handle = filedes; 135 return (0); 136 } 137 138 static __inline int 139 time_pps_destroy(pps_handle_t handle) 140 { 141 return (ioctl(handle, PPS_IOC_DESTROY, 0)); 142 } 143 144 static __inline int 145 time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams) 146 { 147 return (ioctl(handle, PPS_IOC_SETPARAMS, ppsparams)); 148 } 149 150 static __inline int 151 time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams) 152 { 153 return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams)); 154 } 155 156 static __inline int 157 time_pps_getcap(pps_handle_t handle, int *mode) 158 { 159 return (ioctl(handle, PPS_IOC_GETCAP, mode)); 160 } 161 162 static __inline int 163 time_pps_fetch(pps_handle_t handle, const int tsformat, 164 pps_info_t *ppsinfobuf, const struct timespec *timeout) 165 { 166 int error; 167 struct pps_fetch_args arg; 168 169 arg.tsformat = tsformat; 170 if (timeout == NULL) { 171 arg.timeout.tv_sec = -1; 172 arg.timeout.tv_nsec = -1; 173 } else 174 arg.timeout = *timeout; 175 error = ioctl(handle, PPS_IOC_FETCH, &arg); 176 *ppsinfobuf = arg.pps_info_buf; 177 return (error); 178 } 179 180 static __inline int 181 time_pps_kcbind(pps_handle_t handle, const int kernel_consumer, 182 const int edge, const int tsformat) 183 { 184 struct pps_kcbind_args arg; 185 186 arg.kernel_consumer = kernel_consumer; 187 arg.edge = edge; 188 arg.tsformat = tsformat; 189 return (ioctl(handle, PPS_IOC_KCBIND, &arg)); 190 } 191 192 #endif /* !_KERNEL */ 193 #endif /* _SYS_TIMEPPS_H_ */ 194