diff options
author | Matthias Fuchs <matthias.fuchs@esd-electronics.com> | 2009-03-31 18:24:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 11:59:25 -0400 |
commit | a216685818a54b4f15235068b53908f954850251 (patch) | |
tree | c44c65ac4c71637e088e3527b8ef55eaa6938552 /drivers | |
parent | 30e7b039b1f9a6d5a4e50df5469a4f347ea1aa77 (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')
-rw-r--r-- | drivers/rtc/Kconfig | 7 | ||||
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 80 |
2 files changed, 84 insertions, 3 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index d669b9169278..09d5cd33a3f6 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -129,13 +129,14 @@ comment "I2C RTC drivers" | |||
129 | if I2C | 129 | if I2C |
130 | 130 | ||
131 | config RTC_DRV_DS1307 | 131 | config RTC_DRV_DS1307 |
132 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" | 132 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" |
133 | help | 133 | help |
134 | If you say yes here you get support for various compatible RTC | 134 | If you say yes here you get support for various compatible RTC |
135 | chips (often with battery backup) connected with I2C. This driver | 135 | chips (often with battery backup) connected with I2C. This driver |
136 | should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, | 136 | should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, |
137 | and probably other chips. In some cases the RTC must already | 137 | EPSON RX-8025 and probably other chips. In some cases the RTC |
138 | have been initialized (by manufacturing or a bootloader). | 138 | must already have been initialized (by manufacturing or a |
139 | bootloader). | ||
139 | 140 | ||
140 | The first seven registers on these chips hold an RTC, and other | 141 | The first seven registers on these chips hold an RTC, and other |
141 | registers may add features such as NVRAM, a trickle charger for | 142 | registers may add features such as NVRAM, a trickle charger for |
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 | ||
88 | struct ds1307 { | 96 | struct 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 | ||
126 | static const struct i2c_device_id ds1307_id[] = { | 136 | static 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 | }; |
135 | MODULE_DEVICE_TABLE(i2c, ds1307_id); | 146 | MODULE_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; |