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>
This commit is contained in:
Matthias Fuchs
2009-03-31 15:24:58 -07:00
committed by Linus Torvalds
parent 30e7b039b1
commit a216685818
2 changed files with 84 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
*
* Copyright (C) 2005 James Chapman (ds1337 core)
* Copyright (C) 2006 David Brownell
* Copyright (C) 2009 Matthias Fuchs (rx8025 support)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,6 +32,7 @@ enum ds_type {
ds_1339,
ds_1340,
m41t00,
rx_8025,
// rs5c372 too? different address...
};
@@ -83,6 +85,12 @@ enum ds_type {
#define DS1339_REG_ALARM1_SECS 0x07
#define DS1339_REG_TRICKLE 0x10
#define RX8025_REG_CTRL1 0x0e
# define RX8025_BIT_2412 0x20
#define RX8025_REG_CTRL2 0x0f
# define RX8025_BIT_PON 0x10
# define RX8025_BIT_VDET 0x40
# define RX8025_BIT_XST 0x20
struct ds1307 {
@@ -121,6 +129,8 @@ static const struct chip_desc chips[] = {
[ds_1340] = {
},
[m41t00] = {
},
[rx_8025] = {
}, };
static const struct i2c_device_id ds1307_id[] = {
@@ -130,6 +140,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1340", ds_1340 },
{ "m41t00", m41t00 },
{ "rx8025", rx_8025 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
@@ -674,6 +685,72 @@ static int __devinit ds1307_probe(struct i2c_client *client,
dev_warn(&client->dev, "SET TIME!\n");
}
break;
case rx_8025:
tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
if (tmp != 2) {
pr_debug("read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
/* oscillator off? turn it on, so clock can tick. */
if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
ds1307->regs[1] |= RX8025_BIT_XST;
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL2 << 4 | 0x08,
ds1307->regs[1]);
dev_warn(&client->dev,
"oscillator stop detected - SET TIME!\n");
}
if (ds1307->regs[1] & RX8025_BIT_PON) {
ds1307->regs[1] &= ~RX8025_BIT_PON;
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL2 << 4 | 0x08,
ds1307->regs[1]);
dev_warn(&client->dev, "power-on detected\n");
}
if (ds1307->regs[1] & RX8025_BIT_VDET) {
ds1307->regs[1] &= ~RX8025_BIT_VDET;
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL2 << 4 | 0x08,
ds1307->regs[1]);
dev_warn(&client->dev, "voltage drop detected\n");
}
/* make sure we are running in 24hour mode */
if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
u8 hour;
/* switch to 24 hour mode */
i2c_smbus_write_byte_data(client,
RX8025_REG_CTRL1 << 4 | 0x08,
ds1307->regs[0] |
RX8025_BIT_2412);
tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
if (tmp != 2) {
pr_debug("read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
/* correct hour */
hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
if (hour == 12)
hour = 0;
if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
hour += 12;
i2c_smbus_write_byte_data(client,
DS1307_REG_HOUR << 4 | 0x08,
hour);
}
break;
default:
break;
}
@@ -734,6 +811,7 @@ read_rtc:
dev_warn(&client->dev, "SET TIME!\n");
}
break;
case rx_8025:
case ds_1337:
case ds_1339:
break;
@@ -747,6 +825,8 @@ read_rtc:
* systems that will run through year 2100.
*/
break;
case rx_8025:
break;
default:
if (!(tmp & DS1307_BIT_12HR))
break;