svn commit: r321727 - head/sys/dev/iicbus
Ian Lepore
ian at FreeBSD.org
Sun Jul 30 19:58:32 UTC 2017
Author: ian
Date: Sun Jul 30 19:58:31 2017
New Revision: 321727
URL: https://svnweb.freebsd.org/changeset/base/321727
Log:
Fix AM/PM mode handling. The bits to mask off in the hours register changes
between 12/24 hour mode. Also fix conversion between 12 and 24 hour mode.
It's not as easy as adding/subtracting 12, because the clock doesn't roll
over 11->0, it rolls over 12->1; 0 isn't a valid hour in AM/PM mode.
Modified:
head/sys/dev/iicbus/nxprtc.c
Modified: head/sys/dev/iicbus/nxprtc.c
==============================================================================
--- head/sys/dev/iicbus/nxprtc.c Sun Jul 30 18:46:38 2017 (r321726)
+++ head/sys/dev/iicbus/nxprtc.c Sun Jul 30 19:58:31 2017 (r321727)
@@ -83,7 +83,8 @@ __FBSDID("$FreeBSD$");
#define PCF85xx_M_SECOND 0x7f /* Masks for all BCD time regs... */
#define PCF85xx_M_MINUTE 0x7f
-#define PCF85xx_M_HOUR 0x3f
+#define PCF85xx_M_12HOUR 0x1f
+#define PCF85xx_M_24HOUR 0x3f
#define PCF85xx_M_DAY 0x3f
#define PCF85xx_M_MONTH 0x1f
#define PCF85xx_M_YEAR 0xff
@@ -525,7 +526,7 @@ nxprtc_gettime(device_t dev, struct timespec *ts)
struct time_regs tregs;
struct nxprtc_softc *sc;
int err;
- uint8_t cs1, tmrcount;
+ uint8_t cs1, hourmask, tmrcount;
sc = device_get_softc(dev);
@@ -548,10 +549,15 @@ nxprtc_gettime(device_t dev, struct timespec *ts)
return (EINVAL); /* hardware is good, time is not. */
}
+ if (sc->flags & SC_F_AMPM)
+ hourmask = PCF85xx_M_12HOUR;
+ else
+ hourmask = PCF85xx_M_24HOUR;
+
ct.nsec = ((uint64_t)tmrcount * 1000000000) / TMR_TICKS_SEC;
ct.sec = FROMBCD(tregs.sec & PCF85xx_M_SECOND);
ct.min = FROMBCD(tregs.min & PCF85xx_M_MINUTE);
- ct.hour = FROMBCD(tregs.hour & PCF85xx_M_HOUR);
+ ct.hour = FROMBCD(tregs.hour & hourmask);
ct.day = FROMBCD(tregs.day & PCF85xx_M_DAY);
ct.mon = FROMBCD(tregs.month & PCF85xx_M_MONTH);
ct.year = FROMBCD(tregs.year & PCF85xx_M_YEAR);
@@ -574,8 +580,12 @@ nxprtc_gettime(device_t dev, struct timespec *ts)
}
/* If this chip is running in 12-hour/AMPM mode, deal with it. */
- if ((sc->flags & SC_F_AMPM) && (tregs.hour & PCF8523_B_HOUR_PM))
- ct.hour += 12;
+ if (sc->flags & SC_F_AMPM) {
+ if (ct.hour == 12)
+ ct.hour = 0;
+ if (tregs.hour & PCF8523_B_HOUR_PM)
+ ct.hour += 12;
+ }
err = clock_ct_to_ts(&ct, ts);
ts->tv_sec += utc_offset();
@@ -628,9 +638,13 @@ nxprtc_settime(device_t dev, struct timespec *ts)
/* If the chip is in AMPM mode deal with the PM flag. */
pmflag = 0;
- if ((sc->flags & SC_F_AMPM) && ct.hour > 12) {
- ct.hour -= 12;
- pmflag = PCF8523_B_HOUR_PM;
+ if (sc->flags & SC_F_AMPM) {
+ if (ct.hour >= 12) {
+ ct.hour -= 12;
+ pmflag = PCF8523_B_HOUR_PM;
+ }
+ if (ct.hour == 0)
+ ct.hour = 12;
}
/* On 8563 set the century based on the polarity seen when reading. */
More information about the svn-src-all
mailing list