aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/rtc/rtc-ds1307.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 75e30c6a7d5d..5306a1a5b873 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -52,6 +52,7 @@ I2C_CLIENT_INSMOD;
52/* RTC registers don't differ much, except for the century flag */ 52/* RTC registers don't differ much, except for the century flag */
53#define DS1307_REG_SECS 0x00 /* 00-59 */ 53#define DS1307_REG_SECS 0x00 /* 00-59 */
54# define DS1307_BIT_CH 0x80 54# define DS1307_BIT_CH 0x80
55# define DS1340_BIT_nEOSC 0x80
55#define DS1307_REG_MIN 0x01 /* 00-59 */ 56#define DS1307_REG_MIN 0x01 /* 00-59 */
56#define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */ 57#define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */
57# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */ 58# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */
@@ -68,7 +69,7 @@ I2C_CLIENT_INSMOD;
68 */ 69 */
69#define DS1307_REG_CONTROL 0x07 /* or ds1338 */ 70#define DS1307_REG_CONTROL 0x07 /* or ds1338 */
70# define DS1307_BIT_OUT 0x80 71# define DS1307_BIT_OUT 0x80
71# define DS1338_BIT_STOP 0x20 72# define DS1338_BIT_OSF 0x20
72# define DS1307_BIT_SQWE 0x10 73# define DS1307_BIT_SQWE 0x10
73# define DS1307_BIT_RS1 0x02 74# define DS1307_BIT_RS1 0x02
74# define DS1307_BIT_RS0 0x01 75# define DS1307_BIT_RS0 0x01
@@ -84,8 +85,8 @@ I2C_CLIENT_INSMOD;
84# define DS1340_BIT_FT 0x40 85# define DS1340_BIT_FT 0x40
85# define DS1340_BIT_CALIB_SIGN 0x20 86# define DS1340_BIT_CALIB_SIGN 0x20
86# define DS1340_M_CALIBRATION 0x1f 87# define DS1340_M_CALIBRATION 0x1f
87#define DS1338_REG_FLAG 0x09 88#define DS1340_REG_FLAG 0x09
88# define DS1338_BIT_OSF 0x80 89# define DS1340_BIT_OSF 0x80
89#define DS1337_REG_STATUS 0x0f 90#define DS1337_REG_STATUS 0x0f
90# define DS1337_BIT_OSF 0x80 91# define DS1337_BIT_OSF 0x80
91# define DS1337_BIT_A2I 0x02 92# define DS1337_BIT_A2I 0x02
@@ -215,11 +216,18 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
215 tmp = t->tm_year - 100; 216 tmp = t->tm_year - 100;
216 buf[DS1307_REG_YEAR] = BIN2BCD(tmp); 217 buf[DS1307_REG_YEAR] = BIN2BCD(tmp);
217 218
218 if (ds1307->type == ds_1337) 219 switch (ds1307->type) {
220 case ds_1337:
221 case ds_1339:
219 buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY; 222 buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
220 else if (ds1307->type == ds_1340) 223 break;
224 case ds_1340:
221 buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN 225 buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN
222 | DS1340_BIT_CENTURY; 226 | DS1340_BIT_CENTURY;
227 break;
228 default:
229 break;
230 }
223 231
224 ds1307->msg[1].flags = 0; 232 ds1307->msg[1].flags = 0;
225 ds1307->msg[1].len = 8; 233 ds1307->msg[1].len = 8;
@@ -296,11 +304,10 @@ ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
296 switch (ds1307->type) { 304 switch (ds1307->type) {
297 case ds_1337: 305 case ds_1337:
298 case ds_1339: 306 case ds_1339:
299 ds1307->type = ds_1337;
300
301 ds1307->reg_addr = DS1337_REG_CONTROL; 307 ds1307->reg_addr = DS1337_REG_CONTROL;
302 ds1307->msg[1].len = 2; 308 ds1307->msg[1].len = 2;
303 309
310 /* get registers that the "rtc" read below won't read... */
304 tmp = i2c_transfer(adapter, ds1307->msg, 2); 311 tmp = i2c_transfer(adapter, ds1307->msg, 2);
305 if (tmp != 2) { 312 if (tmp != 2) {
306 pr_debug("read error %d\n", tmp); 313 pr_debug("read error %d\n", tmp);
@@ -311,13 +318,16 @@ ds1307_detect(struct i2c_adapter *adapter, int address, int kind)
311 ds1307->reg_addr = 0; 318 ds1307->reg_addr = 0;
312 ds1307->msg[1].len = sizeof(ds1307->regs); 319 ds1307->msg[1].len = sizeof(ds1307->regs);
313 320
314 /* oscillator is off; need to turn it on */ 321 /* oscillator off? turn it on, so clock can tick. */
315 if ((ds1307->regs[0] & DS1337_BIT_nEOSC) 322 if (ds1307->regs[0] & DS1337_BIT_nEOSC)
316 || (ds1307->regs[1] & DS1337_BIT_OSF)) { 323 i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
317no_osc_start: 324 ds1307->regs[0] & ~DS1337_BIT_nEOSC);
318 printk(KERN_ERR "no %s oscillator code\n", 325
319 chip->name); 326 /* oscillator fault? clear flag, and warn */
320 goto exit_free; 327 if (ds1307->regs[1] & DS1337_BIT_OSF) {
328 i2c_smbus_write_byte_data(client, DS1337_REG_STATUS,
329 ds1307->regs[1] & ~DS1337_BIT_OSF);
330 dev_warn(&client->dev, "SET TIME!\n");
321 } 331 }
322 break; 332 break;
323 default: 333 default:
@@ -340,20 +350,33 @@ read_rtc:
340 */ 350 */
341 tmp = ds1307->regs[DS1307_REG_SECS]; 351 tmp = ds1307->regs[DS1307_REG_SECS];
342 switch (ds1307->type) { 352 switch (ds1307->type) {
353 case ds_1340:
354 /* FIXME read register with DS1340_BIT_OSF, use that to
355 * trigger the "set time" warning (*after* restarting the
356 * oscillator!) instead of this weaker ds1307/m41t00 test.
357 */
343 case ds_1307: 358 case ds_1307:
344 case ds_1338:
345 case m41t00: 359 case m41t00:
360 /* clock halted? turn it on, so clock can tick. */
346 if (tmp & DS1307_BIT_CH) { 361 if (tmp & DS1307_BIT_CH) {
347 i2c_smbus_write_byte_data(client, 0, 0); 362 i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
348 dev_warn(&client->dev, 363 dev_warn(&client->dev, "SET TIME!\n");
349 "oscillator started; SET TIME!\n");
350 goto read_rtc; 364 goto read_rtc;
351 } 365 }
352 break; 366 break;
353 case ds_1340: 367 case ds_1338:
354 /* FIXME write code to start the oscillator */ 368 /* clock halted? turn it on, so clock can tick. */
355 if (tmp & DS1307_BIT_CH) 369 if (tmp & DS1307_BIT_CH)
356 goto no_osc_start; 370 i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0);
371
372 /* oscillator fault? clear flag, and warn */
373 if (ds1307->regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
374 i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL,
375 ds1307->regs[DS1337_REG_CONTROL]
376 & ~DS1338_BIT_OSF);
377 dev_warn(&client->dev, "SET TIME!\n");
378 goto read_rtc;
379 }
357 break; 380 break;
358 default: 381 default:
359 break; 382 break;
@@ -380,6 +403,7 @@ read_rtc:
380 * 403 *
381 * REVISIT forcing 24 hour mode can prevent multi-master 404 * REVISIT forcing 24 hour mode can prevent multi-master
382 * configs from sharing this RTC ... don't do this. 405 * configs from sharing this RTC ... don't do this.
406 * The clock needs to be reset after changing it, too...
383 */ 407 */
384 tmp = ds1307->regs[DS1307_REG_HOUR]; 408 tmp = ds1307->regs[DS1307_REG_HOUR];
385 if (tmp & (1 << 6)) { 409 if (tmp & (1 << 6)) {