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_ */