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

Ian Lepore ian at FreeBSD.org
Sun Dec 10 18:55:44 UTC 2017


Author: ian
Date: Sun Dec 10 18:55:42 2017
New Revision: 326750
URL: https://svnweb.freebsd.org/changeset/base/326750

Log:
  Do not give up if writing to the chip's control and status registers fails
  during startup.  When a brand new chip leaves the factory, it is in a
  special power-saving mode that disables most functions on the chip to
  save battery power.  The chip is stuck in this mode until the first write
  to the time registers, which automatically clears the special power-saving
  mode and starts the oscillator.
  
  Also, the day-of-week register in this chip counts 1-7, not 0-6, so write
  the values accordingly.
  
  These changes are based on the patch submitted by Brian Scott, but I
  elimated warnings since this condition is expected, and added some comments,
  and so in general blame me for any mistakes.
  
  PR:		223642

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

Modified: head/sys/dev/iicbus/ds3231.c
==============================================================================
--- head/sys/dev/iicbus/ds3231.c	Sun Dec 10 17:56:03 2017	(r326749)
+++ head/sys/dev/iicbus/ds3231.c	Sun Dec 10 18:55:42 2017	(r326750)
@@ -427,13 +427,19 @@ ds3231_start(void *xdev)
 		device_printf(sc->sc_dev,
 		    "WARNING: RTC clock stopped, check the battery.\n");
 	}
-	/* Ack any pending alarm interrupt. */
-	if (ds3231_status_write(sc, 1, 1) != 0)
-		return;
-	/* Always enable the oscillator. */
-	if (ds3231_ctrl_write(sc) != 0)
-		return;
 
+	/*
+	 * Ack any pending alarm interrupts and clear the EOSC bit to ensure the
+	 * clock runs even when on battery power.  Do not give up if these
+	 * writes fail, because a factory-fresh chip is in a special mode that
+	 * disables much of the chip to save battery power, and the only thing
+	 * that gets it out of that mode is writing to the time registers.  In
+	 * these pristine chips, the EOSC and alarm bits are zero already, so
+	 * the first valid write of time will get everything running properly.
+	 */
+	ds3231_status_write(sc, 1, 1);
+	ds3231_ctrl_write(sc);
+
 	/* Temperature. */
 	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature",
 	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
@@ -568,7 +574,7 @@ ds3231_settime(device_t dev, struct timespec *ts)
 	data[DS3231_MINS]    = TOBCD(ct.min);
 	data[DS3231_HOUR]    = TOBCD(ct.hour) | pmflags;
 	data[DS3231_DATE]    = TOBCD(ct.day);
-	data[DS3231_WEEKDAY] = ct.dow;
+	data[DS3231_WEEKDAY] = ct.dow + 1;
 	data[DS3231_MONTH]   = TOBCD(ct.mon);
 	data[DS3231_YEAR]    = TOBCD(ct.year % 100);
 	if (sc->sc_last_c)


More information about the svn-src-all mailing list