Date: Sun, 10 Dec 2017 18:55:42 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326750 - head/sys/dev/iicbus Message-ID: <201712101855.vBAItgA3077611@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712101855.vBAItgA3077611>