diff options
author | phk <phk@FreeBSD.org> | 1998-06-07 19:44:22 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1998-06-07 19:44:22 +0000 |
commit | a3d971d99da6c9c2a860d0863b2f7995f7605ffb (patch) | |
tree | 6e38c7241c6cc85503b065f6f77935df169cbecb /sys | |
parent | 7926e3cc5bd26a7c5a3e810760d4e3d3fdeccb73 (diff) | |
download | FreeBSD-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.h | 3 | ||||
-rw-r--r-- | sys/dev/ppbus/pps.c | 109 | ||||
-rw-r--r-- | sys/sys/timepps.h | 67 |
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_ */ |