Module Name:    src
Committed By:   aymeric
Date:           Tue Oct 18 18:54:54 UTC 2016

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

Log Message:
add support for the MCP7940 based Pi Face Real Time Clock


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/dev/i2c/ds1307.c
cvs rdiff -u -r1.7 -r1.8 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.23 src/sys/dev/i2c/ds1307.c:1.24
--- src/sys/dev/i2c/ds1307.c:1.23	Tue Oct  4 15:06:59 2016
+++ src/sys/dev/i2c/ds1307.c	Tue Oct 18 18:54:54 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ds1307.c,v 1.23 2016/10/04 15:06:59 kiyohara Exp $	*/
+/*	$NetBSD: ds1307.c,v 1.24 2016/10/18 18:54:54 aymeric Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.23 2016/10/04 15:06:59 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.24 2016/10/18 18:54:54 aymeric Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,14 +57,19 @@ struct dsrtc_model {
 	uint16_t dm_model;
 	uint8_t dm_ch_reg;
 	uint8_t dm_ch_value;
+	uint8_t dm_vbaten_reg;
+	uint8_t dm_vbaten_value;
 	uint8_t dm_rtc_start;
 	uint8_t dm_rtc_size;
 	uint8_t dm_nvram_start;
 	uint8_t dm_nvram_size;
 	uint8_t dm_flags;
-#define	DSRTC_FLAG_CLOCK_HOLD	1
-#define	DSRTC_FLAG_BCD		2	
-#define	DSRTC_FLAG_TEMP		4	
+#define	DSRTC_FLAG_CLOCK_HOLD		0x01
+#define	DSRTC_FLAG_BCD			0x02
+#define	DSRTC_FLAG_TEMP			0x04
+#define DSRTC_FLAG_VBATEN		0x08
+#define	DSRTC_FLAG_YEAR_START_2K	0x10
+#define	DSRTC_FLAG_CLOCK_HOLD_REVERSED	0x20
 };
 
 static const struct dsrtc_model dsrtc_models[] = {
@@ -113,6 +118,19 @@ static const struct dsrtc_model dsrtc_mo
 		.dm_nvram_start = DS3232_NVRAM_START,
 		.dm_nvram_size = DS3232_NVRAM_SIZE,
 		.dm_flags = DSRTC_FLAG_BCD,
+	}, {
+		/* MCP7940 */
+		.dm_model = 7940,
+		.dm_rtc_start = DS1307_RTC_START,
+		.dm_rtc_size = DS1307_RTC_SIZE,
+		.dm_ch_reg = DSXXXX_SECONDS,
+		.dm_ch_value = DS1307_SECONDS_CH,
+		.dm_vbaten_reg = DSXXXX_DAY,
+		.dm_vbaten_value = MCP7940_TOD_DAY_VBATEN,
+		.dm_nvram_start = MCP7940_NVRAM_START,
+		.dm_nvram_size = MCP7940_NVRAM_SIZE,
+		.dm_flags = DSRTC_FLAG_BCD | DSRTC_FLAG_CLOCK_HOLD |
+			DSRTC_FLAG_VBATEN | DSRTC_FLAG_CLOCK_HOLD_REVERSED,
 	},
 };
 
@@ -193,7 +211,7 @@ dsrtc_match(device_t parent, cfdata_t cf
 			return 1;
 	} else {
 		/* indirect config - check typical address */
-		if (ia->ia_addr == DS1307_ADDR)
+		if (ia->ia_addr == DS1307_ADDR || ia->ia_addr == MCP7940_ADDR)
 			return dsrtc_model(cf->cf_flags & 0xffff) != NULL;
 	}
 	return 0;
@@ -457,9 +475,13 @@ dsrtc_clock_read_ymdhms(struct dsrtc_sof
 	dt->dt_mon = bcdtobin(bcd[DSXXXX_MONTH] & DSXXXX_MONTH_MASK);
 
 	/* XXX: Should be an MD way to specify EPOCH used by BIOS/Firmware */
-	dt->dt_year = bcdtobin(bcd[DSXXXX_YEAR]) + POSIX_BASE_YEAR;
-	if (bcd[DSXXXX_MONTH] & DSXXXX_MONTH_CENTURY)
-		dt->dt_year += 100;
+	if (sc->sc_model.dm_flags & DSRTC_FLAG_YEAR_START_2K)
+		dt->dt_year = bcdtobin(bcd[DSXXXX_YEAR]) + 2000;
+	else {
+		dt->dt_year = bcdtobin(bcd[DSXXXX_YEAR]) + POSIX_BASE_YEAR;
+		if (bcd[DSXXXX_MONTH] & DSXXXX_MONTH_CENTURY)
+			dt->dt_year += 100;
+	}
 
 	return 1;
 }
