Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Sep 2017 22:21:15 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r323467 - in stable/11/sys: arm/allwinner conf dev/iicbus mips/conf mips/rmi modules/i2c modules/i2c/ds1307 modules/i2c/ds13rtc modules/i2c/ds3231 modules/i2c/isl12xx modules/i2c/nxprtc...
Message-ID:  <201709112221.v8BMLFoV061582@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Mon Sep 11 22:21:15 2017
New Revision: 323467
URL: https://svnweb.freebsd.org/changeset/base/323467

Log:
  MFC r321708-r321712, r321721, r321726-r321727, r321746, r321751,
      r321791-r321792, r321795, r321798, r321821, r321823, r321826,
      r321828, r321841, r321934, r322025-r322026, r322282, r322431,
      r322473, r322475-r322479
  
  Lots of i2c RTC driver stuff...
  
  r321708:
  Replace the pcf8563 i2c RTC driver with a new nxprtc driver which handles
  all the chips in the NXP PCA212x and PCA/PCF85xx series.  In addition to
  supporting more chips, this driver uses the countdown timer on the chips as
  a fractional seconds counter, giving it a resolution of about 15 milliseconds.
  
  r321709:
  Fix building this driver on non-FDT platforms.
  
  r321710:
  Add a few missing i2c devices that build fine on all arches.
  
  r321711:
  Move the device descriptions onto the device lines, so they cut and paste
  nicely into other config files.
  
  r321712:
  Add the i2c RTC drivers found on various arm systems.
  
  r321721:
  Switch from using iic_transfer() to iicdev_readfrom/writeto(), mostly so
  that transfers will be done with proper ownership of the bus. No
  behavioral changes.
  
  r321726:
  Bugfixes and enhancements...
  
  Don't enable the oscillator when it is found to be stopped at init time,
  just let the first setting of valid time start it.  But still report a dead
  battery if it's stopped at init time.
  
  Don't force the chip into 24hr mode, just cope with whatever mode it is
  already in.
  
  Align the RTC clock to top of second when setting it.
  
  r321727:
  Fix AM/PM mode handling.  The bits to mask off in the hours register changes
  between 12/24 hour mode.  Also fix conversion between 12 and 24 hour mode.
  It's not as easy as adding/subtracting 12, because the clock doesn't roll
  over 11->0, it rolls over 12->1; 0 isn't a valid hour in AM/PM mode.
  
  r321746:
  Use the new clock_schedule() to arrange for clock_settime() to be called
  at the right time to keep the RTC hardware time in sync, instead of using
  pause_sbt() to sleep until the right time.
  
  r321751:
  Remove now-unused variable.
  
  r321791:
  Switch from using iic_transfer() to iicdev_readfrom/writeto(), mostly so
  that transfers will be done with proper ownership of the bus. No
  behavioral changes.  Also add a detach() method.
  
  r321792:
  Add a detach() method.
  
  r321795:
  Check the clock-halted flag every time the clock is read, not just once
  at startup.  The flag stays set until the clock is loaded with good time,
  so we need to keep saying the time is invalid until that happens.
  
  r321798:
  Restore a few rather important lines of code that got fumbled in r321746.
  
  r321821:
  No need to call getnanotime() now that the waiting is done by the central
  subr_rtc code, switch from CLOCKF_SETTIME_NO_TS to CLOCKF_SETTIME_NO_ADJ
  so that we get fed a timestamp, but it's not adjusted to compensate for
  inaccuracy in setting time.
  
  r321823:
  Bugfixes and enhancements...
  
  Don't enable the oscillator when it is found to be stopped at init time,
  just let the first setting of valid time start it.  But still report a dead
  battery if it's stopped at init time.
  
  Don't force the chip into 24hr mode, just cope with whatever mode it is
  already in.
  
  Schedule the clock_settime() callbacks to align the RTC clock to top of
  second when setting it.
  
  r321826:
  Restructure the SUBDIR list as 1-per-line and alphabetize, so it will be
  easier to add new things (and see what changed) in the future.
  
  r321828:
  Build iicbus/{ds1307,ds3231,nxprtc} as modules.
  
  r321841:
  Add a driver for the Intersil ISL12xx family of i2c RTC chips.
  
  Supports ISL1209, ISL1218, ISL1219, ISL1220, ISL1221 (just basic RTC
  functionality, not all the other fancy stuff the chips can do).
  
  r321934:
  Add missing ofw_bus_if.h src file.
  
  r322025:
  Switch to iicdev_readfrom/writeto() to do xfers with proper bus ownership.
  
  Tested by:	manu@
  
  r322026:
  Add missing header file to SRCS.
  
  Reported by:	manu@
  
  r322282:
  Remove the ds133x and s35390a i2c RTC drivers for now.  They both do i2c
  transfers in their probe() or attach() routines, and that doesn't work
  when the low-level controller requires interrupts to be functional.
  
  The DS133x family of chips is nearly identical to the DS1307 and support
  for them should be added to that driver, then the ds133x driver can be
  deleted.  The s35390a driver just needs a non-trivial workover.  In both
  cases that work will be done and committed separately.
  
  r322431:
  Bid for the device with BUS_PROBE_GENERIC, because this is very much a
  generic driver with minimal feature support for a large number of chips.
  More featureful per-chip drivers might exist (especially out-of-tree) and
  those should win the bidding even if they use BUS_PROBE_DEFAULT.
  
  r322473:
  Add a new driver, ds13rtc, that handles all DS13xx series i2c RTC chips.
  
  This driver supports only basic timekeeping functionality.  It completely
  replaces the ds133x driver.  It can also replace the ds1374 driver, but that
  will take a few other changes in MIPS code and config, and will be committed
  separately.  It does NOT replace the existing ds1307 driver, which provides
  access to some of the extended features on the 1307 chip, such as controlling
  the square wave output signal.  If both ds1307 and ds13rtc drivers are
  present, the ds1307 driver will outbid and win control of the device.
  
  This driver can be configured with FDT data, or by using hints on non-FDT
  systems.  In addition to the standard hints for i2c devices, it requires
  a "chiptype" string of the form "dallas,ds13xx" where 'xx' is the chip id
  (i.e., the same format as FDT compat strings).
  
  r322475:
  Change "chiptype" to "compatible".  Making the hint name the same as the FDT
  property name should make it easier to document the list of names accepted
  by both configuration mechanisms.
  
  r322476:
  Remove the old ds1374 driver and use the ds13rtc driver instead.  Adjust
  several mips config files accordingly.
  
  r322477:
  Minor fixes and enhancements for the s35390a i2c RTC driver...
  
  - Add FDT probe code.
  - Do i2c transfers with exclusive bus ownership.
  - Use config_intrhook_oneshot() to defer chip setup because some i2c
    busses can't do transfers without interrupts.
  - Add a detach() routine.
  - Add to module build.
  
  r322478:
  Add back the drivers for Dallas/Maxim ds13xx and Seiko S35390x now that
  they've been rewritten/fixed to not cause panics by doing i2c transfers
  before interrupts are available.
  
  PR:		221227
  
  r322479:
  Add hinted attachment for non-FDT systems.  Also, print a message if
  setting up the timer fails, because on some types of chips that's the
  first attempt to access the device.  If the chip is missing/non-responsive
  then you'd get a driver that attached and didn't register the rtc, with
  no clue about why.  On other chip types there are inits that come before
  timer setup, and they already print messages about errors.

