Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic PPS support. Copied off of com.c support, with ch...



details:   https://anonhg.NetBSD.org/src/rev/c715ccde01b1
branches:  trunk
changeset: 467663:c715ccde01b1
user:      wrstuden <wrstuden%NetBSD.org@localhost>
date:      Sat Mar 27 01:22:36 1999 +0000

description:
PPS support. Copied off of com.c support, with changes as DCD interupts
are only enabled if needed and if ok'd by MD layer.

diffstat:

 sys/dev/ic/z8530sc.h  |    4 +-
 sys/dev/ic/z8530tty.c |  265 +++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 254 insertions(+), 15 deletions(-)

diffs (truncated from 374 to 300 lines):

diff -r 8d5df53d374c -r c715ccde01b1 sys/dev/ic/z8530sc.h
--- a/sys/dev/ic/z8530sc.h      Sat Mar 27 01:21:36 1999 +0000
+++ b/sys/dev/ic/z8530sc.h      Sat Mar 27 01:22:36 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: z8530sc.h,v 1.11 1999/02/03 20:22:28 mycroft Exp $     */
+/*     $NetBSD: z8530sc.h,v 1.12 1999/03/27 01:22:36 wrstuden Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -104,6 +104,7 @@
        u_char  cs_rr0_mask;            /* rr0 bits that stop output */
        u_char  cs_rr0_dcd;             /* which bit to read as DCD */
        u_char  cs_rr0_cts;             /* which bit to read as CTS */
+       u_char  cs_rr0_pps;             /* which bit to use for PPS */
        /* the above is set only while CRTSCTS is enabled. */
 
        u_char  cs_wr5_dtr;             /* which bit to write as DTR */
@@ -112,7 +113,6 @@
 
        char    cs_softreq;             /* need soft interrupt call */
        char    cs_spare1;      /* (for skippy :) */
-       char    cs_spare2;      /* (for skippy :) */
        /* MD code might define a larger variant of this. */
 };
 
diff -r 8d5df53d374c -r c715ccde01b1 sys/dev/ic/z8530tty.c
--- a/sys/dev/ic/z8530tty.c     Sat Mar 27 01:21:36 1999 +0000
+++ b/sys/dev/ic/z8530tty.c     Sat Mar 27 01:22:36 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: z8530tty.c,v 1.58 1999/02/03 23:51:06 mycroft Exp $    */
+/*     $NetBSD: z8530tty.c,v 1.59 1999/03/27 01:22:36 wrstuden Exp $   */
 
 /*-
  * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
@@ -106,6 +106,7 @@
 #include <sys/file.h>
 #include <sys/ioctl.h>
 #include <sys/malloc.h>
+#include <sys/timepps.h>
 #include <sys/tty.h>
 #include <sys/time.h>
 #include <sys/kernel.h>
@@ -137,6 +138,15 @@
 u_int zstty_rbuf_hiwat = (ZSTTY_RING_SIZE * 1) / 4;
 u_int zstty_rbuf_lowat = (ZSTTY_RING_SIZE * 3) / 4;
 
+static int zsppscap = 
+       PPS_TSFMT_TSPEC |
+       PPS_CAPTUREASSERT |
+       PPS_CAPTURECLEAR |
+#ifdef  PPS_SYNC
+       PPS_HARDPPSONASSERT | PPS_HARDPPSONCLEAR |
+#endif /* PPS_SYNC */
+       PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
+
 struct zstty_softc {
        struct  device zst_dev;         /* required first: base device */
        struct  tty *zst_tty;
@@ -179,6 +189,13 @@
                        zst_tx_stopped, /* H/W level stop (lost CTS) */
                        zst_st_check,   /* got a status interrupt */
                        zst_rx_ready;
+
+       /* PPS signal on DCD, with or without inkernel clock disciplining */
+       u_char  zst_ppsmask;                    /* pps signal mask */
+       u_char  zst_ppsassert;                  /* pps leading edge */
+       u_char  zst_ppsclear;                   /* pps trailing edge */
+       pps_info_t ppsinfo;
+       pps_params_t ppsparam;
 };
 
 /* Macros to clear/set/test flags. */
