1/* $NetBSD: timepps.h,v 1.22 2016/07/07 06:55:44 msaitoh Exp $ */
2
3/*
4 * Copyright (c) 1998 Jonathan Stone
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Jonathan Stone for
18 * the NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _SYS_TIMEPPS_H_
35#define _SYS_TIMEPPS_H_
36
37/*
38 * This header file complies with "Pulse-Per-Second API for UNIX-like
39 * Operating Systems, Version 1.0", draft-mogul-pps-api-05.txt
40 */
41
42#include <sys/ioccom.h>
43
44#define PPS_API_VERS_1 1 /* API version number */
45
46/*
47 * PPSAPI type definitions
48 */
49typedef int32_t pps_handle_t; /* represents a PPS source */
50typedef uint32_t pps_seq_t; /* sequence number, at least 32 bits */
51
52typedef union pps_timeu {
53 struct timespec tspec;
54 struct { /* NTP long fixed-point format */
55 unsigned int integral;
56 unsigned int fractional;
57 } ntplfp;
58 unsigned long longpair[2];
59} pps_timeu_t;
60
61
62/*
63 * timestamp information
64 */
65typedef struct {
66 pps_seq_t assert_sequence; /* assert event seq # */
67 pps_seq_t clear_sequence; /* clear event seq # */
68 pps_timeu_t assert_tu;
69 pps_timeu_t clear_tu;
70 int current_mode; /* current mode bits */
71} pps_info_t;
72
73#define assert_timestamp assert_tu.tspec
74#define clear_timestamp clear_tu.tspec
75
76
77/*
78 * Parameter structure
79 */
80typedef struct {
81 int api_version; /* API version number */
82 int mode; /* mode bits */
83 pps_timeu_t assert_off_tu;
84 pps_timeu_t clear_off_tu;
85} pps_params_t;
86#define assert_offset assert_off_tu.tspec
87#define clear_offset clear_off_tu.tspec
88
89
90/*
91 * Device/implementation parameters (mode, edge bits)
92 */
93#define PPS_CAPTUREASSERT 0x01
94#define PPS_CAPTURECLEAR 0x02
95#define PPS_CAPTUREBOTH 0x03
96#define PPS_OFFSETASSERT 0x10
97#define PPS_OFFSETCLEAR 0x20
98#define PPS_CANWAIT 0x100
99#define PPS_CANPOLL 0x200
100
101/*
102 * Kernel actions
103 */
104#define PPS_ECHOASSERT 0x40
105#define PPS_ECHOCLEAR 0x80
106
107
108/*
109 * timestamp formats (tsformat, mode)
110 */
111#define PPS_TSFMT_TSPEC 0x1000
112#define PPS_TSFMT_NTPLFP 0x2000
113
114/*
115 * Kernel discipline actions (kernel_consumer)
116 */
117#define PPS_KC_HARDPPS 0
118#define PPS_KC_HARDPPS_PLL 1
119#define PPS_KC_HARDPPS_FLL 2
120
121/*
122 * IOCTL definitions
123 */
124#define PPS_IOC_CREATE _IO('1', 1)
125#define PPS_IOC_DESTROY _IO('1', 2)
126#define PPS_IOC_SETPARAMS _IOW('1', 3, pps_params_t)
127#define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t)
128#define PPS_IOC_GETCAP _IOR('1', 5, int)
129#define PPS_IOC_FETCH _IOWR('1', 6, pps_info_t)
130#define PPS_IOC_KCBIND _IOW('1', 7, int)
131
132#ifdef _KERNEL
133
134#include <sys/mutex.h>
135
136/* flags for pps_ref_event() - bitmask but only 1 bit allowed */
137#define PPS_REFEVNT_CAPTURE 0x01 /* use captume time stamp */
138#define PPS_REFEVNT_CURRENT 0x02 /* use current time stamp */
139#define PPS_REFEVNT_CAPCUR 0x04 /* use average of above */
140#define PPS_REFEVNT_RMASK 0x0F /* mask reference bits */
141
142#define PPS_REFEVNT_PPS 0x10 /* guess PPS second from */
143 /* capture timestamp */
144
145extern kmutex_t timecounter_lock;
146
147struct pps_state {
148 /* Capture information. */
149 struct timehands *capth;
150 unsigned capgen;
151 u_int64_t capcount;
152 struct bintime ref_time;
153
154 /* State information. */
155 pps_params_t ppsparam;
156 pps_info_t ppsinfo;
157 int kcmode;
158 int ppscap;
159 struct timecounter *ppstc;
160 u_int64_t ppscount[3];
161};
162
163void pps_capture(struct pps_state *);
164void pps_event(struct pps_state *, int);
165void pps_ref_event(struct pps_state *, int, struct bintime *, int);
166void pps_init(struct pps_state *);
167int pps_ioctl(unsigned long, void *, struct pps_state *);
168
169#else /* !_KERNEL */
170
171#include <sys/cdefs.h>
172#include <sys/ioctl.h>
173#include <errno.h>
174
175static __inline int time_pps_create(int, pps_handle_t *);
176static __inline int time_pps_destroy(pps_handle_t);
177static __inline int time_pps_setparams(pps_handle_t, const pps_params_t *);
178static __inline int time_pps_getparams(pps_handle_t, pps_params_t *);
179static __inline int time_pps_getcap(pps_handle_t, int *);
180static __inline int time_pps_fetch(pps_handle_t, const int, pps_info_t *,
181 const struct timespec *);
182#if 0
183static __inline int time_pps_wait(pps_handle_t, const struct timespec *,
184 pps_info_t *);
185#endif
186
187static __inline int time_pps_kcbind(pps_handle_t, const int, const int,
188 const int);
189
190static __inline int
191time_pps_create(int filedes, pps_handle_t *handle)
192{
193
194 *handle = filedes;
195 return (0);
196}
197
198static __inline int
199time_pps_destroy(pps_handle_t handle)
200{
201
202 return (0);
203}
204
205static __inline int
206time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams)
207{
208
209 return (ioctl(handle, PPS_IOC_SETPARAMS, __UNCONST(ppsparams)));
210}
211
212static __inline int
213time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams)
214{
215
216 return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams));
217}
218
219static __inline int
220time_pps_getcap(pps_handle_t handle, int *mode)
221{
222
223 return (ioctl(handle, PPS_IOC_GETCAP, mode));
224}
225
226static __inline int
227time_pps_fetch(pps_handle_t handle, const int tsformat, pps_info_t *ppsinfobuf,
228 const struct timespec *timeout)
229{
230
231 return (ioctl(handle, PPS_IOC_FETCH, ppsinfobuf));
232}
233
234static __inline int
235time_pps_kcbind(pps_handle_t handle, const int kernel_consumer, const int edge,
236 const int tsformat)
237{
238
239 if (tsformat != PPS_TSFMT_TSPEC) {
240 errno = EINVAL;
241 return -1;
242 }
243
244 return (ioctl(handle, PPS_IOC_KCBIND, __UNCONST(&edge)));
245}
246#endif /* !_KERNEL*/
247#endif /* SYS_TIMEPPS_H_ */
248