Added:
  stable/11/sys/dev/iicbus/ds13rtc.c
     - copied, changed from r322473, head/sys/dev/iicbus/ds13rtc.c
  stable/11/sys/dev/iicbus/isl12xx.c
     - copied unchanged from r321841, head/sys/dev/iicbus/isl12xx.c
  stable/11/sys/dev/iicbus/nxprtc.c
     - copied, changed from r321712, head/sys/dev/iicbus/nxprtc.c
  stable/11/sys/modules/i2c/ds1307/
     - copied from r321828, head/sys/modules/i2c/ds1307/
  stable/11/sys/modules/i2c/ds13rtc/
     - copied from r322473, head/sys/modules/i2c/ds13rtc/
  stable/11/sys/modules/i2c/ds3231/
     - copied from r321828, head/sys/modules/i2c/ds3231/
  stable/11/sys/modules/i2c/isl12xx/
     - copied from r321841, head/sys/modules/i2c/isl12xx/
  stable/11/sys/modules/i2c/nxprtc/
     - copied from r321828, head/sys/modules/i2c/nxprtc/
  stable/11/sys/modules/i2c/s35390a/
     - copied from r322479, head/sys/modules/i2c/s35390a/
Deleted:
  stable/11/sys/dev/iicbus/ds133x.c
  stable/11/sys/dev/iicbus/ds1374.c
  stable/11/sys/dev/iicbus/pcf8563.c
  stable/11/sys/dev/iicbus/pcf8563reg.h
Modified:
  stable/11/sys/arm/allwinner/axp209.c
  stable/11/sys/conf/NOTES
  stable/11/sys/conf/files
  stable/11/sys/dev/iicbus/ds1307.c
  stable/11/sys/dev/iicbus/ds1307reg.h
  stable/11/sys/dev/iicbus/ds3231.c
  stable/11/sys/dev/iicbus/ds3231reg.h
  stable/11/sys/dev/iicbus/s35390a.c
  stable/11/sys/mips/conf/XLP.hints
  stable/11/sys/mips/conf/XLR
  stable/11/sys/mips/conf/XLR64
  stable/11/sys/mips/conf/XLRN32
  stable/11/sys/mips/conf/std.XLP
  stable/11/sys/mips/rmi/xlr_i2c.c
  stable/11/sys/modules/i2c/Makefile
  stable/11/sys/modules/i2c/ds1307/Makefile
  stable/11/sys/modules/i2c/ds3231/Makefile
  stable/11/sys/modules/i2c/isl12xx/Makefile
  stable/11/sys/modules/i2c/nxprtc/Makefile
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/allwinner/axp209.c
==============================================================================
--- stable/11/sys/arm/allwinner/axp209.c	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/arm/allwinner/axp209.c	Mon Sep 11 22:21:15 2017	(r323467)
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <sys/sysctl.h>
 
-#include <dev/iicbus/iicbus.h>
 #include <dev/iicbus/iiconf.h>
 
 #include <dev/gpio/gpiobusvar.h>
@@ -59,7 +58,6 @@ __FBSDID("$FreeBSD$");
 
 #include <arm/allwinner/axp209reg.h>
 
-#include "iicbus_if.h"
 #include "gpio_if.h"
 #include "regdev_if.h"
 