@@ -506,7 +528,10 @@ dsrtc_clock_write_ymdhms(struct dsrtc_so
 		return 0;
 	}
 
-	cmdbuf[1] |= dm->dm_ch_value;
+	if (sc->sc_model.dm_flags & DSRTC_FLAG_CLOCK_HOLD_REVERSED)
+		cmdbuf[1] &= ~dm->dm_ch_value;
+	else
+		cmdbuf[1] |= dm->dm_ch_value;
 
 	if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address,
 	    cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) != 0) {
@@ -524,8 +549,13 @@ dsrtc_clock_write_ymdhms(struct dsrtc_so
 	uint8_t op = I2C_OP_WRITE;
 	for (signed int i = dm->dm_rtc_size - 1; i >= 0; i--) {
 		cmdbuf[0] = dm->dm_rtc_start + i;
+		if ((dm->dm_flags & DSRTC_FLAG_VBATEN) &&
+				dm->dm_rtc_start + i == dm->dm_vbaten_reg)
+			bcd[i] |= dm->dm_vbaten_value;
 		if (dm->dm_rtc_start + i == dm->dm_ch_reg) {
 			op = I2C_OP_WRITE_WITH_STOP;
+			if (dm->dm_flags & DSRTC_FLAG_CLOCK_HOLD_REVERSED)
+				bcd[i] |= dm->dm_ch_value;
 		}
 		if ((error = iic_exec(sc->sc_tag, op, sc->sc_address,
 		    cmdbuf, 1, &bcd[i], 1, I2C_F_POLL)) != 0) {
@@ -543,7 +573,10 @@ dsrtc_clock_write_ymdhms(struct dsrtc_so
 	 */
 	if (op != I2C_OP_WRITE_WITH_STOP) {
 		cmdbuf[0] = dm->dm_ch_reg;
-		cmdbuf[1] &= ~dm->dm_ch_value;
+		if (dm->dm_flags & DSRTC_FLAG_CLOCK_HOLD_REVERSED)
+			cmdbuf[1] |= dm->dm_ch_value;
+		else
+			cmdbuf[1] &= ~dm->dm_ch_value;
 
 		if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
 		    sc->sc_address, cmdbuf, 1, &cmdbuf[1], 1,

Index: src/sys/dev/i2c/ds1307reg.h
diff -u src/sys/dev/i2c/ds1307reg.h:1.7 src/sys/dev/i2c/ds1307reg.h:1.8
--- src/sys/dev/i2c/ds1307reg.h:1.7	Tue Oct  4 15:06:59 2016
+++ src/sys/dev/i2c/ds1307reg.h	Tue Oct 18 18:54:54 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ds1307reg.h,v 1.7 2016/10/04 15:06:59 kiyohara Exp $	*/
+/*	$NetBSD: ds1307reg.h,v 1.8 2016/10/18 18:54:54 aymeric Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -43,6 +43,7 @@
  */
 
 #define	DS1307_ADDR		0x68	/* Fixed I2C Slave Address */
+#define	MCP7940_ADDR		0x6f
 
 #define DSXXXX_SECONDS		0x00
 #define DSXXXX_MINUTES		0x01
@@ -91,6 +92,8 @@
 #define	DS3232_NVRAM_START	0x14
 #define	DS3232_NVRAM_SIZE	0xec
 
+#define	MCP7940_NVRAM_START	0x20
+#define	MCP7940_NVRAM_SIZE	0x40
 
 /*
  * Bit definitions.
@@ -116,4 +119,6 @@
 
 #define	DSXXXX_CONTROL_DOSC	(1u << 7)	/* Disable Oscillator */
 
+#define	MCP7940_TOD_DAY_VBATEN	(1u << 3)	/* Enable battery backup */
+
 #endif /* _DEV_I2C_DS1307REG_H_ */

Reply via email to