diff options
author | BARRE Sebastien <sbarre@sdelcc.com> | 2009-01-07 21:07:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 11:30:59 -0500 |
commit | fed40b734c343d4e4acf4b46f186bc3d69271867 (patch) | |
tree | 645f62949e73c87789f7a5b9ab04cb9e9ba52302 /drivers/rtc/rtc-ds1307.c | |
parent | 1107ba885e46964316c083d441d5dd185b6c9e49 (diff) |
rtc-ds1307: SMBus compatibility
Change i2c access functions to SMBus access functions in order to use the
ds1307 with SMBus adapter.
Signed-off-by: Sebastien Barre <sbarre@sdelcc.com>
Acked-by: David Brownell <david-b@pacbell.net>
Tested-by: David Brownell <david-b@pacbell.net>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Acked-by: Jean Delvare <khali@linux-fr.org>
Cc: Rodolfo Giometti <giometti@enneenne.com>
Tested-by: Sebastien Barre <sbarre@sdelcc.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-ds1307.c')
-rw-r--r-- | drivers/rtc/rtc-ds1307.c | 123 |
1 files changed, 35 insertions, 88 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 162330b9d1dc..fec13e7d48ef 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -86,13 +86,11 @@ enum ds_type { | |||
86 | 86 | ||
87 | 87 | ||
88 | struct ds1307 { | 88 | struct ds1307 { |
89 | u8 reg_addr; | ||
90 | u8 regs[11]; | 89 | u8 regs[11]; |
91 | enum ds_type type; | 90 | enum ds_type type; |
92 | unsigned long flags; | 91 | unsigned long flags; |
93 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ | 92 | #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ |
94 | #define HAS_ALARM 1 /* bit 1 == irq claimed */ | 93 | #define HAS_ALARM 1 /* bit 1 == irq claimed */ |
95 | struct i2c_msg msg[2]; | ||
96 | struct i2c_client *client; | 94 | struct i2c_client *client; |
97 | struct rtc_device *rtc; | 95 | struct rtc_device *rtc; |
98 | struct work_struct work; | 96 | struct work_struct work; |
@@ -204,13 +202,9 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) | |||
204 | int tmp; | 202 | int tmp; |
205 | 203 | ||
206 | /* read the RTC date and time registers all at once */ | 204 | /* read the RTC date and time registers all at once */ |
207 | ds1307->reg_addr = 0; | 205 | tmp = i2c_smbus_read_i2c_block_data(ds1307->client, |
208 | ds1307->msg[1].flags = I2C_M_RD; | 206 | DS1307_REG_SECS, 7, ds1307->regs); |
209 | ds1307->msg[1].len = 7; | 207 | if (tmp != 7) { |
210 | |||
211 | tmp = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent), | ||
212 | ds1307->msg, 2); | ||
213 | if (tmp != 2) { | ||
214 | dev_err(dev, "%s error %d\n", "read", tmp); | 208 | dev_err(dev, "%s error %d\n", "read", tmp); |
215 | return -EIO; | 209 | return -EIO; |
216 | } | 210 | } |
@@ -257,7 +251,6 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
257 | t->tm_hour, t->tm_mday, | 251 | t->tm_hour, t->tm_mday, |
258 | t->tm_mon, t->tm_year, t->tm_wday); | 252 | t->tm_mon, t->tm_year, t->tm_wday); |
259 | 253 | ||
260 | *buf++ = 0; /* first register addr */ | ||
261 | buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec); | 254 | buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec); |
262 | buf[DS1307_REG_MIN] = bin2bcd(t->tm_min); | 255 | buf[DS1307_REG_MIN] = bin2bcd(t->tm_min); |
263 | buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); | 256 | buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); |
@@ -282,18 +275,14 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
282 | break; | 275 | break; |
283 | } | 276 | } |
284 | 277 | ||
285 | ds1307->msg[1].flags = 0; | ||
286 | ds1307->msg[1].len = 8; | ||
287 | |||
288 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", | 278 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n", |
289 | "write", buf[0], buf[1], buf[2], buf[3], | 279 | "write", buf[0], buf[1], buf[2], buf[3], |
290 | buf[4], buf[5], buf[6]); | 280 | buf[4], buf[5], buf[6]); |
291 | 281 | ||
292 | result = i2c_transfer(to_i2c_adapter(ds1307->client->dev.parent), | 282 | result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf); |
293 | &ds1307->msg[1], 1); | 283 | if (result < 0) { |
294 | if (result != 1) { | 284 | dev_err(dev, "%s error %d\n", "write", result); |
295 | dev_err(dev, "%s error %d\n", "write", tmp); | 285 | return result; |
296 | return -EIO; | ||
297 | } | 286 | } |
298 | return 0; | 287 | return 0; |
299 | } | 288 | } |
@@ -308,13 +297,9 @@ static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
308 | return -EINVAL; | 297 | return -EINVAL; |
309 | 298 | ||
310 | /* read all ALARM1, ALARM2, and status registers at once */ | 299 | /* read all ALARM1, ALARM2, and status registers at once */ |
311 | ds1307->reg_addr = DS1339_REG_ALARM1_SECS; | 300 | ret = i2c_smbus_read_i2c_block_data(client, |
312 | ds1307->msg[1].flags = I2C_M_RD; | 301 | DS1339_REG_ALARM1_SECS, 9, ds1307->regs); |
313 | ds1307->msg[1].len = 9; | 302 | if (ret != 9) { |
314 | |||
315 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
316 | ds1307->msg, 2); | ||
317 | if (ret != 2) { | ||
318 | dev_err(dev, "%s error %d\n", "alarm read", ret); | 303 | dev_err(dev, "%s error %d\n", "alarm read", ret); |
319 | return -EIO; | 304 | return -EIO; |
320 | } | 305 | } |
@@ -371,13 +356,9 @@ static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
371 | t->enabled, t->pending); | 356 | t->enabled, t->pending); |
372 | 357 | ||
373 | /* read current status of both alarms and the chip */ | 358 | /* read current status of both alarms and the chip */ |
374 | ds1307->reg_addr = DS1339_REG_ALARM1_SECS; | 359 | ret = i2c_smbus_read_i2c_block_data(client, |
375 | ds1307->msg[1].flags = I2C_M_RD; | 360 | DS1339_REG_ALARM1_SECS, 9, buf); |
376 | ds1307->msg[1].len = 9; | 361 | if (ret != 9) { |
377 | |||
378 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
379 | ds1307->msg, 2); | ||
380 | if (ret != 2) { | ||
381 | dev_err(dev, "%s error %d\n", "alarm write", ret); | 362 | dev_err(dev, "%s error %d\n", "alarm write", ret); |
382 | return -EIO; | 363 | return -EIO; |
383 | } | 364 | } |
@@ -392,7 +373,6 @@ static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
392 | ds1307->regs[6], control, status); | 373 | ds1307->regs[6], control, status); |
393 | 374 | ||
394 | /* set ALARM1, using 24 hour and day-of-month modes */ | 375 | /* set ALARM1, using 24 hour and day-of-month modes */ |
395 | *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */ | ||
396 | buf[0] = bin2bcd(t->time.tm_sec); | 376 | buf[0] = bin2bcd(t->time.tm_sec); |
397 | buf[1] = bin2bcd(t->time.tm_min); | 377 | buf[1] = bin2bcd(t->time.tm_min); |
398 | buf[2] = bin2bcd(t->time.tm_hour); | 378 | buf[2] = bin2bcd(t->time.tm_hour); |
@@ -411,14 +391,11 @@ static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
411 | } | 391 | } |
412 | buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); | 392 | buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); |
413 | 393 | ||
414 | ds1307->msg[1].flags = 0; | 394 | ret = i2c_smbus_write_i2c_block_data(client, |
415 | ds1307->msg[1].len = 10; | 395 | DS1339_REG_ALARM1_SECS, 9, buf); |
416 | 396 | if (ret < 0) { | |
417 | ret = i2c_transfer(to_i2c_adapter(client->dev.parent), | ||
418 | &ds1307->msg[1], 1); | ||
419 | if (ret != 1) { | ||
420 | dev_err(dev, "can't set alarm time\n"); | 397 | dev_err(dev, "can't set alarm time\n"); |
421 | return -EIO; | 398 | return ret; |
422 | } | 399 | } |
423 | 400 | ||
424 | return 0; | 401 | return 0; |
@@ -490,7 +467,6 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
490 | { | 467 | { |
491 | struct i2c_client *client; | 468 | struct i2c_client *client; |
492 | struct ds1307 *ds1307; | 469 | struct ds1307 *ds1307; |
493 | struct i2c_msg msg[2]; | ||
494 | int result; | 470 | int result; |
495 | 471 | ||
496 | client = kobj_to_i2c_client(kobj); | 472 | client = kobj_to_i2c_client(kobj); |
@@ -503,24 +479,10 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
503 | if (unlikely(!count)) | 479 | if (unlikely(!count)) |
504 | return count; | 480 | return count; |
505 | 481 | ||
506 | msg[0].addr = client->addr; | 482 | result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf); |
507 | msg[0].flags = 0; | 483 | if (result < 0) |
508 | msg[0].len = 1; | ||
509 | msg[0].buf = buf; | ||
510 | |||
511 | buf[0] = 8 + off; | ||
512 | |||
513 | msg[1].addr = client->addr; | ||
514 | msg[1].flags = I2C_M_RD; | ||
515 | msg[1].len = count; | ||
516 | msg[1].buf = buf; | ||
517 | |||
518 | result = i2c_transfer(to_i2c_adapter(client->dev.parent), msg, 2); | ||
519 | if (result != 2) { | ||
520 | dev_err(&client->dev, "%s error %d\n", "nvram read", result); | 484 | dev_err(&client->dev, "%s error %d\n", "nvram read", result); |
521 | return -EIO; | 485 | return result; |
522 | } | ||
523 | return count; | ||
524 | } | 486 | } |
525 | 487 | ||
526 | static ssize_t | 488 | static ssize_t |
@@ -528,8 +490,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
528 | char *buf, loff_t off, size_t count) | 490 | char *buf, loff_t off, size_t count) |
529 | { | 491 | { |
530 | struct i2c_client *client; | 492 | struct i2c_client *client; |
531 | u8 buffer[NVRAM_SIZE + 1]; | 493 | int result; |
532 | int ret; | ||
533 | 494 | ||
534 | client = kobj_to_i2c_client(kobj); | 495 | client = kobj_to_i2c_client(kobj); |
535 | 496 | ||
@@ -540,11 +501,12 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
540 | if (unlikely(!count)) | 501 | if (unlikely(!count)) |
541 | return count; | 502 | return count; |
542 | 503 | ||
543 | buffer[0] = 8 + off; | 504 | result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf); |
544 | memcpy(buffer + 1, buf, count); | 505 | if (result < 0) { |
545 | 506 | dev_err(&client->dev, "%s error %d\n", "nvram write", result); | |
546 | ret = i2c_master_send(client, buffer, count + 1); | 507 | return result; |
547 | return (ret < 0) ? ret : (ret - 1); | 508 | } |
509 | return count; | ||
548 | } | 510 | } |
549 | 511 | ||
550 | static struct bin_attribute nvram = { | 512 | static struct bin_attribute nvram = { |
@@ -571,9 +533,11 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
571 | const struct chip_desc *chip = &chips[id->driver_data]; | 533 | const struct chip_desc *chip = &chips[id->driver_data]; |
572 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 534 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
573 | int want_irq = false; | 535 | int want_irq = false; |
536 | unsigned char *buf; | ||
574 | 537 | ||
575 | if (!i2c_check_functionality(adapter, | 538 | if (!i2c_check_functionality(adapter, |
576 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | 539 | I2C_FUNC_SMBUS_WRITE_BYTE_DATA | |
540 | I2C_FUNC_SMBUS_I2C_BLOCK)) | ||
577 | return -EIO; | 541 | return -EIO; |
578 | 542 | ||
579 | if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) | 543 | if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL))) |
@@ -581,18 +545,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
581 | 545 | ||
582 | ds1307->client = client; | 546 | ds1307->client = client; |
583 | i2c_set_clientdata(client, ds1307); | 547 | i2c_set_clientdata(client, ds1307); |
584 | |||
585 | ds1307->msg[0].addr = client->addr; | ||
586 | ds1307->msg[0].flags = 0; | ||
587 | ds1307->msg[0].len = 1; | ||
588 | ds1307->msg[0].buf = &ds1307->reg_addr; | ||
589 | |||
590 | ds1307->msg[1].addr = client->addr; | ||
591 | ds1307->msg[1].flags = I2C_M_RD; | ||
592 | ds1307->msg[1].len = sizeof(ds1307->regs); | ||
593 | ds1307->msg[1].buf = ds1307->regs; | ||
594 | |||
595 | ds1307->type = id->driver_data; | 548 | ds1307->type = id->driver_data; |
549 | buf = ds1307->regs; | ||
596 | 550 | ||
597 | switch (ds1307->type) { | 551 | switch (ds1307->type) { |
598 | case ds_1337: | 552 | case ds_1337: |
@@ -602,21 +556,15 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
602 | INIT_WORK(&ds1307->work, ds1307_work); | 556 | INIT_WORK(&ds1307->work, ds1307_work); |
603 | want_irq = true; | 557 | want_irq = true; |
604 | } | 558 | } |
605 | |||
606 | ds1307->reg_addr = DS1337_REG_CONTROL; | ||
607 | ds1307->msg[1].len = 2; | ||
608 | |||
609 | /* get registers that the "rtc" read below won't read... */ | 559 | /* get registers that the "rtc" read below won't read... */ |
610 | tmp = i2c_transfer(adapter, ds1307->msg, 2); | 560 | tmp = i2c_smbus_read_i2c_block_data(ds1307->client, |
561 | DS1337_REG_CONTROL, 2, buf); | ||
611 | if (tmp != 2) { | 562 | if (tmp != 2) { |
612 | pr_debug("read error %d\n", tmp); | 563 | pr_debug("read error %d\n", tmp); |
613 | err = -EIO; | 564 | err = -EIO; |
614 | goto exit_free; | 565 | goto exit_free; |
615 | } | 566 | } |
616 | 567 | ||
617 | ds1307->reg_addr = 0; | ||
618 | ds1307->msg[1].len = sizeof(ds1307->regs); | ||
619 | |||
620 | /* oscillator off? turn it on, so clock can tick. */ | 568 | /* oscillator off? turn it on, so clock can tick. */ |
621 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) | 569 | if (ds1307->regs[0] & DS1337_BIT_nEOSC) |
622 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; | 570 | ds1307->regs[0] &= ~DS1337_BIT_nEOSC; |
@@ -647,9 +595,8 @@ static int __devinit ds1307_probe(struct i2c_client *client, | |||
647 | 595 | ||
648 | read_rtc: | 596 | read_rtc: |
649 | /* read RTC registers */ | 597 | /* read RTC registers */ |
650 | 598 | tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf); | |
651 | tmp = i2c_transfer(adapter, ds1307->msg, 2); | 599 | if (tmp != 8) { |
652 | if (tmp != 2) { | ||
653 | pr_debug("read error %d\n", tmp); | 600 | pr_debug("read error %d\n", tmp); |
654 | err = -EIO; | 601 | err = -EIO; |
655 | goto exit_free; | 602 | goto exit_free; |