@@ -602,7 +600,6 @@ enum AXP2XX_TYPE {
 
 struct axp2xx_softc {
 	device_t		dev;
-	uint32_t		addr;
 	struct resource *	res[1];
 	void *			intrcookie;
 	struct intr_config_hook	intr_hook;
@@ -641,57 +638,15 @@ static struct resource_spec axp_res_spec[] = {
 static int
 axp2xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
 {
-	struct axp2xx_softc *sc = device_get_softc(dev);
-	struct iic_msg msg[2];
 
-	msg[0].slave = sc->addr;
-	msg[0].flags = IIC_M_WR;
-	msg[0].len = 1;
-	msg[0].buf = &reg;
-
-	msg[1].slave = sc->addr;
-	msg[1].flags = IIC_M_RD;
-	msg[1].len = size;
-	msg[1].buf = data;
-
-	return (iicbus_transfer(dev, msg, 2));
+	return (iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT));
 }
 
 static int
 axp2xx_write(device_t dev, uint8_t reg, uint8_t data)
 {
-	uint8_t buffer[2];
-	struct axp2xx_softc *sc = device_get_softc(dev);
-	struct iic_msg msg[2];
-	int nmsgs = 0;
 
-	if (sc->type == AXP209) {
-		buffer[0] = reg;
-		buffer[1] = data;
-
-		msg[0].slave = sc->addr;
-		msg[0].flags = IIC_M_WR;
-		msg[0].len = 2;
-		msg[0].buf = buffer;
-
-		nmsgs = 1;
-	}
-	else if (sc->type == AXP221) {
-		msg[0].slave = sc->addr;
-		msg[0].flags = IIC_M_WR;
-		msg[0].len = 1;
-		msg[0].buf = &reg;
-
-		msg[1].slave = sc->addr;
-		msg[1].flags = IIC_M_WR;
-		msg[1].len = 1;
-		msg[1].buf = &data;
-		nmsgs = 2;
-	}
-	else
-		return (EINVAL);
-
-	return (iicbus_transfer(dev, msg, nmsgs));
+	return (iicdev_writeto(dev, reg, &data, sizeof(data), IIC_INTRWAIT));
 }
 
 static int
@@ -1239,7 +1194,6 @@ axp2xx_start(void *pdev)
 	dev = pdev;
 
 	sc = device_get_softc(dev);
-	sc->addr = iicbus_get_addr(dev);
 	sc->dev = dev;
 
 	if (bootverbose) {
@@ -1451,4 +1405,4 @@ EARLY_DRIVER_MODULE(ofw_gpiobus, axp2xx_pmu, ofw_gpiob
 DRIVER_MODULE(gpioc, axp2xx_pmu, gpioc_driver, gpioc_devclass,
     0, 0);
 MODULE_VERSION(axp2xx, 1);
-MODULE_DEPEND(axp2xx, iicbus, 1, 1, 1);
+MODULE_DEPEND(axp2xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);

Modified: stable/11/sys/conf/NOTES
==============================================================================
--- stable/11/sys/conf/NOTES	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/conf/NOTES	Mon Sep 11 22:21:15 2017	(r323467)
@@ -2567,15 +2567,14 @@ device		iicoc		# OpenCores I2C controller support
 
 # I2C peripheral devices
 #
-# ds133x	Dallas Semiconductor DS1337, DS1338 and DS1339 RTC
-# ds1374	Dallas Semiconductor DS1374 RTC
-# ds1672	Dallas Semiconductor DS1672 RTC
-# s35390a	Seiko Instruments S-35390A RTC
-#
-device		ds133x
-device		ds1374
-device		ds1672
-device		s35390a
+device		ds1307		# Dallas DS1307 RTC and compatible
+device		ds13rtc		# All Dallas/Maxim ds13xx chips
+device		ds1672		# Dallas DS1672 RTC
+device		ds3231		# Dallas DS3231 RTC + temperature
+device		icee		# AT24Cxxx and compatible EEPROMs
+device		lm75		# LM75 compatible temperature sensor
+device		nxprtc		# NXP RTCs: PCA/PFC212x PCA/PCF85xx
+device		s35390a		# Seiko Instruments S-35390A RTC
 
 # Parallel-Port Bus
 #

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/conf/files	Mon Sep 11 22:21:15 2017	(r323467)
@@ -1686,8 +1686,7 @@ dev/ie/if_ie.c			optional ie isa nowerror
 dev/ie/if_ie_isa.c		optional ie isa
 dev/iicbus/ad7418.c		optional ad7418
 dev/iicbus/ds1307.c		optional ds1307
-dev/iicbus/ds133x.c		optional ds133x
-dev/iicbus/ds1374.c		optional ds1374
+dev/iicbus/ds13rtc.c		optional ds13rtc | ds133x | ds1374
 dev/iicbus/ds1672.c		optional ds1672
 dev/iicbus/ds3231.c		optional ds3231
 dev/iicbus/icee.c		optional icee
@@ -1702,9 +1701,10 @@ dev/iicbus/iiconf.c		optional iicbus
 dev/iicbus/iicsmb.c		optional iicsmb				\
 	dependency	"iicbus_if.h"
 dev/iicbus/iicoc.c		optional iicoc
+dev/iicbus/isl12xx.c		optional isl12xx
 dev/iicbus/lm75.c		optional lm75
+dev/iicbus/nxprtc.c		optional nxprtc | pcf8563
 dev/iicbus/ofw_iicbus.c		optional fdt iicbus
-dev/iicbus/pcf8563.c		optional pcf8563
 dev/iicbus/s35390a.c		optional s35390a
 dev/iir/iir.c			optional iir
 dev/iir/iir_ctrl.c		optional iir

Modified: stable/11/sys/dev/iicbus/ds1307.c
==============================================================================
--- stable/11/sys/dev/iicbus/ds1307.c	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/dev/iicbus/ds1307.c	Mon Sep 11 22:21:15 2017	(r323467)
@@ -56,43 +56,36 @@ __FBSDID("$FreeBSD$");
 
 struct ds1307_softc {
 	device_t	sc_dev;
-	int		sc_year0;
-	struct intr_config_hook	enum_hook;
-	uint16_t	sc_addr;	/* DS1307 slave address. */
+	struct intr_config_hook
+			enum_hook;
 	uint8_t		sc_ctrl;
-	int		sc_mcp7941x;
+	bool		sc_mcp7941x;
+	bool		sc_use_ampm;
 };
 
 static void ds1307_start(void *);
 
 #ifdef FDT
 static const struct ofw_compat_data ds1307_compat_data[] = {
-    {"dallas,ds1307", (uintptr_t)"Maxim DS1307 RTC"},
-    {"maxim,ds1307", (uintptr_t)"Maxim DS1307 RTC"},
-    {"microchip,mcp7941x", (uintptr_t)"Microchip MCP7941x RTC"},
+    {"dallas,ds1307",		(uintptr_t)"Dallas DS1307 RTC"},
+    {"maxim,ds1307",		(uintptr_t)"Maxim DS1307 RTC"},
+    {"microchip,mcp7941x",	(uintptr_t)"Microchip MCP7941x RTC"},
     { NULL, 0 }
 };
 #endif
 
 static int
-ds1307_read(device_t dev, uint16_t addr, uint8_t reg, uint8_t *data, size_t len)
+ds1307_read1(device_t dev, uint8_t reg, uint8_t *data)
 {
-	struct iic_msg msg[2] = {
-	    { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
-	    { addr, IIC_M_RD, len, data },
-	};
 
-	return (iicbus_transfer(dev, msg, nitems(msg)));
+	return (iicdev_readfrom(dev, reg, data, 1, IIC_INTRWAIT));
 }
 
 static int
-ds1307_write(device_t dev, uint16_t addr, uint8_t *data, size_t len)
+ds1307_write1(device_t dev, uint8_t reg, uint8_t data)
 {
-	struct iic_msg msg[1] = {
-	    { addr, IIC_M_WR, len, data },
-	};
 
-	return (iicbus_transfer(dev, msg, nitems(msg)));
+	return (iicdev_writeto(dev, reg, &data, 1, IIC_INTRWAIT));
 }
 
 static int
@@ -101,8 +94,7 @@ ds1307_ctrl_read(struct ds1307_softc *sc)
 	int error;
 
 	sc->sc_ctrl = 0;
-	error = ds1307_read(sc->sc_dev, sc->sc_addr, DS1307_CONTROL,
-	    &sc->sc_ctrl, sizeof(sc->sc_ctrl));
+	error = ds1307_read1(sc->sc_dev, DS1307_CONTROL, &sc->sc_ctrl);
 	if (error) {
 		device_printf(sc->sc_dev, "cannot read from RTC.\n");
 		return (error);
@@ -115,11 +107,10 @@ static int
 ds1307_ctrl_write(struct ds1307_softc *sc)
 {
 	int error;
-	uint8_t data[2];
+	uint8_t ctrl;
 
-	data[0] = DS1307_CONTROL;
-	data[1] = sc->sc_ctrl & DS1307_CTRL_MASK;
-	error = ds1307_write(sc->sc_dev, sc->sc_addr, data, sizeof(data));
+	ctrl = sc->sc_ctrl & DS1307_CTRL_MASK;
+	error = ds1307_write1(sc->sc_dev, DS1307_CONTROL, ctrl);
 	if (error != 0)
 		device_printf(sc->sc_dev, "cannot write to RTC.\n");
 
@@ -127,54 +118,6 @@ ds1307_ctrl_write(struct ds1307_softc *sc)
 }
 
 static int
-ds1307_osc_enable(struct ds1307_softc *sc)
-{
-	int error;
-	uint8_t data[2], secs;
-
-	secs = 0;
-	error = ds1307_read(sc->sc_dev, sc->sc_addr, DS1307_SECS,
-	    &secs, sizeof(secs));
-	if (error) {
-		device_printf(sc->sc_dev, "cannot read from RTC.\n");
-		return (error);
-	}
-	/* Check if the oscillator is disabled. */
-	if ((secs & DS1307_SECS_CH) == 0)
-		return (0);
-	device_printf(sc->sc_dev, "clock was halted, check the battery.\n");
-	data[0] = DS1307_SECS;
-	data[1] = secs & DS1307_SECS_MASK;
-	error = ds1307_write(sc->sc_dev, sc->sc_addr, data, sizeof(data));
-	if (error != 0)
-		device_printf(sc->sc_dev, "cannot write to RTC.\n");
-
-	return (error);
-}
-
-static int
-ds1307_set_24hrs_mode(struct ds1307_softc *sc)
-{
-	int error;
-	uint8_t data[2], hour;
-
-	hour = 0;
-	error = ds1307_read(sc->sc_dev, sc->sc_addr, DS1307_HOUR,
-	    &hour, sizeof(hour));
-	if (error) {
-		device_printf(sc->sc_dev, "cannot read from RTC.\n");
-		return (error);
-	}
-	data[0] = DS1307_HOUR;
-	data[1] = hour & DS1307_HOUR_MASK;
-	error = ds1307_write(sc->sc_dev, sc->sc_addr, data, sizeof(data));
-	if (error != 0)
-		device_printf(sc->sc_dev, "cannot write to RTC.\n");
-
-	return (error);
-}
-
-static int
 ds1307_sqwe_sysctl(SYSCTL_HANDLER_ARGS)
 {
 	int sqwe, error, newv, sqwe_bit;
@@ -283,7 +226,7 @@ ds1307_probe(device_t dev)
 #else
 	device_set_desc(dev, "Maxim DS1307 RTC");
 
-	return (BUS_PROBE_DEFAULT);
+	return (BUS_PROBE_NOWILDCARD);
 #endif
 }
 
@@ -294,13 +237,13 @@ ds1307_attach(device_t dev)
 
 	sc = device_get_softc(dev);
 	sc->sc_dev = dev;
-	sc->sc_addr = iicbus_get_addr(dev);
-	sc->sc_year0 = 1900;
 	sc->enum_hook.ich_func = ds1307_start;
 	sc->enum_hook.ich_arg = dev;
 
+#ifdef FDT
 	if (ofw_bus_is_compatible(dev, "microchip,mcp7941x"))
 		sc->sc_mcp7941x = 1;
+#endif
 
 	/*
 	 * We have to wait until interrupts are enabled.  Usually I2C read
@@ -312,6 +255,14 @@ ds1307_attach(device_t dev)
 	return (0);
 }
 
+static int
+ds1307_detach(device_t dev)
+{
+
+	clock_unregister(dev);
+	return (0);
+}
+
 static void
 ds1307_start(void *xdev)
 {
@@ -320,6 +271,7 @@ ds1307_start(void *xdev)
 	struct sysctl_ctx_list *ctx;
 	struct sysctl_oid *tree_node;
 	struct sysctl_oid_list *tree;
+	uint8_t secs;
 
 	dev = (device_t)xdev;
 	sc = device_get_softc(dev);
@@ -328,12 +280,16 @@ ds1307_start(void *xdev)
 	tree = SYSCTL_CHILDREN(tree_node);
 
 	config_intrhook_disestablish(&sc->enum_hook);
-	/* Set the 24 hours mode. */
-	if (ds1307_set_24hrs_mode(sc) != 0)
+
+	/* Check if the oscillator is disabled. */
+	if (ds1307_read1(sc->sc_dev, DS1307_SECS, &secs) != 0) {
+		device_printf(sc->sc_dev, "cannot read from RTC.\n");
 		return;
-	/* Enable the oscillator if halted. */
-	if (ds1307_osc_enable(sc) != 0)
-		return;
+	}
+	if ((secs & DS1307_SECS_CH) != 0) {
+		device_printf(sc->sc_dev,
+		    "WARNING: RTC clock stopped, check the battery.\n");
+	}
 
 	/* Configuration parameters. */
 	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "sqwe",
@@ -347,8 +303,13 @@ ds1307_start(void *xdev)
 	    CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
 	    ds1307_sqw_out_sysctl, "IU", "DS1307 square-wave output state");
 
-	/* 1 second resolution. */
-	clock_register(dev, 1000000);
+	/*
+	 * Register as a clock with 1 second resolution.  Schedule the
+	 * clock_settime() method to be called just after top-of-second;
+	 * resetting the time resets top-of-second in the hardware.
+	 */
+	clock_register_flags(dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
+	clock_schedule(dev, 1);
 }
 
 static int
@@ -357,56 +318,85 @@ ds1307_gettime(device_t dev, struct timespec *ts)
 	int error;
 	struct clocktime ct;
 	struct ds1307_softc *sc;
-	uint8_t data[7];
+	uint8_t data[7], hourmask;
 
 	sc = device_get_softc(dev);
-	memset(data, 0, sizeof(data));
-	error = ds1307_read(sc->sc_dev, sc->sc_addr, DS1307_SECS,
-	    data, sizeof(data)); 
+	error = iicdev_readfrom(sc->sc_dev, DS1307_SECS, data, sizeof(data),
+	    IIC_INTRWAIT);
 	if (error != 0) {
 		device_printf(dev, "cannot read from RTC.\n");
 		return (error);
 	}
+
+	/* If the clock halted, we don't have good data. */
+	if (data[DS1307_SECS] & DS1307_SECS_CH)
+		return (EINVAL);
+
+	/* If chip is in AM/PM mode remember that. */
+	if (data[DS1307_HOUR] & DS1307_HOUR_USE_AMPM) {
+		sc->sc_use_ampm = true;
+		hourmask = DS1307_HOUR_MASK_12HR;
+	} 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] & DS1307_HOUR_MASK);
-	ct.day = FROMBCD(data[DS1307_DATE] & DS1307_DATE_MASK);
-	ct.dow = data[DS1307_WEEKDAY] & DS1307_WEEKDAY_MASK;
-	ct.mon = FROMBCD(data[DS1307_MONTH] & DS1307_MONTH_MASK);
-	ct.year = FROMBCD(data[DS1307_YEAR] & DS1307_YEAR_MASK);
-	ct.year += sc->sc_year0;
-	if (ct.year < POSIX_BASE_YEAR)
-		ct.year += 100;	/* assume [1970, 2069] */
+	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);
 
+	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));
 }
 
 static int
 ds1307_settime(device_t dev, struct timespec *ts)
 {
-	int error;
 	struct clocktime ct;
 	struct ds1307_softc *sc;
-	uint8_t data[8];
+	int error;
+	uint8_t data[7];
+	uint8_t pmflags;
 
 	sc = device_get_softc(dev);
-	/* Accuracy is only one second. */
-	if (ts->tv_nsec >= 500000000)
-		ts->tv_sec++;
-	ts->tv_nsec = 0;
+
+	/*
+	 * We request a timespec with no resolution-adjustment.  That also
+	 * disables utc adjustment, so apply that ourselves.
+	 */
+	ts->tv_sec -= utc_offset();
 	clock_ts_to_ct(ts, &ct);
-	memset(data, 0, sizeof(data));
-	data[0] = DS1307_SECS;
-	data[DS1307_SECS + 1] = TOBCD(ct.sec);
-	data[DS1307_MINS + 1] = TOBCD(ct.min);
-	data[DS1307_HOUR + 1] = TOBCD(ct.hour);
-	data[DS1307_DATE + 1] = TOBCD(ct.day);
-	data[DS1307_WEEKDAY + 1] = ct.dow;
-	data[DS1307_MONTH + 1] = TOBCD(ct.mon);
-	data[DS1307_YEAR + 1] = TOBCD(ct.year % 100);
+
+	/* 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;
+			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);
 	/* Write the time back to RTC. */
-	error = ds1307_write(dev, sc->sc_addr, data, sizeof(data));
+	error = iicdev_writeto(sc->sc_dev, DS1307_SECS, data, sizeof(data),
+	    IIC_INTRWAIT);
 	if (error != 0)
 		device_printf(dev, "cannot write to RTC.\n");
 
@@ -416,6 +406,7 @@ ds1307_settime(device_t dev, struct timespec *ts)
 static device_method_t ds1307_methods[] = {
 	DEVMETHOD(device_probe,		ds1307_probe),
 	DEVMETHOD(device_attach,	ds1307_attach),
+	DEVMETHOD(device_detach,	ds1307_detach),
 
 	DEVMETHOD(clock_gettime,	ds1307_gettime),
 	DEVMETHOD(clock_settime,	ds1307_settime),

Modified: stable/11/sys/dev/iicbus/ds1307reg.h
==============================================================================
--- stable/11/sys/dev/iicbus/ds1307reg.h	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/dev/iicbus/ds1307reg.h	Mon Sep 11 22:21:15 2017	(r323467)
@@ -39,7 +39,10 @@
 #define	DS1307_MINS		0x01
 #define	DS1307_MINS_MASK		0x7f
 #define	DS1307_HOUR		0x02
-#define	DS1307_HOUR_MASK		0x3f
+#define	DS1307_HOUR_MASK_12HR		0x1f
+#define	DS1307_HOUR_MASK_24HR		0x3f
+#define	DS1307_HOUR_IS_PM		0x20
+#define	DS1307_HOUR_USE_AMPM		0x40
 #define	DS1307_WEEKDAY		0x03
 #define	DS1307_WEEKDAY_MASK		0x07
 #define	DS1307_DATE		0x04

Copied and modified: stable/11/sys/dev/iicbus/ds13rtc.c (from r322473, head/sys/dev/iicbus/ds13rtc.c)
==============================================================================
--- head/sys/dev/iicbus/ds13rtc.c	Sun Aug 13 21:02:40 2017	(r322473, copy source)
+++ stable/11/sys/dev/iicbus/ds13rtc.c	Mon Sep 11 22:21:15 2017	(r323467)
@@ -495,7 +495,7 @@ ds13rtc_get_chiptype(device_t dev)
 	 * We can only attach if provided a chiptype hint string.
 	 */
 	if (resource_string_value(device_get_name(dev), 
-	    device_get_unit(dev), "chiptype", &htype) != 0)
+	    device_get_unit(dev), "compatible", &htype) != 0)
 		return (TYPE_NONE);
 
 	/*

Modified: stable/11/sys/dev/iicbus/ds3231.c
==============================================================================
--- stable/11/sys/dev/iicbus/ds3231.c	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/dev/iicbus/ds3231.c	Mon Sep 11 22:21:15 2017	(r323467)
@@ -62,29 +62,23 @@ struct ds3231_softc {
 	uint16_t	sc_addr;	/* DS3231 slave address. */
 	uint8_t		sc_ctrl;
 	uint8_t		sc_status;
