summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/Makefile6
-rw-r--r--include/timepps.h86
-rw-r--r--sys/dev/ppbus/ppbconf.h3
-rw-r--r--sys/dev/ppbus/pps.c109
-rw-r--r--sys/sys/timepps.h67
5 files changed, 218 insertions, 53 deletions
diff --git a/include/Makefile b/include/Makefile
index cca7b0b..a03da72 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -1,5 +1,5 @@
# From: @(#)Makefile 8.2 (Berkeley) 1/4/94
-# $Id: Makefile,v 1.76 1998/03/28 11:48:14 dufault Exp $
+# $Id: Makefile,v 1.77 1998/05/21 19:21:43 eivind Exp $
#
# Doing a make install builds /usr/include
#
@@ -18,8 +18,8 @@ FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
paths.h pthread.h pthread_np.h pwd.h \
ranlib.h regex.h regexp.h resolv.h rune.h runetype.h setjmp.h sgtty.h \
signal.h stab.h stddef.h stdio.h stdlib.h string.h stringlist.h \
- strings.h struct.h sysexits.h tar.h time.h timers.h ttyent.h unistd.h \
- utime.h utmp.h vis.h
+ strings.h struct.h sysexits.h tar.h time.h timepps.h timers.h \
+ ttyent.h unistd.h utime.h utmp.h vis.h
.if defined(WANT_CSRG_LIBM)
FILES+= math.h
.endif
diff --git a/include/timepps.h b/include/timepps.h
new file mode 100644
index 0000000..c9277ce
--- /dev/null
+++ b/include/timepps.h
@@ -0,0 +1,86 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id$
+ *
+ * The is a FreeBSD protype version of the "draft-mogul-pps-api-02.txt"
+ * specification for Pulse Per Second timing interfaces.
+ *
+ */
+
+#ifndef _TIME_PPS_H_
+#define _TIME_PPS_H_
+
+#include <sys/timepps.h>
+
+int time_pps_create(int filedes, pps_handle_t *handle);
+int time_pps_destroy(pps_handle_t handle);
+int time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams);
+int time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams);
+int time_pps_getcap(pps_handle_t handle, int *mode);
+int time_pps_fetch(pps_handle_t handle, pps_info_t *ppsinfobuf);
+int time_pps_wait(pps_handle_t handle, const struct timespec *timeout,
+ pps_info_t *ppsinfobuf);
+
+__inline int
+time_pps_create(int filedes, pps_handle_t *handle)
+{
+ int error;
+
+ *handle = -1;
+ error = ioctl(filedes, PPS_IOC_CREATE, 0);
+ if (error < 0)
+ return (-1);
+ *handle = filedes;
+ return (0);
+}
+
+__inline int
+time_pps_destroy(pps_handle_t handle)
+{
+ return (ioctl(handle, PPS_IOC_DESTROY, 0));
+}
+
+__inline int
+time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams)
+{
+ return (ioctl(handle, PPS_IOC_SETPARAMS, ppsparams));
+}
+
+__inline int
+time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams)
+{
+ return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams));
+}
+
+__inline int
+time_pps_getcap(pps_handle_t handle, int *mode)
+{
+ return (ioctl(handle, PPS_IOC_GETCAP, mode));
+}
+
+__inline int
+time_pps_fetch(pps_handle_t handle, pps_info_t *ppsinfobuf)
+{
+ return (ioctl(handle, PPS_IOC_FETCH, ppsinfobuf));
+}
+
+__inline int
+time_pps_wait(pps_handle_t handle, const struct timespec *timeout,
+ pps_info_t *ppsinfobuf)
+{
+ int error;
+ struct pps_wait_args arg;
+
+ arg.timeout = *timeout;
+ error = ioctl(handle, PPS_IOC_WAIT, &arg);
+ *ppsinfobuf = arg.pps_info_buf;
+ return (error);
+}
+
+#endif /* !_TIME_PPS_H_ */
diff --git a/sys/dev/ppbus/ppbconf.h b/sys/dev/ppbus/ppbconf.h
index 57d98b7..5a69d85 100644
--- a/sys/dev/ppbus/ppbconf.h
+++ b/sys/dev/ppbus/ppbconf.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppbconf.h,v 1.4 1997/09/01 00:51:48 bde Exp $
+ * $Id: ppbconf.h,v 1.5 1997/09/01 18:39:37 bde Exp $
*
*/
#ifndef __PPBCONF_H
@@ -59,6 +59,7 @@
#define AUTOFEED 0x02
#define nINIT 0x04
#define SELECTIN 0x08
+#define IRQENABLE 0x10
#define PCD 0x20
/*
diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c
index 2894abf..931b829 100644
--- a/sys/dev/ppbus/pps.c
+++ b/sys/dev/ppbus/pps.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: pps.c,v 1.3 1998/02/15 14:54:09 phk Exp $
+ * $Id: pps.c,v 1.4 1998/02/16 23:51:00 eivind Exp $
*
*/
@@ -17,6 +17,7 @@
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/uio.h>
+#include <sys/timepps.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
@@ -25,18 +26,21 @@
#include <dev/ppbus/ppbconf.h>
#include "pps.h"
-#define PPS_NAME "pps" /* our official name */
+#define PPS_NAME "lppps" /* our official name */
static struct pps_data {
int pps_unit;
struct ppb_device pps_dev;
- struct ppsclockev {
- struct timespec timestamp;
- u_int serial;
- } ev;
- int sawtooth;
+ pps_params_t ppsparam;
+ pps_info_t ppsinfo;
} *softc[NPPS];
+static int ppscap =
+ PPS_CAPTUREASSERT |
+ PPS_HARDPPSONASSERT |
+ PPS_OFFSETASSERT |
+ PPS_ECHOASSERT;
+
static int npps;
/*
@@ -56,13 +60,12 @@ DATA_SET(ppbdriver_set, ppsdriver);
static d_open_t ppsopen;
static d_close_t ppsclose;
-static d_read_t ppsread;
-static d_write_t ppswrite;
+static d_ioctl_t ppsioctl;
#define CDEV_MAJOR 89
static struct cdevsw pps_cdevsw =
- { ppsopen, ppsclose, ppsread, ppswrite,
- noioctl, nullstop, nullreset, nodevtotty,
+ { ppsopen, ppsclose, noread, nowrite,
+ ppsioctl, nullstop, nullreset, nodevtotty,
seltrue, nommap, nostrat, PPS_NAME,
NULL, -1 };
@@ -122,7 +125,7 @@ ppsopen(dev_t dev, int flags, int fmt, struct proc *p)
if (ppb_request_bus(&sc->pps_dev, PPB_WAIT|PPB_INTR))
return (EINTR);
- ppb_wctr(&sc->pps_dev, 0x10);
+ ppb_wctr(&sc->pps_dev, IRQENABLE);
return(0);
}
@@ -132,6 +135,7 @@ ppsclose(dev_t dev, int flags, int fmt, struct proc *p)
{
struct pps_data *sc = softc[minor(dev)];
+ sc->ppsparam.mode = 0;
ppb_release_bus(&sc->pps_dev);
return(0);
}
@@ -139,60 +143,67 @@ ppsclose(dev_t dev, int flags, int fmt, struct proc *p)
static void
ppsintr(int unit)
{
-/*
- * XXX: You want to thing carefully about what you actually want to do
- * here.
- */
-#if 1
struct pps_data *sc = softc[unit];
struct timespec tc;
-#if 1
struct timeval tv;
-#endif
nanotime(&tc);
if (!(ppb_rstr(&sc->pps_dev) & nACK))
return;
- tc.tv_nsec -= sc->sawtooth;
- sc->sawtooth = 0;
- if (tc.tv_nsec > 1000000000) {
- tc.tv_sec++;
- tc.tv_nsec -= 1000000000;
- } else if (tc.tv_nsec < 0) {
+ if (sc->ppsparam.mode & PPS_ECHOASSERT)
+ ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED);
+ timespecadd(&tc, &sc->ppsparam.assert_offset);
+ if (tc.tv_nsec < 0) {
tc.tv_sec--;
tc.tv_nsec += 1000000000;
}
- sc->ev.timestamp = tc;
- sc->ev.serial++;
-#if 1
- tv.tv_sec = tc.tv_sec;
- tv.tv_usec = tc.tv_nsec / 1000;
- hardpps(&tv, tv.tv_usec);
-#endif
-#endif
+ sc->ppsinfo.assert_timestamp = tc;
+ sc->ppsinfo.assert_sequence++;
+ if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) {
+ tv.tv_sec = tc.tv_sec;
+ tv.tv_usec = tc.tv_nsec / 1000;
+ hardpps(&tv, tv.tv_usec);
+ }
+ if (sc->ppsparam.mode & PPS_ECHOASSERT)
+ ppb_wctr(&sc->pps_dev, IRQENABLE);
}
-static int
-ppsread(dev_t dev, struct uio *uio, int ioflag)
+static int
+ppsioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p)
{
struct pps_data *sc = softc[minor(dev)];
- int err, c;
+ pps_params_t *pp;
+ pps_info_t *pi;
- c = imin(uio->uio_resid, (int)sizeof sc->ev);
- err = uiomove((caddr_t)&sc->ev, c, uio);
- return(err);
+ switch (cmd) {
+ case PPS_IOC_CREATE:
+ return (0);
+ case PPS_IOC_DESTROY:
+ return (0);
+ case PPS_IOC_SETPARAMS:
+ pp = (pps_params_t *)data;
+ if (pp->mode & ~ppscap)
+ return (EINVAL);
+ sc->ppsparam = *pp;
+ return (0);
+ case PPS_IOC_GETPARAMS:
+ pp = (pps_params_t *)data;
+ *pp = sc->ppsparam;
+ return (0);
+ case PPS_IOC_GETCAP:
+ *(int*)data = ppscap;
+ return (0);
+ case PPS_IOC_FETCH:
+ pi = (pps_info_t *)data;
+ *pi = sc->ppsinfo;
+ return (0);
+ case PPS_IOC_WAIT:
+ return (EOPNOTSUPP);
+ default:
+ return (ENODEV);
+ }
}
-static int
-ppswrite(dev_t dev, struct uio *uio, int ioflag)
-{
- struct pps_data *sc = softc[minor(dev)];
- int err, c;
-
- c = imin(uio->uio_resid, (int)sizeof sc->sawtooth);
- err = uiomove((caddr_t)&sc->sawtooth, c, uio);
- return(err);
-}
static pps_devsw_installed = 0;
diff --git a/sys/sys/timepps.h b/sys/sys/timepps.h
new file mode 100644
index 0000000..b2bf4e3
--- /dev/null
+++ b/sys/sys/timepps.h
@@ -0,0 +1,67 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id$
+ *
+ * The is a FreeBSD protype version of the "draft-mogul-pps-api-02.txt"
+ * specification for Pulse Per Second timing interfaces.
+ *
+ */
+
+#ifndef _SYS_TIMEPPS_H_
+#define _SYS_TIMEPPS_H_
+
+#include <sys/ioccom.h>
+
+typedef int pps_handle_t;
+
+typedef unsigned pps_seq_t;
+
+typedef struct {
+ pps_seq_t assert_sequence;
+ pps_seq_t clear_sequence;
+ struct timespec assert_timestamp;
+ struct timespec clear_timestamp;
+ int current_mode;
+} pps_info_t;
+
+typedef struct {
+ int mode;
+ struct timespec assert_offset;
+ struct timespec clear_offset;
+} pps_params_t;
+
+#define PPS_CAPTUREASSERT 0x01
+#define PPS_CAPTURECLEAR 0x01
+#define PPS_CAPTUREBOTH 0x03
+
+#define PPS_HARDPPSONASSERT 0x04
+#define PPS_HARDPPSONCLEAR 0x08
+
+#define PPS_OFFSETASSERT 0x10
+#define PPS_OFFSETCLEAR 0x20
+
+#define PPS_ECHOASSERT 0x40
+#define PPS_ECHOCLEAR 0x80
+
+#define PPS_CANWAIT 0x100
+
+struct pps_wait_args {
+ struct timespec timeout;
+ pps_info_t pps_info_buf;
+};
+
+#define PPS_IOC_CREATE _IO('1', 1)
+#define PPS_IOC_DESTROY _IO('1', 2)
+#define PPS_IOC_SETPARAMS _IOW('1', 3, pps_params_t)
+#define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t)
+#define PPS_IOC_GETCAP _IOR('1', 5, int)
+#define PPS_IOC_FETCH _IOWR('1', 6, pps_info_t)
+#define PPS_IOC_WAIT _IOWR('1', 6, struct pps_wait_args)
+
+#endif /* _SYS_TIMEPPS_H_ */
OpenPOWER on IntegriCloud