[PATCH] i2c: Extend ds1337 initialization
authorMichael Burian <dynmail1@gassner-waagen.at>
Mon, 7 Nov 2005 21:30:14 +0000 (22:30 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 6 Jan 2006 06:16:20 +0000 (22:16 -0800)
Add code to handle case where board firmware does not start the
RTC.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
CC: James Chapman <jchapman@katalix.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/i2c/chips/ds1337.c

index 02682fb794c8366007d33be29d0d03f0a9d55cda..18228957606cf55918dfe5e769ac24055e0b7fb6 100644 (file)
@@ -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)