+	bool		sc_use_ampm;
 };
 
 static void ds3231_start(void *);
 
 static int
-ds3231_read(device_t dev, uint16_t addr, uint8_t reg, uint8_t *data, size_t len)
+ds3231_read1(device_t dev, uint8_t reg, uint8_t *data)
 {
-	struct iic_msg msg[2] = {
-	    { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
-	    { addr, IIC_M_RD, len, data },
-	};
 
-	return (iicbus_transfer(dev, msg, nitems(msg)));
+	return (iicdev_readfrom(dev, reg, data, 1, IIC_INTRWAIT));
 }
 
 static int
-ds3231_write(device_t dev, uint16_t addr, uint8_t *data, size_t len)
+ds3231_write1(device_t dev, uint8_t reg, uint8_t data)
 {
-	struct iic_msg msg[1] = {
-	    { addr, IIC_M_WR, len, data },
-	};
 
-	return (iicbus_transfer(dev, msg, nitems(msg)));
+	return (iicdev_writeto(dev, reg, &data, 1, IIC_INTRWAIT));
 }
 
 static int
@@ -92,14 +86,11 @@ ds3231_ctrl_read(struct ds3231_softc *sc)
 {
 	int error;
 
-	sc->sc_ctrl = 0;
-	error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_CONTROL,
-	    &sc->sc_ctrl, sizeof(sc->sc_ctrl));
+	error = ds3231_read1(sc->sc_dev, DS3231_CONTROL, &sc->sc_ctrl);
 	if (error) {
 		device_printf(sc->sc_dev, "cannot read from RTC.\n");
 		return (error);
 	}
-
 	return (0);
 }
 
