Module Name:    src
Committed By:   macallan
Date:           Sun Oct 12 01:23:23 UTC 2014

Modified Files:
        src/sys/dev/i2c: ds1307.c ds1307reg.h

Log Message:
- support DS3231 ( more or less a DS3232 without NVRAM it seems )
- support the DS3231's temperature sensor


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/sys/dev/i2c/ds1307.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/i2c/ds1307reg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/i2c/ds1307.c
diff -u src/sys/dev/i2c/ds1307.c:1.18 src/sys/dev/i2c/ds1307.c:1.19
--- src/sys/dev/i2c/ds1307.c:1.18	Fri Jul 25 08:10:37 2014
+++ src/sys/dev/i2c/ds1307.c	Sun Oct 12 01:23:23 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ds1307.c,v 1.18 2014/07/25 08:10:37 dholland Exp $	*/
+/*	$NetBSD: ds1307.c,v 1.19 2014/10/12 01:23:23 macallan Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.18 2014/07/25 08:10:37 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.19 2014/10/12 01:23:23 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1
 
 #include <dev/i2c/i2cvar.h>
 #include <dev/i2c/ds1307reg.h>
+#include <dev/sysmon/sysmonvar.h>
 
 struct dsrtc_model {
 	uint16_t dm_model;
@@ -63,6 +64,7 @@ struct dsrtc_model {
 	uint8_t dm_flags;
 #define	DSRTC_FLAG_CLOCK_HOLD	1
 #define	DSRTC_FLAG_BCD		2	
+#define	DSRTC_FLAG_TEMP		4	
 };
 
 static const struct dsrtc_model dsrtc_models[] = {
@@ -86,6 +88,16 @@ static const struct dsrtc_model dsrtc_mo
 		.dm_rtc_size = DS1672_RTC_SIZE,
 		.dm_flags = 0,
 	}, {
+		.dm_model = 3231,
+		.dm_rtc_start = DS3232_RTC_START,
+		.dm_rtc_size = DS3232_RTC_SIZE,
+		/*
+		 * XXX
+		 * the DS3232 likely has the temperature sensor too but I can't
+		 * easily verify or test that right now
+		 */
+		.dm_flags = DSRTC_FLAG_BCD | DSRTC_FLAG_TEMP,
+	}, {
 		.dm_model = 3232,
 		.dm_rtc_start = DS3232_RTC_START,
 		.dm_rtc_size = DS3232_RTC_SIZE,
@@ -102,6 +114,8 @@ struct dsrtc_softc {
 	bool sc_open;
 	struct dsrtc_model sc_model;
 	struct todr_chip_handle sc_todr;
+	struct sysmon_envsys *sc_sme;
+	envsys_data_t sc_sensor;
 };
 
 static void	dsrtc_attach(device_t, device_t, void *);
@@ -141,6 +155,9 @@ static int dsrtc_settime_timeval(struct 
 static int dsrtc_clock_read_timeval(struct dsrtc_softc *, time_t *);
 static int dsrtc_clock_write_timeval(struct dsrtc_softc *, time_t);
 
+static int dsrtc_read_temp(struct dsrtc_softc *, uint32_t *);
+static void dsrtc_refresh(struct sysmon_envsys *, envsys_data_t *);
+
 static const struct dsrtc_model *
 dsrtc_model(u_int model)
 {
@@ -202,6 +219,35 @@ dsrtc_attach(device_t parent, device_t s
 	sc->sc_todr.todr_setwen = NULL;
 
 	todr_attach(&sc->sc_todr);
+	if ((sc->sc_model.dm_flags & DSRTC_FLAG_TEMP) != 0) {
+		int error;
+
+		sc->sc_sme = sysmon_envsys_create();
+		sc->sc_sme->sme_name = device_xname(self);
+		sc->sc_sme->sme_cookie = sc;
+		sc->sc_sme->sme_refresh = dsrtc_refresh;
+
+		sc->sc_sensor.units =  ENVSYS_STEMP;
+		sc->sc_sensor.state = ENVSYS_SINVALID;
+		sc->sc_sensor.flags = 0;
+		(void)strlcpy(sc->sc_sensor.desc, "temperature",
+		    sizeof(sc->sc_sensor.desc));
+
+		if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor)) {
+			aprint_error_dev(self, "unable to attach sensor\n");
+			goto bad;
+		}
+
+		error = sysmon_envsys_register(sc->sc_sme);
+		if (error) {
+			aprint_error_dev(self, 
+			    "error %d registering with sysmon\n", error);
+			goto bad;
+		}
+	}
+	return;
+bad:
+	sysmon_envsys_destroy(sc->sc_sme);
 }
 
 /*ARGSUSED*/
@@ -624,3 +670,56 @@ dsrtc_clock_write_timeval(struct dsrtc_s
 
 	return 1;
 }
+
+static int
+dsrtc_read_temp(struct dsrtc_softc *sc, uint32_t *temp)
+{
+	int error, tc;
+	uint8_t reg = DS3232_TEMP_MSB;
+	uint8_t buf[2];
+
+	if ((sc->sc_model.dm_flags & DSRTC_FLAG_TEMP) == 0)
+		return ENOTSUP;
+
+	if ((error = iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) != 0) {
+		aprint_error_dev(sc->sc_dev,
+		    "%s: failed to acquire I2C bus: %d\n",
+		    __func__, error);
+		return 0;
+	}
+
+	/* read temperature registers: */
+	error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address,
+	     &reg, 1, buf, 2, I2C_F_POLL);
+
+	/* Done with I2C */
+	iic_release_bus(sc->sc_tag, I2C_F_POLL);
+
+	if (error != 0) {
+		aprint_error_dev(sc->sc_dev,
+		    "%s: failed to read temperature: %d\n",
+		    __func__, error);
+		return 0;
+	}
+
+	/* convert to microkelvin */
+	tc = buf[0] * 1000000 + (buf[1] >> 6) * 250000;
+	*temp = tc + 273150000;
+	return 1;
+}
+
+static void
+dsrtc_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
+{
+	struct dsrtc_softc *sc = sme->sme_cookie;
+	uint32_t temp;
+
+	if (dsrtc_read_temp(sc, &temp) == 0) {
+		edata->state = ENVSYS_SINVALID;
+		return;
+	}
+
+	edata->value_cur = temp;
+
+	edata->state = ENVSYS_SVALID;
+}

Index: src/sys/dev/i2c/ds1307reg.h
diff -u src/sys/dev/i2c/ds1307reg.h:1.4 src/sys/dev/i2c/ds1307reg.h:1.5
--- src/sys/dev/i2c/ds1307reg.h:1.4	Thu Feb 23 20:59:19 2012
+++ src/sys/dev/i2c/ds1307reg.h	Sun Oct 12 01:23:23 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ds1307reg.h,v 1.4 2012/02/23 20:59:19 matt Exp $	*/
+/*	$NetBSD: ds1307reg.h,v 1.5 2014/10/12 01:23:23 macallan Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -81,6 +81,8 @@
 #define DS3232_CSR		0x0f
 #define	DS3232_RTC_START	0
 #define	DS3232_RTC_SIZE		DSXXXX_RTC_SIZE
+#define DS3232_TEMP_MSB		0x11
+#define DS3232_TEMP_LSB		0x12
 #define	DS3232_NVRAM_START	0x14
 #define	DS3232_NVRAM_SIZE	0xec
 

Reply via email to