summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-06-07 19:44:22 +0000
committerphk <phk@FreeBSD.org>1998-06-07 19:44:22 +0000
commita3d971d99da6c9c2a860d0863b2f7995f7605ffb (patch)
tree6e38c7241c6cc85503b065f6f77935df169cbecb /sys
parent7926e3cc5bd26a7c5a3e810760d4e3d3fdeccb73 (diff)
downloadFreeBSD-src-a3d971d99da6c9c2a860d0863b2f7995f7605ffb.zip
FreeBSD-src-a3d971d99da6c9c2a860d0863b2f7995f7605ffb.tar.gz
This is a prototype implementation of the draft-mogul-pps-api-##.txt
paper. It will be updated along with the draft and possible subsequent standard. The ppbus based pps driver is updated to implement this API.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ppbus/ppbconf.h3
-rw-r--r--sys/dev/ppbus/pps.c109
-rw-r--r--sys/sys/timepps.h67
3 files changed, 129 insertions, 50 deletions
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