From 0cc1098a1a6b8353da73ee579091d399652aa57c Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Mon, 15 Jul 2019 21:47:40 +0000 Subject: [PATCH] In nxprtc(4), use the countdown timer for better timekeeping resolution on PCx2129 chips too. The datasheet for the PCx2129 chips says that there is only a watchdog timer, no countdown timer. It turns out the countdown timer hardware is there and works just the same as it does on a PCx2127 chip, except that you can't use it to trigger an interrupt or toggle an output pin. We don't need interrupts or output pins, we only need to read the timer register to get sub-second resolution. So start treating the 2129 chips the same as 2127. --- sys/dev/iicbus/nxprtc.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/sys/dev/iicbus/nxprtc.c b/sys/dev/iicbus/nxprtc.c index 37976a664c6..02eb9f85b51 100644 --- a/sys/dev/iicbus/nxprtc.c +++ b/sys/dev/iicbus/nxprtc.c @@ -33,8 +33,8 @@ __FBSDID("$FreeBSD$"); * - PCA8565 = like PCF8563, automotive temperature range * - PCF8523 = low power, countdown timer, oscillator freq tuning, 2 timers * - PCF2127 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, 512B ram - * - PCA2129 = like PCF8523, automotive, tcxo, tamper/ts, i2c & spi, no timer - * - PCF2129 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, no timer + * - PCA2129 = like PCF8523, automotive, tcxo, tamper/ts, i2c & spi, (note 1) + * - PCF2129 = like PCF8523, industrial, tcxo, tamper/ts, i2c & spi, (note 1) * * Most chips have a countdown timer, ostensibly intended to generate periodic * interrupt signals on an output pin. The timer is driven from the same @@ -42,6 +42,13 @@ __FBSDID("$FreeBSD$"); * in sync when the STOP bit is cleared after the time and timer registers are * set. The timer register can also be read on the fly, so we use it to count * fractional seconds and get a resolution of ~15ms. + * + * [1] Note that the datasheets for the PCx2129 chips state that they have only + * a watchdog timer, not a countdown timer. Empirical testing shows that the + * countdown timer is actually there and it works fine, except that it can't + * trigger an interrupt or toggle an output pin like it can on other chips. We + * don't care about interrupts and output pins, we just read the timer register + * to get better resolution. */ #include "opt_platform.h" @@ -471,7 +478,13 @@ pcf2127_start_timer(struct nxprtc_softc *sc) int err; uint8_t stdctl, tmrctl; - /* See comment in pcf8523_start_timer(). */ + /* + * Set up timer if it's not already in the mode we normally run it. See + * the comment in pcf8523_start_timer() for more details. + * + * Note that the PCF2129 datasheet says it has no countdown timer, but + * empirical testing shows that it works just fine for our purposes. + */ if ((err = read_reg(sc, PCF2127_R_TMR_CTL, &tmrctl)) != 0) return (err); @@ -521,10 +534,6 @@ nxprtc_start(void *dev) switch (sc->chiptype) { case TYPE_PCA2129: case TYPE_PCF2129: - if (pcf8523_start(sc) != 0) - return; - /* No timer to start */ - break; case TYPE_PCF2127: if (pcf8523_start(sc) != 0) return; @@ -796,10 +805,6 @@ nxprtc_attach(device_t dev) switch (sc->chiptype) { case TYPE_PCA2129: case TYPE_PCF2129: - sc->secaddr = PCF8523_R_SECOND; - sc->tmcaddr = 0; - sc->use_timer = false; - break; case TYPE_PCF2127: case TYPE_PCF8523: sc->secaddr = PCF8523_R_SECOND; -- 2.45.0