@@ -107,12 +98,11 @@ static int
 ds3231_ctrl_write(struct ds3231_softc *sc)
 {
 	int error;
-	uint8_t data[2];
+	uint8_t data;
 
-	data[0] = DS3231_CONTROL;
 	/* Always enable the oscillator.  Always disable both alarms. */
-	data[1] = sc->sc_ctrl & ~DS3231_CTRL_MASK;
-	error = ds3231_write(sc->sc_dev, sc->sc_addr, data, sizeof(data));
+	data = sc->sc_ctrl & ~DS3231_CTRL_MASK;
+	error = ds3231_write1(sc->sc_dev, DS3231_CONTROL, data);
 	if (error != 0)
 		device_printf(sc->sc_dev, "cannot write to RTC.\n");
 
@@ -124,9 +114,7 @@ ds3231_status_read(struct ds3231_softc *sc)
 {
 	int error;
 
-	sc->sc_status = 0;
-	error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_STATUS,
-	    &sc->sc_status, sizeof(sc->sc_status));
+	error = ds3231_read1(sc->sc_dev, DS3231_STATUS, &sc->sc_status);
 	if (error) {
 		device_printf(sc->sc_dev, "cannot read from RTC.\n");
 		return (error);
@@ -139,15 +127,14 @@ static int
 ds3231_status_write(struct ds3231_softc *sc, int clear_a1, int clear_a2)
 {
 	int error;
-	uint8_t data[2];
+	uint8_t data;
 
-	data[0] = DS3231_STATUS;
-	data[1] = sc->sc_status;
+	data = sc->sc_status;
 	if (clear_a1 == 0)
-		data[1] |= DS3231_STATUS_A1F;
+		data |= DS3231_STATUS_A1F;
 	if (clear_a2 == 0)
-		data[1] |= DS3231_STATUS_A2F;
-	error = ds3231_write(sc->sc_dev, sc->sc_addr, data, sizeof(data));
+		data |= DS3231_STATUS_A2F;
+	error = ds3231_write1(sc->sc_dev, DS3231_STATUS, data);
 	if (error != 0)
 		device_printf(sc->sc_dev, "cannot write to RTC.\n");
 
@@ -155,36 +142,14 @@ ds3231_status_write(struct ds3231_softc *sc, int clear
 }
 
 static int
-ds3231_set_24hrs_mode(struct ds3231_softc *sc)
-{
-	int error;
-	uint8_t data[2], hour;
-
-	hour = 0;
-	error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_HOUR,
-	    &hour, sizeof(hour));
-	if (error) {
-		device_printf(sc->sc_dev, "cannot read from RTC.\n");
-		return (error);
-	}
-	data[0] = DS3231_HOUR;
-	data[1] = hour & ~DS3231_C_MASK;
-	error = ds3231_write(sc->sc_dev, sc->sc_addr, data, sizeof(data));
-	if (error != 0)
-		device_printf(sc->sc_dev, "cannot write to RTC.\n");
-
-	return (error);
-}
-
-static int
 ds3231_temp_read(struct ds3231_softc *sc, int *temp)
 {
 	int error, neg, t;
 	uint8_t buf8[2];
 	uint16_t buf;
 
-	error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_TEMP,
-	    buf8, sizeof(buf8));
+	error = iicdev_readfrom(sc->sc_dev, DS3231_TEMP, buf8, sizeof(buf8),
+	    IIC_INTRWAIT);
 	if (error != 0)
 		return (error);
 	buf = (buf8[0] << 8) | (buf8[1] & 0xff);
@@ -426,6 +391,14 @@ ds3231_attach(device_t dev)
 	return (0);
 }
 
+static int
+ds3231_detach(device_t dev)
+{
+
+	clock_unregister(dev);
+	return (0);
+}
+
 static void
 ds3231_start(void *xdev)
 {
@@ -446,20 +419,20 @@ ds3231_start(void *xdev)
 		return;
 	if (ds3231_status_read(sc) != 0)
 		return;
-	/* Clear the OSF bit and ack any pending alarm interrupt. */
+	/*
+	 * Warn if the clock stopped, but don't restart it until the first
+	 * clock_settime() call.
+	 */
 	if (sc->sc_status & DS3231_STATUS_OSF) {
 		device_printf(sc->sc_dev,
-		    "oscillator has stopped, check the battery.\n");
-		sc->sc_status &= ~DS3231_STATUS_OSF;
+		    "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;
-	/* Set the 24 hours mode. */
-	if (ds3231_set_24hrs_mode(sc) != 0)
-		return;
 
 	/* Temperature. */
 	SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature",
@@ -485,8 +458,13 @@ ds3231_start(void *xdev)
 	    CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, sc, 0,
 	    ds3231_en32khz_sysctl, "IU", "DS3231 enable the 32kHz output");
 
-	/* 1 second resolution. */
-	clock_register(dev, 1000000);
+	/*
+	 * Register as a clock with 1 second resolution.  Schedule the
+	 * clock_settime() method to be called just after top-of-second;
+	 * resetting the time resets top-of-second in the hardware.
+	 */
+	clock_register_flags(dev, 1000000, CLOCKF_SETTIME_NO_ADJ);
+	clock_schedule(dev, 1);
 }
 
 static int
@@ -495,24 +473,45 @@ ds3231_gettime(device_t dev, struct timespec *ts)
 	int c, error;
 	struct clocktime ct;
 	struct ds3231_softc *sc;
-	uint8_t data[7];
+	uint8_t data[7], hourmask;
 
 	sc = device_get_softc(dev);
-	memset(data, 0, sizeof(data));
-	error = ds3231_read(sc->sc_dev, sc->sc_addr, DS3231_SECS,
-	    data, sizeof(data)); 
+
+	/* If the clock halted, we don't have good data. */
+	if ((error = ds3231_status_read(sc)) != 0) {
+		device_printf(dev, "cannot read from RTC.\n");
+		return (error);
+	}
+	if (sc->sc_status & DS3231_STATUS_OSF)
+		return (EINVAL);
+
+	error = iicdev_readfrom(sc->sc_dev, DS3231_SECS, data, sizeof(data),
+	    IIC_INTRWAIT);
 	if (error != 0) {
 		device_printf(dev, "cannot read from RTC.\n");
 		return (error);
 	}
+
+	/* If chip is in AM/PM mode remember that. */
+	if (data[DS3231_HOUR] & DS3231_HOUR_USE_AMPM) {
+		sc->sc_use_ampm = true;
+		hourmask = DS3231_HOUR_MASK_12HR;
+	} else
+		hourmask = DS3231_HOUR_MASK_24HR;
+
 	ct.nsec = 0;
-	ct.sec = FROMBCD(data[DS3231_SECS] & DS3231_SECS_MASK);
-	ct.min = FROMBCD(data[DS3231_MINS] & DS3231_MINS_MASK);
-	ct.hour = FROMBCD(data[DS3231_HOUR] & DS3231_HOUR_MASK);
-	ct.day = FROMBCD(data[DS3231_DATE] & DS3231_DATE_MASK);
-	ct.dow = data[DS3231_WEEKDAY] & DS3231_WEEKDAY_MASK;
-	ct.mon = FROMBCD(data[DS3231_MONTH] & DS3231_MONTH_MASK);
-	ct.year = FROMBCD(data[DS3231_YEAR] & DS3231_YEAR_MASK);
+	ct.sec  = FROMBCD(data[DS3231_SECS]  & DS3231_SECS_MASK);
+	ct.min  = FROMBCD(data[DS3231_MINS]  & DS3231_MINS_MASK);
+	ct.hour = FROMBCD(data[DS3231_HOUR]  & hourmask);
+	ct.day  = FROMBCD(data[DS3231_DATE]  & DS3231_DATE_MASK);
+	ct.mon  = FROMBCD(data[DS3231_MONTH] & DS3231_MONTH_MASK);
+	ct.year = FROMBCD(data[DS3231_YEAR]  & DS3231_YEAR_MASK);
+
+	/*
+	 * If the century flag has toggled since we last saw it, there has been
+	 * a century rollover.  If this is the first time we're seeing it,
+	 * remember the state so we can preserve its polarity on writes.
+	 */
 	c = (data[DS3231_MONTH] & DS3231_C_MASK) ? 1 : 0;
 	if (sc->sc_last_c == -1)
 		sc->sc_last_c = c;
@@ -524,6 +523,14 @@ ds3231_gettime(device_t dev, struct timespec *ts)
 	if (ct.year < POSIX_BASE_YEAR)
 		ct.year += 100;	/* assume [1970, 2069] */
 
+	/* If running in AM/PM mode, deal with it. */
+	if (sc->sc_use_ampm) {
+		if (ct.hour == 12)
+			ct.hour = 0;
+		if (data[DS3231_HOUR] & DS3231_HOUR_IS_PM)
+			ct.hour += 12;
+	}
+
 	return (clock_ct_to_ts(&ct, ts));
 }
 
