svn commit: r328303 - head/sys/dev/iicbus

Ian Lepore ian at FreeBSD.org
Tue Jan 23 21:36:29 UTC 2018


Author: ian
Date: Tue Jan 23 21:36:26 2018
New Revision: 328303
URL: https://svnweb.freebsd.org/changeset/base/328303

Log:
  Switch to using the bcd_clocktime conversion functions that validate the BCD
  data without panicking, and have common code for handling AM/PM mode.

Modified:
  head/sys/dev/iicbus/nxprtc.c

Modified: head/sys/dev/iicbus/nxprtc.c
==============================================================================
--- head/sys/dev/iicbus/nxprtc.c	Tue Jan 23 21:31:43 2018	(r328302)
+++ head/sys/dev/iicbus/nxprtc.c	Tue Jan 23 21:36:26 2018	(r328303)
@@ -192,10 +192,10 @@ struct nxprtc_softc {
 	uint8_t		secaddr;	/* Address of seconds register */
 	uint8_t		tmcaddr;	/* Address of timer count register */
 	bool		use_timer;	/* Use timer for fractional sec */
+	bool		use_ampm;	/* Chip is set to use am/pm mode */
 };
 
 #define	SC_F_CPOL	(1 << 0)	/* Century bit means 19xx */
-#define	SC_F_AMPM	(1 << 1)	/* Use PM flag in hours reg */
 
 /*
  * We use the compat_data table to look up hint strings in the non-FDT case, so
@@ -382,10 +382,10 @@ pcf8523_start(struct nxprtc_softc *sc)
 	/* Remember whether we're running in AM/PM mode. */
 	if (is2129) {
 		if (cs1 & PCF2129_B_CS1_12HR)
-			sc->flags |= SC_F_AMPM;
+			sc->use_ampm = true;
 	} else {
 		if (cs1 & PCF8523_B_CS1_12HR)
-			sc->flags |= SC_F_AMPM;
+			sc->use_ampm = true;
 	}
 
 	return (0);
@@ -543,7 +543,7 @@ nxprtc_start(void *dev)
 static int
 nxprtc_gettime(device_t dev, struct timespec *ts)
 {
-	struct clocktime ct;
+	struct bcd_clocktime bct;
 	struct time_regs tregs;
 	struct nxprtc_softc *sc;
 	int err;
@@ -570,21 +570,19 @@ nxprtc_gettime(device_t dev, struct timespec *ts)
 		return (EINVAL); /* hardware is good, time is not. */
 	}
 
-	if (sc->flags & SC_F_AMPM)
+	if (sc->use_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  & 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);
-	ct.year += 1900;
-	if (ct.year < POSIX_BASE_YEAR)
-		ct.year += 100;	/* assume [1970, 2069] */
+	bct.nsec = ((uint64_t)tmrcount * 1000000000) / TMR_TICKS_SEC;
+	bct.ispm = (tregs.hour & PCF8523_B_HOUR_PM) != 0;
+	bct.sec  = tregs.sec   & PCF85xx_M_SECOND;
+	bct.min  = tregs.min   & PCF85xx_M_MINUTE;
+	bct.hour = tregs.hour  & hourmask;
+	bct.day  = tregs.day   & PCF85xx_M_DAY;
+	bct.mon  = tregs.month & PCF85xx_M_MONTH;
+	bct.year = tregs.year  & PCF85xx_M_YEAR;
 
 	/*
 	 * Old PCF8563 datasheets recommended that the C bit be 1 for 19xx and 0
@@ -594,21 +592,13 @@ nxprtc_gettime(device_t dev, struct timespec *ts)
 	 */
 	if (sc->chiptype == TYPE_PCF8563) {
 		if (tregs.month & PCF8563_B_MONTH_C) {
-			if (ct.year >= 2000)
+			if (bct.year < 0x70)
 				sc->flags |= SC_F_CPOL;
-		} else if (ct.year < 2000)
+		} else if (bct.year >= 0x70)
 				sc->flags |= SC_F_CPOL;
 	}
 
-	/* If this chip is running in 12-hour/AMPM mode, deal with it. */
-	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);
+	err = clock_bcd_to_ts(&bct, ts, sc->use_ampm);
 	ts->tv_sec += utc_offset();
 
 	return (err);
@@ -617,11 +607,11 @@ nxprtc_gettime(device_t dev, struct timespec *ts)
 static int
 nxprtc_settime(device_t dev, struct timespec *ts)
 {
-	struct clocktime ct;
+	struct bcd_clocktime bct;
 	struct time_regs tregs;
 	struct nxprtc_softc *sc;
 	int err;
-	uint8_t cflag, cs1, pmflag;
+	uint8_t cflag, cs1;
 
 	sc = device_get_softc(dev);
 
@@ -647,36 +637,25 @@ nxprtc_settime(device_t dev, struct timespec *ts)
 	getnanotime(ts);
 	ts->tv_sec -= utc_offset();
 	ts->tv_nsec = 0;
-	clock_ts_to_ct(ts, &ct);
+	clock_ts_to_bcd(ts, &bct, sc->use_ampm);
 
-	/* If the chip is in AMPM mode deal with the PM flag. */
-	pmflag = 0;
-	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. */
 	cflag = 0;
 	if (sc->chiptype == TYPE_PCF8563) {
 		if ((sc->flags & SC_F_CPOL) != 0) {
-			if (ct.year >= 2000)
+			if (bct.year >= 0x2000)
 				cflag = PCF8563_B_MONTH_C;
-		} else if (ct.year < 2000)
+		} else if (bct.year < 0x2000)
 				cflag = PCF8563_B_MONTH_C;
 	}
 
-	tregs.sec   = TOBCD(ct.sec);
-	tregs.min   = TOBCD(ct.min);
-	tregs.hour  = TOBCD(ct.hour) | pmflag;
-	tregs.day   = TOBCD(ct.day);
-	tregs.month = TOBCD(ct.mon);
-	tregs.year  = TOBCD(ct.year % 100) | cflag;
-	tregs.wday  = ct.dow;
+	tregs.sec   = bct.sec;
+	tregs.min   = bct.min;
+	tregs.hour  = bct.hour | (bct.ispm ? PCF8523_B_HOUR_PM : 0);
+	tregs.day   = bct.day;
+	tregs.month = bct.mon;
+	tregs.year  = (bct.year & 0xff) | cflag;
+	tregs.wday  = bct.dow;
 
 	/*
 	 * Set the time, reset the timer count register, then start the clocks.


More information about the svn-src-all mailing list