forked from luck/tmp_suning_uos_patched
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:
parent
30e7b039b1
commit
a216685818
|
@ -129,13 +129,14 @@ comment "I2C RTC drivers"
|
|||
if I2C
|
||||
|
||||
config RTC_DRV_DS1307
|
||||
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
|
||||
tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
|
||||
help
|
||||
If you say yes here you get support for various compatible RTC
|
||||
chips (often with battery backup) connected with I2C. This driver
|
||||
should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
|
||||
and probably other chips. In some cases the RTC must already
|
||||
have been initialized (by manufacturing or a bootloader).
|
||||
EPSON RX-8025 and probably other chips. In some cases the RTC
|
||||
must already have been initialized (by manufacturing or a
|
||||
bootloader).
|
||||
|
||||
The first seven registers on these chips hold an RTC, and other
|
||||
registers may add features such as NVRAM, a trickle charger for
|
||||
|
|
|
@ -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 @@ static int __devinit ds1307_probe(struct i2c_client *client,
|
|||
dev_warn(&client->dev, "SET TIME!\n");
|
||||
}
|
||||
break;
|
||||
case rx_8025:
|
||||
case ds_1337:
|
||||
case ds_1339:
|
||||
break;
|
||||
|
@ -747,6 +825,8 @@ static int __devinit ds1307_probe(struct i2c_client *client,
|
|||
* systems that will run through year 2100.
|
||||
*/
|
||||
break;
|
||||
case rx_8025:
|
||||
break;
|
||||
default:
|
||||
if (!(tmp & DS1307_BIT_12HR))
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user