summaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds1307.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ds1307.c')
-rw-r--r--drivers/rtc/rtc-ds1307.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 8e1c5cb6ece6..4e31036ee259 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -186,6 +186,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "mcp7941x", mcp794xx },
{ "pt7c4338", ds_1307 },
{ "rx8025", rx_8025 },
+ { "isl12057", ds_1337 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
@@ -382,10 +383,25 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
-
- /* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
+#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
+ switch (ds1307->type) {
+ case ds_1337:
+ case ds_1339:
+ case ds_3231:
+ if (ds1307->regs[DS1307_REG_MONTH] & DS1337_BIT_CENTURY)
+ t->tm_year += 100;
+ break;
+ case ds_1340:
+ if (ds1307->regs[DS1307_REG_HOUR] & DS1340_BIT_CENTURY)
+ t->tm_year += 100;
+ break;
+ default:
+ break;
+ }
+#endif
+
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"read", t->tm_sec, t->tm_min,
@@ -409,6 +425,27 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
+#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
+ if (t->tm_year < 100)
+ return -EINVAL;
+
+ switch (ds1307->type) {
+ case ds_1337:
+ case ds_1339:
+ case ds_3231:
+ case ds_1340:
+ if (t->tm_year > 299)
+ return -EINVAL;
+ default:
+ if (t->tm_year > 199)
+ return -EINVAL;
+ break;
+ }
+#else
+ if (t->tm_year < 100 || t->tm_year > 199)
+ return -EINVAL;
+#endif
+
buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
@@ -424,11 +461,13 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
case ds_1337:
case ds_1339:
case ds_3231:
- buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
+ if (t->tm_year > 199)
+ buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
break;
case ds_1340:
- buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
- | DS1340_BIT_CENTURY;
+ buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN;
+ if (t->tm_year > 199)
+ buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY;
break;
case mcp794xx:
/*
@@ -1295,6 +1334,11 @@ static int ds1307_probe(struct i2c_client *client,
if (of_property_read_bool(client->dev.of_node, "wakeup-source")) {
ds1307_can_wakeup_device = true;
}
+ /* Intersil ISL12057 DT backward compatibility */
+ if (of_property_read_bool(client->dev.of_node,
+ "isil,irq2-can-wakeup-machine")) {
+ ds1307_can_wakeup_device = true;
+ }
#endif
switch (ds1307->type) {