@@ -209,6 +226,7 @@
 static int  zs_to_tiocm __P((struct zstty_softc *));
 static int    zshwiflow __P((struct tty *, int));
 static void  zs_hwiflow __P((struct zstty_softc *));
+static void zs_maskintr __P((struct zstty_softc *));
 
 /* Low-level routines. */
 static void zstty_rxint   __P((struct zs_chanstate *));
@@ -397,6 +415,10 @@
        /* Clear any break condition set with TIOCSBRK. */
        zs_break(cs, 0);
 
+       /* Turn off PPS capture on last close. */
+       zst->zst_ppsmask = 0;
+       zst->ppsparam.mode = 0;
+
        /*
         * Hang up if necessary.  Wait a bit, so the other side has time to
         * notice even if we immediately open the port again.
@@ -486,6 +508,10 @@
                 */
                SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
 
+               /* Clear PPS capture state on first open. */
+               zst->zst_ppsmask = 0;
+               zst->ppsparam.mode = 0;
+
                splx(s2);
 
                /* Make sure zsparam will see changes. */
@@ -683,6 +709,151 @@
                *(int *)data = zs_to_tiocm(zst);
                break;
 
+       case PPS_CREATE:
+               break;
+
+       case PPS_DESTROY:
+               break;
+
+       case PPS_GETPARAMS: {
+               pps_params_t *pp;
+               pp = (pps_params_t *)data;
+               *pp = zst->ppsparam;
+               break;
+       }
+
+       case PPS_SETPARAMS: {
+               pps_params_t *pp;
+               int mode;
+               if (cs->cs_rr0_pps == 0) {
+                       error = EINVAL;
+                       break;
+               }
+               pp = (pps_params_t *)data;
+               if (pp->mode & ~zsppscap) {
+                       error = EINVAL;
+                       break;
+               }
+               zst->ppsparam = *pp;
+               /*
+                * compute masks from user-specified timestamp state.
+                */
+               mode = zst->ppsparam.mode;
+#ifdef PPS_SYNC
+               if (mode & PPS_HARDPPSONASSERT) {
+                       mode |= PPS_CAPTUREASSERT;
+                       /* XXX revoke any previous HARDPPS source */
+               }
+               if (mode & PPS_HARDPPSONCLEAR) {
+                       mode |= PPS_CAPTURECLEAR;
+                       /* XXX revoke any previous HARDPPS source */
+               }
+#endif /* PPS_SYNC */
+               switch (mode & PPS_CAPTUREBOTH) {
+               case 0:
+                       zst->zst_ppsmask = 0;
+                       break;
+
+               case PPS_CAPTUREASSERT:
+                       zst->zst_ppsmask = ZSRR0_DCD;
+                       zst->zst_ppsassert = ZSRR0_DCD;
+                       zst->zst_ppsclear = -1;
+                       break;
+
+               case PPS_CAPTURECLEAR:
+                       zst->zst_ppsmask = ZSRR0_DCD;
+                       zst->zst_ppsassert = -1;
+                       zst->zst_ppsclear = 0;
+                       break;
+
+               case PPS_CAPTUREBOTH:
+                       zst->zst_ppsmask = ZSRR0_DCD;
+                       zst->zst_ppsassert = ZSRR0_DCD;
+                       zst->zst_ppsclear = 0;
+                       break;
+
+               default:
+                       error = EINVAL;
+                       break;
+               }
+
+               /*
+                * Now update interrupts.
+                */
+               zs_maskintr(zst);
+               /*
+                * If nothing is being transmitted, set up new current values,
+                * else mark them as pending.
+                */
+               if (!cs->cs_heldchange) {
+                       if (zst->zst_tx_busy) {
+                               zst->zst_heldtbc = zst->zst_tbc;
+                               zst->zst_tbc = 0;
+                               cs->cs_heldchange = 1;
+                       } else
+                               zs_loadchannelregs(cs);
+               }
+
+               break;
+       }
+
+       case PPS_GETCAP:
+               *(int *)data = zsppscap;
+               break;
+
+       case PPS_FETCH: {
+               pps_info_t *pi;
+               pi = (pps_info_t *)data;
+               *pi = zst->ppsinfo;
+               break;
+       }
+
+       case PPS_WAIT:
+               /* XXX */
+               error = EOPNOTSUPP;
+               break;
+
+       case TIOCDCDTIMESTAMP:  /* XXX old, overloaded  API used by xntpd v3 */
+               if (cs->cs_rr0_pps == 0) {
+                       error = EINVAL;
+                       break;
+               }
+               /*
+                * Some GPS clocks models use the falling rather than
+                * rising edge as the on-the-second signal.
+                * The old API has no way to specify PPS polarity.
+                */
+               zst->zst_ppsmask = ZSRR0_DCD;
+#ifndef        PPS_TRAILING_EDGE
+               zst->zst_ppsassert = ZSRR0_DCD;
+               zst->zst_ppsclear = -1;
+               TIMESPEC_TO_TIMEVAL((struct timeval *)data,
+                       &zst->ppsinfo.assert_timestamp);
+#else
+               zst->zst_ppsassert = -1;
+               zst->zst_ppsclear = 01;
+               TIMESPEC_TO_TIMEVAL((struct timeval *)data,
+                       &zst->ppsinfo.clear_timestamp);
+#endif
+               /*
+                * Now update interrupts.
+                */
+               zs_maskintr(zst);
+               /*
+                * If nothing is being transmitted, set up new current values,
+                * else mark them as pending.
+                */
+               if (!cs->cs_heldchange) {
+                       if (zst->zst_tx_busy) {
+                               zst->zst_heldtbc = zst->zst_tbc;
+                               zst->zst_tbc = 0;
+                               cs->cs_heldchange = 1;
+                       } else
+                               zs_loadchannelregs(cs);
+               }
+
+               break;
+
        default:
                error = ENOTTY;
                break;
