diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1307.c')
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 80 |
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 | ||
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; |