From 32c13ad7b5a74dde368ef15da1aa5ca52fdbd1b9 Mon Sep 17 00:00:00 2001 From: marcel Date: Thu, 11 Sep 2003 23:06:42 +0000 Subject: [PATCH] Add support for using uart(4) for pulse capturing for the Pulse Per Second (PPS) timing interface. The support is non-optional and by default uses the DCD line signal as the pulse input. A compile-time option (UART_PPS_ON_CTS) can be used to have uart(4) use the CTS line signal. Include in uart_bus.h to avoid having to add the inclusion of that header in all source files. Reviewed by: phk --- sys/conf/NOTES | 4 ++++ sys/conf/options | 3 +++ sys/dev/uart/uart_bus.h | 17 +++++++++++++++++ sys/dev/uart/uart_core.c | 12 ++++++++++++ sys/dev/uart/uart_tty.c | 11 +++++++++-- 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/sys/conf/NOTES b/sys/conf/NOTES index a85846bf8a6d..e5ae8a411bb1 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1465,6 +1465,10 @@ options CONSPEED=115200 # Speed for serial console # device uart +# Options for uart(4) +options UART_PPS_ON_CTS # Do time pulse capturing using CTS + # instead of DCD. + # The following hint should only be used for pure ISA devices. It is not # needed otherwise. Use of hints is strongly discouraged. hint.uart.0.at="isa" diff --git a/sys/conf/options b/sys/conf/options index 09926466bf17..38b1d01fda97 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -537,6 +537,9 @@ COM_MULTIPORT opt_sio.h BREAK_TO_DEBUGGER opt_comconsole.h ALT_BREAK_TO_DEBUGGER opt_comconsole.h +# Options to support PPS +UART_PPS_ON_CTS opt_uart.h + # options for bus/device framework BUS_DEBUG opt_bus.h diff --git a/sys/dev/uart/uart_bus.h b/sys/dev/uart/uart_bus.h index 71aa1beb532b..bd0bab7a74e2 100644 --- a/sys/dev/uart/uart_bus.h +++ b/sys/dev/uart/uart_bus.h @@ -29,6 +29,12 @@ #ifndef _DEV_UART_BUS_H_ #define _DEV_UART_BUS_H_ +#ifndef KLD_MODULE +#include "opt_uart.h" +#endif + +#include + /* Drain and flush targets. */ #define UART_DRAIN_RECEIVER 0x0001 #define UART_DRAIN_TRANSMITTER 0x0002 @@ -75,6 +81,14 @@ #define UART_SIGMASK_STATE 0x003f #define UART_SIGMASK_DELTA 0x3f00 +#ifdef UART_PPS_ON_CTS +#define UART_SIG_DPPS UART_SIG_DCTS +#define UART_SIG_PPS UART_SIG_CTS +#else +#define UART_SIG_DPPS UART_SIG_DDCD +#define UART_SIG_PPS UART_SIG_DCD +#endif + /* UART_IOCTL() requests */ #define UART_IOCTL_BREAK 1 #define UART_IOCTL_IFLOW 2 @@ -133,6 +147,9 @@ struct uart_softc { int sc_txdatasz; int sc_txfifosz; /* Size of TX FIFO and buffer. */ + /* Pulse capturing support (PPS). */ + struct pps_state sc_pps; + /* Upper layer data. */ void *sc_softih; uint32_t sc_ttypend; diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c index 450313a92b9f..883bea299683 100644 --- a/sys/dev/uart/uart_core.c +++ b/sys/dev/uart/uart_core.c @@ -162,6 +162,15 @@ uart_intr_sigchg(struct uart_softc *sc) int new, old, sig; sig = UART_GETSIG(sc); + + if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) { + if (sig & UART_SIG_DPPS) { + pps_capture(&sc->sc_pps); + pps_event(&sc->sc_pps, (sig & UART_SIG_PPS) ? + PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); + } + } + do { old = sc->sc_ttypend; new = old & ~UART_SIGMASK_STATE; @@ -393,6 +402,9 @@ uart_bus_attach(device_t dev) sc->sc_sysdev->stopbits); } + sc->sc_pps.ppscap = PPS_CAPTUREBOTH; + pps_init(&sc->sc_pps); + error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc); if (error) diff --git a/sys/dev/uart/uart_tty.c b/sys/dev/uart/uart_tty.c index 3841889ddf22..2814e6d4ae48 100644 --- a/sys/dev/uart/uart_tty.c +++ b/sys/dev/uart/uart_tty.c @@ -476,6 +476,9 @@ uart_tty_close(dev_t dev, int flags, int mode, struct thread *td) if (sc->sc_sysdev == NULL) UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS); + /* Disable pulse capturing. */ + sc->sc_pps.ppsparam.mode = 0; + (*linesw[tp->t_line].l_close)(tp, flags); ttyclose(tp); wakeup(sc); @@ -505,6 +508,7 @@ uart_tty_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, if (error != ENOIOCTL) return (error); + error = 0; switch (cmd) { case TIOCSBRK: UART_IOCTL(sc, UART_IOCTL_BREAK, 1); @@ -563,7 +567,10 @@ uart_tty_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, *(int*)data = bits; break; default: - return (ENOTTY); + error = pps_ioctl(cmd, data, &sc->sc_pps); + if (error == ENODEV) + error = ENOTTY; + break; } - return (0); + return (error); }