master
  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_ */