From khali@linux-fr.org Mon Nov 7 13:30:27 2005 Date: Mon, 7 Nov 2005 22:30:14 +0100 From: Jean Delvare To: Greg KH Cc: Michael Burian , James Chapman Subject: [PATCH] i2c: Extend ds1337 initialization Message-Id: <20051107223014.1af97872.khali@linux-fr.org> Content-Disposition: inline; filename=i2c-ds1337-init.patch From: Michael Burian Add code to handle case where board firmware does not start the RTC. Signed-off-by: Jean Delvare CC: James Chapman Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/ds1337.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) --- gregkh-2.6.orig/drivers/i2c/chips/ds1337.c +++ gregkh-2.6/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)