diff options
Diffstat (limited to 'drivers/i2c/chips/ds1337.c')
-rw-r--r-- | drivers/i2c/chips/ds1337.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 02682fb794c8..93d483b8b770 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c | |||
@@ -52,9 +52,9 @@ static int ds1337_command(struct i2c_client *client, unsigned int cmd, | |||
52 | * Driver data (common to all clients) | 52 | * Driver data (common to all clients) |
53 | */ | 53 | */ |
54 | static struct i2c_driver ds1337_driver = { | 54 | static struct i2c_driver ds1337_driver = { |
55 | .owner = THIS_MODULE, | 55 | .driver = { |
56 | .name = "ds1337", | 56 | .name = "ds1337", |
57 | .flags = I2C_DF_NOTIFY, | 57 | }, |
58 | .attach_adapter = ds1337_attach_adapter, | 58 | .attach_adapter = ds1337_attach_adapter, |
59 | .detach_client = ds1337_detach_client, | 59 | .detach_client = ds1337_detach_client, |
60 | .command = ds1337_command, | 60 | .command = ds1337_command, |
@@ -337,13 +337,38 @@ exit: | |||
337 | 337 | ||
338 | static void ds1337_init_client(struct i2c_client *client) | 338 | static void ds1337_init_client(struct i2c_client *client) |
339 | { | 339 | { |
340 | s32 val; | 340 | u8 status, control; |
341 | 341 | ||
342 | /* Ensure that device is set in 24-hour mode */ | 342 | /* On some boards, the RTC isn't configured by boot firmware. |
343 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | 343 | * Handle that case by starting/configuring the RTC now. |
344 | if ((val >= 0) && (val & (1 << 6))) | 344 | */ |
345 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | 345 | status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); |
346 | val & 0x3f); | 346 | control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); |
347 | |||
348 | if ((status & 0x80) || (control & 0x80)) { | ||
349 | /* RTC not running */ | ||
350 | u8 buf[16]; | ||
351 | struct i2c_msg msg[1]; | ||
352 | |||
353 | dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__); | ||
354 | |||
355 | /* Initialize all, including STATUS and CONTROL to zero */ | ||
356 | memset(buf, 0, sizeof(buf)); | ||
357 | msg[0].addr = client->addr; | ||
358 | msg[0].flags = 0; | ||
359 | msg[0].len = sizeof(buf); | ||
360 | msg[0].buf = &buf[0]; | ||
361 | |||
362 | i2c_transfer(client->adapter, msg, 1); | ||
363 | } else { | ||
364 | /* Running: ensure that device is set in 24-hour mode */ | ||
365 | s32 val; | ||
366 | |||
367 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | ||
368 | if ((val >= 0) && (val & (1 << 6))) | ||
369 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | ||
370 | val & 0x3f); | ||
371 | } | ||
347 | } | 372 | } |
348 | 373 | ||
349 | static int ds1337_detach_client(struct i2c_client *client) | 374 | static int ds1337_detach_client(struct i2c_client *client) |