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

Justin Hibbits jhibbits at FreeBSD.org
Wed Nov 8 01:29:36 UTC 2017


Author: jhibbits
Date: Wed Nov  8 01:28:20 2017
New Revision: 325527
URL: https://svnweb.freebsd.org/changeset/base/325527

Log:
  DS1307: Add the mcp7941x enable bit
  
  Summary:
  Existing code recognizes the mcp7941x RTC, but this RTC has an
  enable bit at the same location as the "Clock Halt" bit on the ds1307, with an
  opposite assertion (set == on, whereas CH set == clock stopped).  Thus the
  current code halts the clock, with no way to enable it.
  
  Reviewed By:	ian
  MFC after:	2 weeks
  Differential Revision: https://reviews.freebsd.org/D12961

Modified:
  head/sys/dev/iicbus/ds1307.c
  head/sys/dev/iicbus/ds1307reg.h

Modified: head/sys/dev/iicbus/ds1307.c
==============================================================================
--- head/sys/dev/iicbus/ds1307.c	Wed Nov  8 01:26:44 2017	(r325526)
+++ head/sys/dev/iicbus/ds1307.c	Wed Nov  8 01:28:20 2017	(r325527)
@@ -272,6 +272,7 @@ ds1307_start(void *xdev)
 	struct sysctl_oid *tree_node;
 	struct sysctl_oid_list *tree;
 	uint8_t secs;
+	uint8_t osc_en;
 
 	dev = (device_t)xdev;
 	sc = device_get_softc(dev);
@@ -286,7 +287,12 @@ ds1307_start(void *xdev)
 		device_printf(sc->sc_dev, "cannot read from RTC.\n");
 		return;
 	}
-	if ((secs & DS1307_SECS_CH) != 0) {
+	if (sc->sc_mcp7941x)
+		osc_en = 0x80;
+	else
+		osc_en = 0x00;
+
+	if (((secs & DS1307_SECS_CH) ^ osc_en) != 0) {
 		device_printf(sc->sc_dev,
 		    "WARNING: RTC clock stopped, check the battery.\n");
 	}
@@ -318,7 +324,7 @@ ds1307_gettime(device_t dev, struct timespec *ts)
 	int error;
 	struct clocktime ct;
 	struct ds1307_softc *sc;
-	uint8_t data[7], hourmask;
+	uint8_t data[7], hourmask, st_mask;
 
 	sc = device_get_softc(dev);
 	error = iicdev_readfrom(sc->sc_dev, DS1307_SECS, data, sizeof(data),
@@ -329,7 +335,12 @@ ds1307_gettime(device_t dev, struct timespec *ts)
 	}
 
 	/* If the clock halted, we don't have good data. */
-	if (data[DS1307_SECS] & DS1307_SECS_CH)
+	if (sc->sc_mcp7941x)
+		st_mask = 0x80;
+	else
+		st_mask = 0x00;
+
+	if (((data[DS1307_SECS] & DS1307_SECS_CH) ^ st_mask) != 0)
 		return (EINVAL);
 
 	/* If chip is in AM/PM mode remember that. */
@@ -394,6 +405,13 @@ ds1307_settime(device_t dev, struct timespec *ts)
 	data[DS1307_WEEKDAY] = ct.dow;
 	data[DS1307_MONTH]   = TOBCD(ct.mon);
 	data[DS1307_YEAR]    = TOBCD(ct.year % 100);
+	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)
+			data[DS1307_MONTH] |= MCP7941X_MONTH_LPYR;
+	}
 	/* Write the time back to RTC. */
 	error = iicdev_writeto(sc->sc_dev, DS1307_SECS, data, sizeof(data),
 	    IIC_INTRWAIT);

Modified: head/sys/dev/iicbus/ds1307reg.h
==============================================================================
--- head/sys/dev/iicbus/ds1307reg.h	Wed Nov  8 01:26:44 2017	(r325526)
+++ head/sys/dev/iicbus/ds1307reg.h	Wed Nov  8 01:28:20 2017	(r325527)
@@ -36,6 +36,7 @@
 #define	DS1307_SECS		0x00
 #define	DS1307_SECS_MASK		0x7f
 #define	DS1307_SECS_CH			0x80
+#define	MCP7941X_SECS_ST		0x80
 #define	DS1307_MINS		0x01
 #define	DS1307_MINS_MASK		0x7f
 #define	DS1307_HOUR		0x02
@@ -44,10 +45,12 @@
 #define	DS1307_HOUR_IS_PM		0x20
 #define	DS1307_HOUR_USE_AMPM		0x40
 #define	DS1307_WEEKDAY		0x03
+#define	MCP7941X_WEEKDAY_VBATEN		0x08
 #define	DS1307_WEEKDAY_MASK		0x07
 #define	DS1307_DATE		0x04
 #define	DS1307_DATE_MASK		0x3f
 #define	DS1307_MONTH		0x05
+#define	MCP7941X_MONTH_LPYR		0x20
 #define	DS1307_MONTH_MASK		0x1f
 #define	DS1307_YEAR		0x06
 #define	DS1307_YEAR_MASK		0xff


More information about the svn-src-all mailing list