summaryrefslogtreecommitdiff
path: root/drivers/rtc/ds1307.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/ds1307.c')
-rw-r--r--drivers/rtc/ds1307.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
index 2015ce9bbc..3be97c9d93 100644
--- a/drivers/rtc/ds1307.c
+++ b/drivers/rtc/ds1307.c
@@ -43,11 +43,21 @@ enum ds_type {
#define RTC_SEC_BIT_CH 0x80 /* Clock Halt (in Register 0) */
+/* DS1307-specific bits */
#define RTC_CTL_BIT_RS0 0x01 /* Rate select 0 */
#define RTC_CTL_BIT_RS1 0x02 /* Rate select 1 */
#define RTC_CTL_BIT_SQWE 0x10 /* Square Wave Enable */
#define RTC_CTL_BIT_OUT 0x80 /* Output Control */
+/* DS1337-specific bits */
+#define DS1337_CTL_BIT_RS1 0x08 /* Rate select 1 */
+#define DS1337_CTL_BIT_RS2 0x10 /* Rate select 2 */
+#define DS1337_CTL_BIT_EOSC 0x80 /* Enable Oscillator */
+
+/* DS1340-specific bits */
+#define DS1340_SEC_BIT_EOSC 0x80 /* Enable Oscillator */
+#define DS1340_CTL_BIT_OUT 0x80 /* Output Control */
+
/* MCP7941X-specific bits */
#define MCP7941X_BIT_ST 0x80
#define MCP7941X_BIT_VBATEN 0x08
@@ -261,9 +271,25 @@ read_rtc:
buf[RTC_SEC_REG_ADDR]);
return -1;
}
- }
-
- if (type == m41t11) {
+ } else if (type == ds_1337) {
+ if (buf[RTC_CTL_REG_ADDR] & DS1337_CTL_BIT_EOSC) {
+ printf("### Warning: RTC oscillator has stopped\n");
+ /* clear the not oscillator enable (~EOSC) flag */
+ buf[RTC_CTL_REG_ADDR] &= ~DS1337_CTL_BIT_EOSC;
+ dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ buf[RTC_CTL_REG_ADDR]);
+ return -1;
+ }
+ } else if (type == ds_1340) {
+ if (buf[RTC_SEC_REG_ADDR] & DS1340_SEC_BIT_EOSC) {
+ printf("### Warning: RTC oscillator has stopped\n");
+ /* clear the not oscillator enable (~EOSC) flag */
+ buf[RTC_SEC_REG_ADDR] &= ~DS1340_SEC_BIT_EOSC;
+ dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR,
+ buf[RTC_SEC_REG_ADDR]);
+ return -1;
+ }
+ } else if (type == m41t11) {
/* clock halted? turn it on, so clock can tick. */
if (buf[RTC_SEC_REG_ADDR] & RTC_SEC_BIT_CH) {
buf[RTC_SEC_REG_ADDR] &= ~RTC_SEC_BIT_CH;
@@ -273,9 +299,7 @@ read_rtc:
buf[RTC_SEC_REG_ADDR]);
goto read_rtc;
}
- }
-
- if (type == mcp794xx) {
+ } else if (type == mcp794xx) {
/* make sure that the backup battery is enabled */
if (!(buf[RTC_DAY_REG_ADDR] & MCP7941X_BIT_VBATEN)) {
dm_i2c_reg_write(dev, RTC_DAY_REG_ADDR,
@@ -314,18 +338,37 @@ read_rtc:
static int ds1307_rtc_reset(struct udevice *dev)
{
int ret;
+ enum ds_type type = dev_get_driver_data(dev);
- /* clear Clock Halt */
+ /*
+ * reset clock/oscillator in the seconds register:
+ * on DS1307 bit 7 enables Clock Halt (CH),
+ * on DS1340 bit 7 disables the oscillator (not EOSC)
+ * on MCP794xx bit 7 enables Start Oscillator (ST)
+ */
ret = dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, 0x00);
if (ret < 0)
return ret;
- ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
- RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 |
- RTC_CTL_BIT_RS0);
- if (ret < 0)
- return ret;
- return 0;
+ if (type == ds_1307) {
+ /* Write control register in order to enable square-wave
+ * output (SQWE) and set a default rate of 32.768kHz (RS1|RS0).
+ */
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 |
+ RTC_CTL_BIT_RS0);
+ } else if (type == ds_1337) {
+ /* Write control register in order to enable oscillator output
+ * (not EOSC) and set a default rate of 32.768kHz (RS2|RS1).
+ */
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ DS1337_CTL_BIT_RS2 | DS1337_CTL_BIT_RS1);
+ } else if (type == ds_1340 || type == mcp794xx || type == m41t11) {
+ /* Reset clock calibration, frequency test and output level. */
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR, 0x00);
+ }
+
+ return ret;
}
static int ds1307_probe(struct udevice *dev)