diff options
Diffstat (limited to 'sys/dev/usb/serial/usb_serial.c')
-rw-r--r-- | sys/dev/usb/serial/usb_serial.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c index 1f577a8..8ac15a0 100644 --- a/sys/dev/usb/serial/usb_serial.c +++ b/sys/dev/usb/serial/usb_serial.c @@ -96,6 +96,11 @@ __FBSDID("$FreeBSD$"); static SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom"); +static int ucom_pps_mode; + +SYSCTL_INT(_hw_usb_ucom, OID_AUTO, pps_mode, CTLFLAG_RWTUN, + &ucom_pps_mode, 0, "pulse capturing mode - 0/1/2 - disabled/CTS/DCD"); + #ifdef USB_DEBUG static int ucom_debug = 0; @@ -409,6 +414,10 @@ ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc) sc->sc_tty = tp; + sc->sc_pps.ppscap = PPS_CAPTUREBOTH; + sc->sc_pps.mtx = sc->sc_mtx; + pps_init(&sc->sc_pps); + DPRINTF("ttycreate: %s\n", buf); /* Check if this device should be a console */ @@ -858,6 +867,8 @@ ucom_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) } else { error = ENOIOCTL; } + if (error == ENOIOCTL) + error = pps_ioctl(cmd, data, &sc->sc_pps); break; } return (error); @@ -1061,7 +1072,7 @@ ucom_cfg_status_change(struct usb_proc_msg *_task) struct tty *tp; uint8_t new_msr; uint8_t new_lsr; - uint8_t onoff; + uint8_t msr_delta; uint8_t lsr_delta; tp = sc->sc_tty; @@ -1085,15 +1096,37 @@ ucom_cfg_status_change(struct usb_proc_msg *_task) /* TTY device closed */ return; } - onoff = ((sc->sc_msr ^ new_msr) & SER_DCD); + msr_delta = (sc->sc_msr ^ new_msr); lsr_delta = (sc->sc_lsr ^ new_lsr); sc->sc_msr = new_msr; sc->sc_lsr = new_lsr; - if (onoff) { + /* time pulse counting support */ + switch(ucom_pps_mode) { + case 1: + if ((sc->sc_pps.ppscap & PPS_CAPTUREBOTH) && + (msr_delta & SER_CTS)) { + pps_capture(&sc->sc_pps); + pps_event(&sc->sc_pps, (sc->sc_msr & SER_CTS) ? + PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); + } + break; + case 2: + if ((sc->sc_pps.ppscap & PPS_CAPTUREBOTH) && + (msr_delta & SER_DCD)) { + pps_capture(&sc->sc_pps); + pps_event(&sc->sc_pps, (sc->sc_msr & SER_DCD) ? + PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); + } + break; + default: + break; + } + + if (msr_delta & SER_DCD) { - onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; + int onoff = (sc->sc_msr & SER_DCD) ? 1 : 0; DPRINTF("DCD changed to %d\n", onoff); |