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