@@ -533,36 +540,71 @@ ds3231_settime(device_t dev, struct timespec *ts)
 	int error;
 	struct clocktime ct;
 	struct ds3231_softc *sc;
-	uint8_t data[8];
+	uint8_t data[7];
+	uint8_t pmflags;
 
 	sc = device_get_softc(dev);
-	/* Accuracy is only one second. */
-	if (ts->tv_nsec >= 500000000)
-		ts->tv_sec++;
-	ts->tv_nsec = 0;
+
+	/*
+	 * We request a timespec with no resolution-adjustment.  That also
+	 * disables utc adjustment, so apply that ourselves.
+	 */
+	ts->tv_sec -= utc_offset();
 	clock_ts_to_ct(ts, &ct);
-	memset(data, 0, sizeof(data));
-	data[0] = DS3231_SECS;
-	data[DS3231_SECS + 1] = TOBCD(ct.sec);
-	data[DS3231_MINS + 1] = TOBCD(ct.min);
-	data[DS3231_HOUR + 1] = TOBCD(ct.hour);
-	data[DS3231_DATE + 1] = TOBCD(ct.day);
-	data[DS3231_WEEKDAY + 1] = ct.dow;
-	data[DS3231_MONTH + 1] = TOBCD(ct.mon);
-	data[DS3231_YEAR + 1] = TOBCD(ct.year % 100);
+
+	/* If the chip is in AM/PM mode, adjust hour and set flags as needed. */
+	if (sc->sc_use_ampm) {
+		pmflags = DS3231_HOUR_USE_AMPM;
+		if (ct.hour >= 12) {
+			ct.hour -= 12;
+			pmflags |= DS3231_HOUR_IS_PM;
+		}
+		if (ct.hour == 0)
+			ct.hour = 12;
+	} else
+		pmflags = 0;
+
+	data[DS3231_SECS]    = TOBCD(ct.sec);
+	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_MONTH]   = TOBCD(ct.mon);
+	data[DS3231_YEAR]    = TOBCD(ct.year % 100);
 	if (sc->sc_last_c)
 		data[DS3231_MONTH] |= DS3231_C_MASK;
