aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig4
-rw-r--r--drivers/rtc/rtc-rs5c372.c95
2 files changed, 36 insertions, 63 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 83b071b6ece4..905d3308253b 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -160,11 +160,11 @@ config RTC_DRV_MAX6900
160 will be called rtc-max6900. 160 will be called rtc-max6900.
161 161
162config RTC_DRV_RS5C372 162config RTC_DRV_RS5C372
163 tristate "Ricoh RS5C372A/B" 163 tristate "Ricoh RS5C372A/B, RV5C386, RV5C387A"
164 depends on RTC_CLASS && I2C 164 depends on RTC_CLASS && I2C
165 help 165 help
166 If you say yes here you get support for the 166 If you say yes here you get support for the
167 Ricoh RS5C372A and RS5C372B RTC chips. 167 Ricoh RS5C372A, RS5C372B, RV5C386, and RV5C387A RTC chips.
168 168
169 This driver can also be built as a module. If so, the module 169 This driver can also be built as a module. If so, the module
170 will be called rtc-rs5c372. 170 will be called rtc-rs5c372.
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 09bbe575647b..6b67b5097927 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -13,13 +13,7 @@
13#include <linux/rtc.h> 13#include <linux/rtc.h>
14#include <linux/bcd.h> 14#include <linux/bcd.h>
15 15
16#define DRV_VERSION "0.4" 16#define DRV_VERSION "0.5"
17
18/* Addresses to scan */
19static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END };
20
21/* Insmod parameters */
22I2C_CLIENT_INSMOD;
23 17
24 18
25/* 19/*
@@ -88,9 +82,6 @@ struct rs5c372 {
88 unsigned has_irq:1; 82 unsigned has_irq:1;
89 char buf[17]; 83 char buf[17];
90 char *regs; 84 char *regs;
91
92 /* on conversion to a "new style" i2c driver, this vanishes */
93 struct i2c_client dev;
94}; 85};
95 86
96static int rs5c_get_regs(struct rs5c372 *rs5c) 87static int rs5c_get_regs(struct rs5c372 *rs5c)
@@ -483,25 +474,35 @@ static int rs5c_sysfs_register(struct device *dev)
483 return err; 474 return err;
484} 475}
485 476
477static void rs5c_sysfs_unregister(struct device *dev)
478{
479 device_remove_file(dev, &dev_attr_trim);
480 device_remove_file(dev, &dev_attr_osc);
481}
482
486#else 483#else
487static int rs5c_sysfs_register(struct device *dev) 484static int rs5c_sysfs_register(struct device *dev)
488{ 485{
489 return 0; 486 return 0;
490} 487}
488
489static void rs5c_sysfs_unregister(struct device *dev)
490{
491 /* nothing */
492}
491#endif /* SYSFS */ 493#endif /* SYSFS */
492 494
493static struct i2c_driver rs5c372_driver; 495static struct i2c_driver rs5c372_driver;
494 496
495static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) 497static int rs5c372_probe(struct i2c_client *client)
496{ 498{
497 int err = 0; 499 int err = 0;
498 struct i2c_client *client;
499 struct rs5c372 *rs5c372; 500 struct rs5c372 *rs5c372;
500 struct rtc_time tm; 501 struct rtc_time tm;
501 502
502 dev_dbg(&adapter->dev, "%s\n", __FUNCTION__); 503 dev_dbg(&client->dev, "%s\n", __FUNCTION__);
503 504
504 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { 505 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
505 err = -ENODEV; 506 err = -ENODEV;
506 goto exit; 507 goto exit;
507 } 508 }
@@ -514,35 +515,22 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
514 /* we read registers 0x0f then 0x00-0x0f; skip the first one */ 515 /* we read registers 0x0f then 0x00-0x0f; skip the first one */
515 rs5c372->regs=&rs5c372->buf[1]; 516 rs5c372->regs=&rs5c372->buf[1];
516 517
517 /* On conversion to a "new style" i2c driver, we'll be handed
518 * the i2c_client (we won't create it)
519 */
520 client = &rs5c372->dev;
521 rs5c372->client = client; 518 rs5c372->client = client;
522
523 /* I2C client */
524 client->addr = address;
525 client->driver = &rs5c372_driver;
526 client->adapter = adapter;
527
528 strlcpy(client->name, rs5c372_driver.driver.name, I2C_NAME_SIZE);
529
530 i2c_set_clientdata(client, rs5c372); 519 i2c_set_clientdata(client, rs5c372);
531 520
532 /* Inform the i2c layer */
533 if ((err = i2c_attach_client(client)))
534 goto exit_kfree;
535
536 err = rs5c_get_regs(rs5c372); 521 err = rs5c_get_regs(rs5c372);
537 if (err < 0) 522 if (err < 0)
538 goto exit_detach; 523 goto exit_kfree;
539 524
540 /* For "new style" drivers, irq is in i2c_client and chip type 525 if (strcmp(client->name, "rs5c372a") == 0)
541 * info comes from i2c_client.dev.platform_data. Meanwhile: 526 rs5c372->type = rtc_rs5c372a;
542 * 527 else if (strcmp(client->name, "rs5c372b") == 0)
543 * STICK BOARD-SPECIFIC SETUP CODE RIGHT HERE 528 rs5c372->type = rtc_rs5c372b;
544 */ 529 else if (strcmp(client->name, "rv5c386") == 0)
545 if (rs5c372->type == rtc_undef) { 530 rs5c372->type = rtc_rv5c386;
531 else if (strcmp(client->name, "rv5c387a") == 0)
532 rs5c372->type = rtc_rv5c387a;
533 else {
546 rs5c372->type = rtc_rs5c372b; 534 rs5c372->type = rtc_rs5c372b;
547 dev_warn(&client->dev, "assuming rs5c372b\n"); 535 dev_warn(&client->dev, "assuming rs5c372b\n");
548 } 536 }
@@ -567,7 +555,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
567 break; 555 break;
568 default: 556 default:
569 dev_err(&client->dev, "unknown RTC type\n"); 557 dev_err(&client->dev, "unknown RTC type\n");
570 goto exit_detach; 558 goto exit_kfree;
571 } 559 }
572 560
573 /* if the oscillator lost power and no other software (like 561 /* if the oscillator lost power and no other software (like
@@ -601,7 +589,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
601 589
602 if ((i2c_master_send(client, buf, 3)) != 3) { 590 if ((i2c_master_send(client, buf, 3)) != 3) {
603 dev_err(&client->dev, "setup error\n"); 591 dev_err(&client->dev, "setup error\n");
604 goto exit_detach; 592 goto exit_kfree;
605 } 593 }
606 rs5c372->regs[RS5C_REG_CTRL1] = buf[1]; 594 rs5c372->regs[RS5C_REG_CTRL1] = buf[1];
607 rs5c372->regs[RS5C_REG_CTRL2] = buf[2]; 595 rs5c372->regs[RS5C_REG_CTRL2] = buf[2];
@@ -621,14 +609,14 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
621 rs5c372->time24 ? "24hr" : "am/pm" 609 rs5c372->time24 ? "24hr" : "am/pm"
622 ); 610 );
623 611
624 /* FIXME when client->irq exists, use it to register alarm irq */ 612 /* REVISIT use client->irq to register alarm irq ... */
625 613
626 rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name, 614 rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name,
627 &client->dev, &rs5c372_rtc_ops, THIS_MODULE); 615 &client->dev, &rs5c372_rtc_ops, THIS_MODULE);
628 616
629 if (IS_ERR(rs5c372->rtc)) { 617 if (IS_ERR(rs5c372->rtc)) {
630 err = PTR_ERR(rs5c372->rtc); 618 err = PTR_ERR(rs5c372->rtc);
631 goto exit_detach; 619 goto exit_kfree;
632 } 620 }
633 621
634 err = rs5c_sysfs_register(&client->dev); 622 err = rs5c_sysfs_register(&client->dev);
@@ -640,9 +628,6 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
640exit_devreg: 628exit_devreg:
641 rtc_device_unregister(rs5c372->rtc); 629 rtc_device_unregister(rs5c372->rtc);
642 630
643exit_detach:
644 i2c_detach_client(client);
645
646exit_kfree: 631exit_kfree:
647 kfree(rs5c372); 632 kfree(rs5c372);
648 633
@@ -650,24 +635,12 @@ exit:
650 return err; 635 return err;
651} 636}
652 637
653static int rs5c372_attach(struct i2c_adapter *adapter) 638static int rs5c372_remove(struct i2c_client *client)
654{ 639{
655 return i2c_probe(adapter, &addr_data, rs5c372_probe);
656}
657
658static int rs5c372_detach(struct i2c_client *client)
659{
660 int err;
661 struct rs5c372 *rs5c372 = i2c_get_clientdata(client); 640 struct rs5c372 *rs5c372 = i2c_get_clientdata(client);
662 641
663 if (rs5c372->rtc) 642 rtc_device_unregister(rs5c372->rtc);
664 rtc_device_unregister(rs5c372->rtc); 643 rs5c_sysfs_unregister(&client->dev);
665
666 /* REVISIT properly destroy the sysfs files ... */
667
668 if ((err = i2c_detach_client(client)))
669 return err;
670
671 kfree(rs5c372); 644 kfree(rs5c372);
672 return 0; 645 return 0;
673} 646}
@@ -676,8 +649,8 @@ static struct i2c_driver rs5c372_driver = {
676 .driver = { 649 .driver = {
677 .name = "rtc-rs5c372", 650 .name = "rtc-rs5c372",
678 }, 651 },
679 .attach_adapter = &rs5c372_attach, 652 .probe = rs5c372_probe,
680 .detach_client = &rs5c372_detach, 653 .remove = rs5c372_remove,
681}; 654};
682 655
683static __init int rs5c372_init(void) 656static __init int rs5c372_init(void)