aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-rs5c372.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-07-17 07:04:55 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-17 13:23:08 -0400
commitd815461c7a73903d0a926b3cace6f69e144c54a3 (patch)
treeeceeae1db5fd3c876160ad517872cd19a74ecdba /drivers/rtc/rtc-rs5c372.c
parent045e0e85f2f6ee6621d8f7bab3059e9c74076738 (diff)
rtc-rs5c372 becomes a new-style i2c driver
Convert rtc-rs5c372 to be a "new style" I2C driver, and update the Kconfig text to be more complete.. Verified on an OMAP H4 development platform, along with a board init patch to declare its rv5c387a device. Only one defconfig -- powerpc/linkstation -- uses this driver; but several other platforms use it, just without defconfig support. Such platforms need to be converted so (a) their I2C adapter driver supports new-style drivers, and (b) board init code declares this I2C device. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Voipio Riku <Riku.Voipio@movial.fi> Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Cc: Martin Michlmayr <tbm@cyrius.com> Cc: Jean Delvare <khali@linux-fr.org> Cc: Alessandro Zummo <a.zummo@towertech.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-rs5c372.c')
-rw-r--r--drivers/rtc/rtc-rs5c372.c95
1 files changed, 34 insertions, 61 deletions
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)