summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/chips/ds1337.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 02682fb794c..18228957606 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -337,13 +337,38 @@ exit:
static void ds1337_init_client(struct i2c_client *client)
{
- s32 val;
+ u8 status, control;
- /* Ensure that device is set in 24-hour mode */
- val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
- if ((val >= 0) && (val & (1 << 6)))
- i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
- val & 0x3f);
+ /* On some boards, the RTC isn't configured by boot firmware.
+ * Handle that case by starting/configuring the RTC now.
+ */
+ status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
+ control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+
+ if ((status & 0x80) || (control & 0x80)) {
+ /* RTC not running */
+ u8 buf[16];
+ struct i2c_msg msg[1];
+
+ dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
+
+ /* Initialize all, including STATUS and CONTROL to zero */
+ memset(buf, 0, sizeof(buf));
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = sizeof(buf);
+ msg[0].buf = &buf[0];
+
+ i2c_transfer(client->adapter, msg, 1);
+ } else {
+ /* Running: ensure that device is set in 24-hour mode */
+ s32 val;
+
+ val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
+ if ((val >= 0) && (val & (1 << 6)))
+ i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
+ val & 0x3f);
+ }
}
static int ds1337_detach_client(struct i2c_client *client)