@@ -790,7 +961,7 @@
        struct zstty_softc *zst = zstty_cd.cd_devs[ZSUNIT(tp->t_dev)];
        struct zs_chanstate *cs = zst->zst_cs;
        int ospeed, cflag;
-       u_char tmp3, tmp4, tmp5, tmp15;
+       u_char tmp3, tmp4, tmp5;
        int s, error;
 
        ospeed = t->c_ospeed;
@@ -844,17 +1015,10 @@
         */
        s = splzs();
 
-       cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
-       tmp15 = cs->cs_preg[15];
-       if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
-               SET(tmp15, ZSWR15_DCD_IE);
-       else
-               CLR(tmp15, ZSWR15_DCD_IE);
-       if (ISSET(cs->cs_rr0_mask, ZSRR0_CTS))
-               SET(tmp15, ZSWR15_CTS_IE);
-       else
-               CLR(tmp15, ZSWR15_CTS_IE);
-       cs->cs_preg[15] = tmp15;
+       /*
+        * Recalculate which status ints to enable.
+        */
+       zs_maskintr(zst);
 
        /* Recompute character size bits. */
        tmp3 = cs->cs_preg[3];
@@ -964,6 +1128,34 @@
 }
 
 /*
+ * Compute interupt enable bits and set in the pending bits. Called both
+ * in zsparam() and when PPS (pulse per second timing) state changes.
+ * Must be called at splzs().
+ */
+static void
+zs_maskintr(zst)
+       struct zstty_softc *zst;
+{
+       struct zs_chanstate *cs = zst->zst_cs;
+       int tmp15;
+



Home | Main Index | Thread Index | Old Index