aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds1307.c
diff options
context:
space:
mode:
authorMatthias Fuchs <matthias.fuchs@esd-electronics.com>2009-03-31 18:24:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:25 -0400
commita216685818a54b4f15235068b53908f954850251 (patch)
treec44c65ac4c71637e088e3527b8ef55eaa6938552 /drivers/rtc/rtc-ds1307.c
parent30e7b039b1f9a6d5a4e50df5469a4f347ea1aa77 (diff)
rtc: add EPSON RX8025 support to DS1307 RTC driver
Add support for the EPSON RX8025 RTC. The date/time registers of this chip are compatible with the DS1307. Signed-off-by: Matthias Fuchs <matthias.fuchs@esd-electronics.com> Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-ds1307.c')
-rw-r--r--drivers/rtc/rtc-ds1307.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 1c975e6439b3..2c4a65302a9d 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2005 James Chapman (ds1337 core) 4 * Copyright (C) 2005 James Chapman (ds1337 core)
5 * Copyright (C) 2006 David Brownell 5 * Copyright (C) 2006 David Brownell
6 * Copyright (C) 2009 Matthias Fuchs (rx8025 support)
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -31,6 +32,7 @@ enum ds_type {
31 ds_1339, 32 ds_1339,
32 ds_1340, 33 ds_1340,
33 m41t00, 34 m41t00,
35 rx_8025,
34 // rs5c372 too? different address... 36 // rs5c372 too? different address...
35}; 37};
36 38
@@ -83,6 +85,12 @@ enum ds_type {
83#define DS1339_REG_ALARM1_SECS 0x07 85#define DS1339_REG_ALARM1_SECS 0x07
84#define DS1339_REG_TRICKLE 0x10 86#define DS1339_REG_TRICKLE 0x10
85 87
88#define RX8025_REG_CTRL1 0x0e
89# define RX8025_BIT_2412 0x20
90#define RX8025_REG_CTRL2 0x0f
91# define RX8025_BIT_PON 0x10
92# define RX8025_BIT_VDET 0x40
93# define RX8025_BIT_XST 0x20
86 94
87 95
88struct ds1307 { 96struct ds1307 {
@@ -121,6 +129,8 @@ static const struct chip_desc chips[] = {
121[ds_1340] = { 129[ds_1340] = {
122}, 130},
123[m41t00] = { 131[m41t00] = {
132},
133[rx_8025] = {
124}, }; 134}, };
125 135
126static const struct i2c_device_id ds1307_id[] = { 136static const struct i2c_device_id ds1307_id[] = {
@@ -130,6 +140,7 @@ static const struct i2c_device_id ds1307_id[] = {
130 { "ds1339", ds_1339 }, 140 { "ds1339", ds_1339 },
131 { "ds1340", ds_1340 }, 141 { "ds1340", ds_1340 },
132 { "m41t00", m41t00 }, 142 { "m41t00", m41t00 },
143 { "rx8025", rx_8025 },
133 { } 144 { }
134}; 145};
135MODULE_DEVICE_TABLE(i2c, ds1307_id); 146MODULE_DEVICE_TABLE(i2c, ds1307_id);
@@ -674,6 +685,72 @@ static int __devinit ds1307_probe(struct i2c_client *client,
674 dev_warn(&client->dev, "SET TIME!\n"); 685 dev_warn(&client->dev, "SET TIME!\n");
675 } 686 }
676 break; 687 break;
688
689 case rx_8025:
690 tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
691 RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
692 if (tmp != 2) {
693 pr_debug("read error %d\n", tmp);
694 err = -EIO;
695 goto exit_free;
696 }
697
698 /* oscillator off? turn it on, so clock can tick. */
699 if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
700 ds1307->regs[1] |= RX8025_BIT_XST;
701 i2c_smbus_write_byte_data(client,
702 RX8025_REG_CTRL2 << 4 | 0x08,
703 ds1307->regs[1]);
704 dev_warn(&client->dev,
705 "oscillator stop detected - SET TIME!\n");
706 }
707
708 if (ds1307->regs[1] & RX8025_BIT_PON) {
709 ds1307->regs[1] &= ~RX8025_BIT_PON;
710 i2c_smbus_write_byte_data(client,
711 RX8025_REG_CTRL2 << 4 | 0x08,
712 ds1307->regs[1]);
713 dev_warn(&client->dev, "power-on detected\n");
714 }
715
716 if (ds1307->regs[1] & RX8025_BIT_VDET) {
717 ds1307->regs[1] &= ~RX8025_BIT_VDET;
718 i2c_smbus_write_byte_data(client,
719 RX8025_REG_CTRL2 << 4 | 0x08,
720 ds1307->regs[1]);
721 dev_warn(&client->dev, "voltage drop detected\n");
722 }
723
724 /* make sure we are running in 24hour mode */
725 if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
726 u8 hour;
727
728 /* switch to 24 hour mode */
729 i2c_smbus_write_byte_data(client,
730 RX8025_REG_CTRL1 << 4 | 0x08,
731 ds1307->regs[0] |
732 RX8025_BIT_2412);
733
734 tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
735 RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
736 if (tmp != 2) {
737 pr_debug("read error %d\n", tmp);
738 err = -EIO;
739 goto exit_free;
740 }
741
742 /* correct hour */
743 hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
744 if (hour == 12)
745 hour = 0;
746 if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
747 hour += 12;
748
749 i2c_smbus_write_byte_data(client,
750 DS1307_REG_HOUR << 4 | 0x08,
751 hour);
752 }
753 break;
677 default: 754 default:
678 break; 755 break;
679 } 756 }
@@ -734,6 +811,7 @@ read_rtc:
734 dev_warn(&client->dev, "SET TIME!\n"); 811 dev_warn(&client->dev, "SET TIME!\n");
735 } 812 }
736 break; 813 break;
814 case rx_8025:
737 case ds_1337: 815 case ds_1337:
738 case ds_1339: 816 case ds_1339:
739 break; 817 break;
@@ -747,6 +825,8 @@ read_rtc:
747 * systems that will run through year 2100. 825 * systems that will run through year 2100.
748 */ 826 */
749 break; 827 break;
828 case rx_8025:
829 break;
750 default: 830 default:
751 if (!(tmp & DS1307_BIT_12HR)) 831 if (!(tmp & DS1307_BIT_12HR))
752 break; 832 break;