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

Ian Lepore ian at FreeBSD.org
Tue Jan 23 21:31:45 UTC 2018


Author: ian
Date: Tue Jan 23 21:31:43 2018
New Revision: 328302
URL: https://svnweb.freebsd.org/changeset/base/328302

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/ds1307.c

Modified: head/sys/dev/iicbus/ds1307.c
==============================================================================
--- head/sys/dev/iicbus/ds1307.c	Tue Jan 23 21:18:15 2018	(r328301)
+++ head/sys/dev/iicbus/ds1307.c	Tue Jan 23 21:31:43 2018	(r328302)
@@ -322,7 +322,7 @@ static int
 ds1307_gettime(device_t dev, struct timespec *ts)
 {
 	int error;
-	struct clocktime ct;
+	struct bcd_clocktime bct;
 	struct ds1307_softc *sc;
 	uint8_t data[7], hourmask, st_mask;
 
@@ -350,30 +350,24 @@ ds1307_gettime(device_t dev, struct timespec *ts)
 	} else
 		hourmask = DS1307_HOUR_MASK_24HR;
 
-	ct.nsec = 0;
-	ct.sec  = FROMBCD(data[DS1307_SECS]  & DS1307_SECS_MASK);
-	ct.min  = FROMBCD(data[DS1307_MINS]  & DS1307_MINS_MASK);
-	ct.hour = FROMBCD(data[DS1307_HOUR]  & hourmask);
-	ct.day  = FROMBCD(data[DS1307_DATE]  & DS1307_DATE_MASK);
-	ct.mon  = FROMBCD(data[DS1307_MONTH] & DS1307_MONTH_MASK);
-	ct.year = FROMBCD(data[DS1307_YEAR]  & DS1307_YEAR_MASK);
+	bct.nsec = 0;
+	bct.ispm = (data[DS1307_HOUR] & DS1307_HOUR_IS_PM) != 0;
+	bct.sec  = data[DS1307_SECS]  & DS1307_SECS_MASK;
+	bct.min  = data[DS1307_MINS]  & DS1307_MINS_MASK;
+	bct.hour = data[DS1307_HOUR]  & hourmask;
+	bct.day  = data[DS1307_DATE]  & DS1307_DATE_MASK;
+	bct.mon  = data[DS1307_MONTH] & DS1307_MONTH_MASK;
+	bct.year = data[DS1307_YEAR]  & DS1307_YEAR_MASK;
 
-	if (sc->sc_use_ampm) {
-		if (ct.hour == 12)
-			ct.hour = 0;
-		if (data[DS1307_HOUR] & DS1307_HOUR_IS_PM)
-			ct.hour += 12;
-	}
-
-	return (clock_ct_to_ts(&ct, ts));
+	return (clock_bcd_to_ts(&bct, ts, sc->sc_use_ampm));
 }
 
 static int
 ds1307_settime(device_t dev, struct timespec *ts)
 {
-	struct clocktime ct;
+	struct bcd_clocktime bct;
 	struct ds1307_softc *sc;
-	int error;
+	int error, year;
 	uint8_t data[7];
 	uint8_t pmflags;
 
@@ -384,32 +378,28 @@ ds1307_settime(device_t dev, struct timespec *ts)
 	 * disables utc adjustment, so apply that ourselves.
 	 */
 	ts->tv_sec -= utc_offset();
-	clock_ts_to_ct(ts, &ct);
+	clock_ts_to_bcd(ts, &bct, sc->sc_use_ampm);
 
 	/* If the chip is in AM/PM mode, adjust hour and set flags as needed. */
 	if (sc->sc_use_ampm) {
 		pmflags = DS1307_HOUR_USE_AMPM;
-		if (ct.hour >= 12) {
-			ct.hour -= 12;
+		if (bct.ispm)
 			pmflags |= DS1307_HOUR_IS_PM;
-		}
-		if (ct.hour == 0)
-			ct.hour = 12;
 	} else
 		pmflags = 0;
 
-	data[DS1307_SECS]    = TOBCD(ct.sec);
-	data[DS1307_MINS]    = TOBCD(ct.min);
-	data[DS1307_HOUR]    = TOBCD(ct.hour) | pmflags;
-	data[DS1307_DATE]    = TOBCD(ct.day);
-	data[DS1307_WEEKDAY] = ct.dow;
-	data[DS1307_MONTH]   = TOBCD(ct.mon);
-	data[DS1307_YEAR]    = TOBCD(ct.year % 100);
+	data[DS1307_SECS]    = bct.sec;
+	data[DS1307_MINS]    = bct.min;
+	data[DS1307_HOUR]    = bct.hour | pmflags;
+	data[DS1307_DATE]    = bct.day;
+	data[DS1307_WEEKDAY] = bct.dow;
+	data[DS1307_MONTH]   = bct.mon;
+	data[DS1307_YEAR]    = bct.year & 0xff;
 	if (sc->sc_mcp7941x) {
 		data[DS1307_SECS] |= MCP7941X_SECS_ST;
 		data[DS1307_WEEKDAY] |= MCP7941X_WEEKDAY_VBATEN;
-		if ((ct.year % 4 == 0 && ct.year % 100 != 0) ||
-		    ct.year % 400 == 0)
+		year = bcd2bin(bct.year >> 8) * 100 + bcd2bin(bct.year & 0xff);
+		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
 			data[DS1307_MONTH] |= MCP7941X_MONTH_LPYR;
 	}
 	/* Write the time back to RTC. */


More information about the svn-src-head mailing list