+
 	/* Write the time back to RTC. */
-	error = ds3231_write(dev, sc->sc_addr, data, sizeof(data));
-	if (error != 0)
+	error = iicdev_writeto(dev, DS3231_SECS, data, sizeof(data),
+	    IIC_INTRWAIT);
+	if (error != 0) {
 		device_printf(dev, "cannot write to RTC.\n");
+		return (error);
+	}
 
+	/*
+	 * Unlike most hardware, the osc-was-stopped bit does not clear itself
+	 * after setting the time, it has to be manually written to zero.
+	 */
+	if (sc->sc_status & DS3231_STATUS_OSF) {
+		if ((error = ds3231_status_read(sc)) != 0) {
+			device_printf(dev, "cannot read from RTC.\n");
+			return (error);
+		}
+		sc->sc_status &= ~DS3231_STATUS_OSF;
+		if ((error = ds3231_status_write(sc, 0, 0)) != 0) {
+			device_printf(dev, "cannot write to RTC.\n");
+			return (error);
+		}
+	}
+
 	return (error);
 }
 
 static device_method_t ds3231_methods[] = {
 	DEVMETHOD(device_probe,		ds3231_probe),
 	DEVMETHOD(device_attach,	ds3231_attach),
+	DEVMETHOD(device_detach,	ds3231_detach),
 
 	DEVMETHOD(clock_gettime,	ds3231_gettime),
 	DEVMETHOD(clock_settime,	ds3231_settime),

Modified: stable/11/sys/dev/iicbus/ds3231reg.h
==============================================================================
--- stable/11/sys/dev/iicbus/ds3231reg.h	Mon Sep 11 22:18:01 2017	(r323466)
+++ stable/11/sys/dev/iicbus/ds3231reg.h	Mon Sep 11 22:21:15 2017	(r323467)
@@ -38,7 +38,10 @@
 #define	DS3231_MINS		0x01
 #define	DS3231_MINS_MASK		0x7f
 #define	DS3231_HOUR		0x02
-#define	DS3231_HOUR_MASK		0x3f
+#define	DS3231_HOUR_MASK_12HR		0x3f
+#define	DS3231_HOUR_MASK_24HR		0x1f
+#define	DS3231_HOUR_IS_PM		0x20
+#define	DS3231_HOUR_USE_AMPM		0x40
 #define	DS3231_WEEKDAY		0x03
 #define	DS3231_WEEKDAY_MASK		0x07
 #define	DS3231_DATE		0x04

Copied: stable/11/sys/dev/iicbus/isl12xx.c (from r321841, head/sys/dev/iicbus/isl12xx.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/sys/dev/iicbus/isl12xx.c	Mon Sep 11 22:21:15 2017	(r323467, copy of r321841, head/sys/dev/iicbus/isl12xx.c)
@@ -0,0 +1,354 @@
+/*-
+ * Copyright (c) 2017 Ian Lepore.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Driver for ISL12xx family i2c realtime clocks:
+ *  - ISL1209 = 2B sram, tamper/event timestamp
+ *  - ISL1218 = 8B sram, DS13xx pin compatible (but not software compatible)
+ *  - ISL1219 = 2B sram, tamper/event timestamp
+ *  - ISL1220 = 8B sram, separate Fout
+ *  - ISL1221 = 2B sram, separate Fout, tamper/event timestamp
+ *
+ * This driver supports only the basic RTC functionality in all these chips.
+ */
+
+#include "opt_platform.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/sx.h>
+
+#ifdef FDT
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "clock_if.h"
+#include "iicbus_if.h"
+
+/*
+ * All register and bit names as found in the datasheet.  When a bit name ends
+ * in 'B' that stands for "bar" and it is an active-low signal; something named
+ * "EVENB" implies 1=event-disable, 0=event-enable.
+ */
+
+#define	ISL12XX_SC_REG		0x00		/* RTC Seconds */
+
+#define	ISL12XX_SR_REG		0x07		/* Status */
+#define	  ISL12XX_SR_ARST	  (1u << 7)	/*   Auto-reset on status read */
+#define	  ISL12XX_SR_XTOSCB	  (1u << 5)	/*   Osc disable (use ext osc) */
+#define	  ISL12XX_SR_WRTC	  (1u << 4)	/*   Write RTC enable */
+#define	  ISL12XX_SR_EVT	  (1u << 3)	/*   Event occurred (w0c) */
+#define	  ISL12XX_SR_ALM	  (1u << 2)	/*   Alarm occurred (w0c) */
+#define	  ISL12XX_SR_BAT	  (1u << 1)	/*   Running on battery (w0c) */
+#define	  ISL12XX_SR_RTCF	  (1u << 0)	/*   RTC fail (power loss) */
+#define	  ISL12XX_SR_W0C_BITS (ISL12XX_SR_BAT | ISL12XX_SR_ALM | ISL12XX_SR_EVT)
+
+#define	ISL12XX_INT_REG		0x08		/* Interrupts */
+#define	  ISL12XX_INT_IM	  (1u << 7)	/*   Alarm interrupt mode */
+#define	  ISL12XX_INT_ALME	  (1u << 6)	/*   Alarm enable */
+#define	  ISL12XX_INT_LPMODE	  (1u << 5)	/*   Low Power mode */
+#define	  ISL12XX_INT_FOBATB	  (1u << 4)	/*   Fout/IRQ disabled on bat */
+#define	  ISL12XX_INT_FO_SHIFT	  0		/*   Frequency output select */
+#define	  ISL12XX_INT_FO_MASK	  0x0f		/*   shift and mask. */
+
+#define	ISL12XX_EV_REG		0x09		/* Event */
+#define	  ISL12XX_EV_EVIENB	  (1u << 7)	/*   Disable internal pullup */
+#define	  ISL12XX_EV_EVBATB	  (1u << 6)	/*   Disable ev detect on bat */
+#define	  ISL12XX_EV_RTCHLT	  (1u << 5)	/*   Halt RTC on event */
+#define	  ISL12XX_EV_EVEN	  (1u << 4)	/*   Event detect enable */
+#define	  ISL12XX_EV_EHYS_SHIFT	  2		/*   Event input hysteresis */
+#define	  ISL12XX_EV_EHYS_MASK	  0x03		/*   selection; see datasheet */
+#define	  ISL12XX_EV_ESMP_SHIFT	  0		/*   Event input sample rate */
+#define	  ISL12XX_EV_ESMP_MASK	  0x03		/*   selection; see datasheet */
+
+#define	ISL12XX_ATR_REG		0x0a		/* Analog trim (osc adjust) */
+
+#define	ISL12XX_DTR_REG		0x0b		/* Digital trim (osc adjust) */
+
+#define	ISL12XX_SCA_REG		0x0c		/* Alarm seconds */
+
+#define	ISL12XX_USR1_REG	0x12		/* User byte 1 */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709112221.v8BMLFoV061582>