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