xref: /netbsd-src/sys/sys/timepps.h (revision 8bc54e5be648e06e7c6b48f7611f8bccfda032d4)
1*8bc54e5bSmsaitoh /*	$NetBSD: timepps.h,v 1.22 2016/07/07 06:55:44 msaitoh Exp $	*/
278741b62Sjonathan 
378741b62Sjonathan /*
478741b62Sjonathan  * Copyright (c) 1998 Jonathan Stone
578741b62Sjonathan  * All rights reserved.
678741b62Sjonathan  *
778741b62Sjonathan  * Redistribution and use in source and binary forms, with or without
878741b62Sjonathan  * modification, are permitted provided that the following conditions
978741b62Sjonathan  * are met:
1078741b62Sjonathan  * 1. Redistributions of source code must retain the above copyright
1178741b62Sjonathan  *    notice, this list of conditions and the following disclaimer.
1278741b62Sjonathan  * 2. Redistributions in binary form must reproduce the above copyright
1378741b62Sjonathan  *    notice, this list of conditions and the following disclaimer in the
1478741b62Sjonathan  *    documentation and/or other materials provided with the distribution.
1578741b62Sjonathan  * 3. All advertising materials mentioning features or use of this software
1678741b62Sjonathan  *    must display the following acknowledgement:
1778741b62Sjonathan  *      This product includes software developed by Jonathan Stone for
1878741b62Sjonathan  *      the NetBSD Project.
1978741b62Sjonathan  * 4. The name of the author may not be used to endorse or promote products
2078741b62Sjonathan  *    derived from this software without specific prior written permission.
2178741b62Sjonathan  *
2278741b62Sjonathan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2378741b62Sjonathan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2478741b62Sjonathan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2578741b62Sjonathan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2678741b62Sjonathan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2778741b62Sjonathan  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2878741b62Sjonathan  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2978741b62Sjonathan  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3078741b62Sjonathan  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3178741b62Sjonathan  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3278741b62Sjonathan  */
3378741b62Sjonathan 
3478741b62Sjonathan #ifndef _SYS_TIMEPPS_H_
3578741b62Sjonathan #define _SYS_TIMEPPS_H_
3678741b62Sjonathan 
370588cdfcSjonathan /*
380588cdfcSjonathan  * This header file complies with "Pulse-Per-Second API for UNIX-like
390588cdfcSjonathan  * Operating Systems, Version 1.0", draft-mogul-pps-api-05.txt
400588cdfcSjonathan  */
410588cdfcSjonathan 
4278741b62Sjonathan #include <sys/ioccom.h>
4378741b62Sjonathan 
440588cdfcSjonathan #define PPS_API_VERS_1	1	/* API version number */
450588cdfcSjonathan 
460588cdfcSjonathan /*
470588cdfcSjonathan  * PPSAPI type definitions
480588cdfcSjonathan  */
490588cdfcSjonathan typedef int32_t pps_handle_t;	/* represents a PPS source */
50144515ceSperry typedef uint32_t pps_seq_t;	/* sequence number, at least 32 bits */
5178741b62Sjonathan 
5278741b62Sjonathan typedef union pps_timeu {
5378741b62Sjonathan 	struct timespec	tspec;
5478741b62Sjonathan 	struct {        /* NTP long fixed-point format */
5578741b62Sjonathan 		unsigned int     integral;
5678741b62Sjonathan 		unsigned int     fractional;
5778741b62Sjonathan 	} ntplfp;
5878741b62Sjonathan 	unsigned long   longpair[2];
5978741b62Sjonathan } pps_timeu_t;
6078741b62Sjonathan 
6178741b62Sjonathan 
620588cdfcSjonathan /*
630588cdfcSjonathan  * timestamp information
640588cdfcSjonathan  */
6578741b62Sjonathan typedef struct {
6678741b62Sjonathan 	pps_seq_t	assert_sequence;	/* assert event seq # */
6778741b62Sjonathan 	pps_seq_t	clear_sequence;		/* clear event seq # */
6878741b62Sjonathan 	pps_timeu_t	assert_tu;
6978741b62Sjonathan 	pps_timeu_t	clear_tu;
7078741b62Sjonathan 	int		current_mode;		/* current mode bits */
7178741b62Sjonathan } pps_info_t;
7278741b62Sjonathan 
730588cdfcSjonathan #define assert_timestamp	assert_tu.tspec
740588cdfcSjonathan #define clear_timestamp		clear_tu.tspec
7578741b62Sjonathan 
760588cdfcSjonathan 
770588cdfcSjonathan /*
780588cdfcSjonathan  * Parameter structure
790588cdfcSjonathan  */
8078741b62Sjonathan typedef struct {
810588cdfcSjonathan 	int api_version;			/* API version number */
8278741b62Sjonathan 	int mode;				/* mode bits */
8378741b62Sjonathan 	pps_timeu_t	assert_off_tu;
8478741b62Sjonathan 	pps_timeu_t	clear_off_tu;
8578741b62Sjonathan } pps_params_t;
8678741b62Sjonathan #define assert_offset		assert_off_tu.tspec
8778741b62Sjonathan #define clear_offset		clear_off_tu.tspec
8878741b62Sjonathan 
8978741b62Sjonathan 
900588cdfcSjonathan /*
910588cdfcSjonathan  * Device/implementation parameters (mode, edge bits)
920588cdfcSjonathan  */
9378741b62Sjonathan #define PPS_CAPTUREASSERT	0x01
9478741b62Sjonathan #define PPS_CAPTURECLEAR	0x02
9578741b62Sjonathan #define PPS_CAPTUREBOTH		0x03
9678741b62Sjonathan #define PPS_OFFSETASSERT	0x10
9778741b62Sjonathan #define PPS_OFFSETCLEAR		0x20
980588cdfcSjonathan #define PPS_CANWAIT		0x100
990588cdfcSjonathan #define PPS_CANPOLL		0x200
10078741b62Sjonathan 
1010588cdfcSjonathan /*
1020588cdfcSjonathan  * Kernel actions
1030588cdfcSjonathan  */
10478741b62Sjonathan #define PPS_ECHOASSERT		0x40
10578741b62Sjonathan #define PPS_ECHOCLEAR		0x80
10678741b62Sjonathan 
10778741b62Sjonathan 
1080588cdfcSjonathan /*
1090588cdfcSjonathan  * timestamp formats (tsformat, mode)
1100588cdfcSjonathan  */
11178741b62Sjonathan #define PPS_TSFMT_TSPEC		0x1000
11278741b62Sjonathan #define PPS_TSFMT_NTPLFP	0x2000
11378741b62Sjonathan 
1140588cdfcSjonathan /*
1150588cdfcSjonathan  * Kernel discipline actions (kernel_consumer)
1160588cdfcSjonathan  */
1170588cdfcSjonathan #define PPS_KC_HARDPPS		0
1180588cdfcSjonathan #define PPS_KC_HARDPPS_PLL	1
1190588cdfcSjonathan #define PPS_KC_HARDPPS_FLL	2
1200588cdfcSjonathan 
1210588cdfcSjonathan /*
1220588cdfcSjonathan  * IOCTL definitions
1230588cdfcSjonathan  */
1240588cdfcSjonathan #define PPS_IOC_CREATE		_IO('1', 1)
1250588cdfcSjonathan #define PPS_IOC_DESTROY		_IO('1', 2)
1260588cdfcSjonathan #define PPS_IOC_SETPARAMS	_IOW('1', 3, pps_params_t)
1270588cdfcSjonathan #define PPS_IOC_GETPARAMS	_IOR('1', 4, pps_params_t)
1280588cdfcSjonathan #define PPS_IOC_GETCAP		_IOR('1', 5, int)
1290588cdfcSjonathan #define PPS_IOC_FETCH		_IOWR('1', 6, pps_info_t)
1302763a4b9Ssimonb #define PPS_IOC_KCBIND		_IOW('1', 7, int)
13178741b62Sjonathan 
132de4337abSkardel #ifdef _KERNEL
133de4337abSkardel 
134a2249ef7Sad #include <sys/mutex.h>
135a2249ef7Sad 
136effe57d3Skardel /* flags for pps_ref_event() - bitmask but only 1 bit allowed */
137effe57d3Skardel #define PPS_REFEVNT_CAPTURE	0x01 /* use captume time stamp */
138effe57d3Skardel #define PPS_REFEVNT_CURRENT	0x02 /* use current time stamp */
139effe57d3Skardel #define PPS_REFEVNT_CAPCUR	0x04 /* use average of above */
140effe57d3Skardel #define PPS_REFEVNT_RMASK       0x0F /* mask reference bits */
141effe57d3Skardel 
142effe57d3Skardel #define PPS_REFEVNT_PPS		0x10 /* guess PPS second from */
143effe57d3Skardel                                      /* capture timestamp */
144effe57d3Skardel 
145a2249ef7Sad extern kmutex_t timecounter_lock;
146a2249ef7Sad 
147de4337abSkardel struct pps_state {
148de4337abSkardel 	/* Capture information. */
149de4337abSkardel 	struct timehands *capth;
150de4337abSkardel 	unsigned	capgen;
151a8881005Skardel 	u_int64_t	capcount;
152effe57d3Skardel 	struct bintime  ref_time;
153de4337abSkardel 
154de4337abSkardel 	/* State information. */
155de4337abSkardel 	pps_params_t	ppsparam;
156de4337abSkardel 	pps_info_t	ppsinfo;
157de4337abSkardel 	int		kcmode;
158de4337abSkardel 	int		ppscap;
159de4337abSkardel 	struct timecounter *ppstc;
160a8881005Skardel 	u_int64_t	ppscount[3];
161de4337abSkardel };
162de4337abSkardel 
163de4337abSkardel void pps_capture(struct pps_state *);
164de4337abSkardel void pps_event(struct pps_state *, int);
165effe57d3Skardel void pps_ref_event(struct pps_state *, int, struct bintime *, int);
166de4337abSkardel void pps_init(struct pps_state *);
16753524e44Schristos int pps_ioctl(unsigned long, void *, struct pps_state *);
168de4337abSkardel 
169de4337abSkardel #else /* !_KERNEL */
1700588cdfcSjonathan 
1710588cdfcSjonathan #include <sys/cdefs.h>
1720588cdfcSjonathan #include <sys/ioctl.h>
173de4337abSkardel #include <errno.h>
1740588cdfcSjonathan 
175fbae48b9Sperry static __inline int time_pps_create(int, pps_handle_t *);
176fbae48b9Sperry static __inline int time_pps_destroy(pps_handle_t);
177fbae48b9Sperry static __inline int time_pps_setparams(pps_handle_t, const pps_params_t *);
178fbae48b9Sperry static __inline int time_pps_getparams(pps_handle_t, pps_params_t *);
179fbae48b9Sperry static __inline int time_pps_getcap(pps_handle_t, int *);
180fbae48b9Sperry static __inline int time_pps_fetch(pps_handle_t, const int, pps_info_t *,
1810e1b702cSperry 	const struct timespec *);
1820b915538Smycroft #if 0
183fbae48b9Sperry static __inline int time_pps_wait(pps_handle_t, const struct timespec *,
1840e1b702cSperry 	pps_info_t *);
1850b915538Smycroft #endif
1860588cdfcSjonathan 
187fbae48b9Sperry static __inline int time_pps_kcbind(pps_handle_t, const int, const int,
1880e1b702cSperry 	const int);
18983eb9e9fSjonathan 
190fbae48b9Sperry static __inline int
time_pps_create(int filedes,pps_handle_t * handle)191de854baeSmatt time_pps_create(int filedes, pps_handle_t *handle)
1920588cdfcSjonathan {
193fcdfaefcSsimonb 
1940588cdfcSjonathan 	*handle = filedes;
1950588cdfcSjonathan 	return (0);
1960588cdfcSjonathan }
1970588cdfcSjonathan 
198fbae48b9Sperry static __inline int
time_pps_destroy(pps_handle_t handle)199de854baeSmatt time_pps_destroy(pps_handle_t handle)
2000588cdfcSjonathan {
201fcdfaefcSsimonb 
2020588cdfcSjonathan 	return (0);
2030588cdfcSjonathan }
2040588cdfcSjonathan 
205fbae48b9Sperry static __inline int
time_pps_setparams(pps_handle_t handle,const pps_params_t * ppsparams)206de854baeSmatt time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams)
2070588cdfcSjonathan {
208fcdfaefcSsimonb 
209ba9d68d0Schristos 	return (ioctl(handle, PPS_IOC_SETPARAMS, __UNCONST(ppsparams)));
2100588cdfcSjonathan }
2110588cdfcSjonathan 
212fbae48b9Sperry static __inline int
time_pps_getparams(pps_handle_t handle,pps_params_t * ppsparams)213de854baeSmatt time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams)
2140588cdfcSjonathan {
215fcdfaefcSsimonb 
2160588cdfcSjonathan 	return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams));
2170588cdfcSjonathan }
2180588cdfcSjonathan 
219fbae48b9Sperry static __inline int
time_pps_getcap(pps_handle_t handle,int * mode)220de854baeSmatt time_pps_getcap(pps_handle_t handle, int *mode)
2210588cdfcSjonathan {
222fcdfaefcSsimonb 
2230588cdfcSjonathan 	return (ioctl(handle, PPS_IOC_GETCAP, mode));
2240588cdfcSjonathan }
2250588cdfcSjonathan 
226fbae48b9Sperry static __inline int
time_pps_fetch(pps_handle_t handle,const int tsformat,pps_info_t * ppsinfobuf,const struct timespec * timeout)227de854baeSmatt time_pps_fetch(pps_handle_t handle, const int tsformat, pps_info_t *ppsinfobuf,
228de854baeSmatt 	const struct timespec *timeout)
2290588cdfcSjonathan {
230fcdfaefcSsimonb 
2310588cdfcSjonathan 	return (ioctl(handle, PPS_IOC_FETCH, ppsinfobuf));
2320588cdfcSjonathan }
2330588cdfcSjonathan 
234fbae48b9Sperry static __inline int
time_pps_kcbind(pps_handle_t handle,const int kernel_consumer,const int edge,const int tsformat)235de854baeSmatt time_pps_kcbind(pps_handle_t handle, const int kernel_consumer, const int edge,
236de854baeSmatt 	const int tsformat)
2370588cdfcSjonathan {
238fcdfaefcSsimonb 
239de4337abSkardel 	if (tsformat != PPS_TSFMT_TSPEC) {
240de4337abSkardel 		errno = EINVAL;
241de4337abSkardel 		return -1;
242de4337abSkardel 	}
243de4337abSkardel 
244ba9d68d0Schristos 	return (ioctl(handle, PPS_IOC_KCBIND, __UNCONST(&edge)));
2450588cdfcSjonathan }
24678741b62Sjonathan #endif /* !_KERNEL*/
24778741b62Sjonathan #endif /* SYS_TIMEPPS_H_ */
248