aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-10-17 11:51:16 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-10-17 11:51:16 -0400
commit0c6e97317102a8f480bdfb418f19fe989ad1c047 (patch)
treee4174ba35c27d96bcc11562002f80862967cf8c3 /drivers
parent6e1b5029dc0e4cfa765309312ebdc88711e37a20 (diff)
hwmon: (lm78) Convert to a new-style i2c driver
The new-style lm78 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/lm78.c194
1 files changed, 89 insertions, 105 deletions
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 177eaddde321..b5e3b2851698 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -115,7 +115,7 @@ static inline int TEMP_FROM_REG(s8 val)
115#define DIV_FROM_REG(val) (1 << (val)) 115#define DIV_FROM_REG(val) (1 << (val))
116 116
117struct lm78_data { 117struct lm78_data {
118 struct i2c_client client; 118 struct i2c_client *client;
119 struct device *hwmon_dev; 119 struct device *hwmon_dev;
120 struct mutex lock; 120 struct mutex lock;
121 enum chips type; 121 enum chips type;
@@ -142,9 +142,11 @@ struct lm78_data {
142}; 142};
143 143
144 144
145static int lm78_attach_adapter(struct i2c_adapter *adapter); 145static int lm78_i2c_detect(struct i2c_client *client, int kind,
146static int lm78_detect(struct i2c_adapter *adapter, int address, int kind); 146 struct i2c_board_info *info);
147static int lm78_detach_client(struct i2c_client *client); 147static int lm78_i2c_probe(struct i2c_client *client,
148 const struct i2c_device_id *id);
149static int lm78_i2c_remove(struct i2c_client *client);
148 150
149static int __devinit lm78_isa_probe(struct platform_device *pdev); 151static int __devinit lm78_isa_probe(struct platform_device *pdev);
150static int __devexit lm78_isa_remove(struct platform_device *pdev); 152static int __devexit lm78_isa_remove(struct platform_device *pdev);
@@ -155,12 +157,23 @@ static struct lm78_data *lm78_update_device(struct device *dev);
155static void lm78_init_device(struct lm78_data *data); 157static void lm78_init_device(struct lm78_data *data);
156 158
157 159
160static const struct i2c_device_id lm78_i2c_id[] = {
161 { "lm78", lm78 },
162 { "lm79", lm79 },
163 { }
164};
165MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
166
158static struct i2c_driver lm78_driver = { 167static struct i2c_driver lm78_driver = {
168 .class = I2C_CLASS_HWMON,
159 .driver = { 169 .driver = {
160 .name = "lm78", 170 .name = "lm78",
161 }, 171 },
162 .attach_adapter = lm78_attach_adapter, 172 .probe = lm78_i2c_probe,
163 .detach_client = lm78_detach_client, 173 .remove = lm78_i2c_remove,
174 .id_table = lm78_i2c_id,
175 .detect = lm78_i2c_detect,
176 .address_data = &addr_data,
164}; 177};
165 178
166static struct platform_driver lm78_isa_driver = { 179static struct platform_driver lm78_isa_driver = {
@@ -445,29 +458,6 @@ static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
445static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); 458static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
446static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); 459static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
447 460
448/* This function is called when:
449 * lm78_driver is inserted (when this module is loaded), for each
450 available adapter
451 * when a new adapter is inserted (and lm78_driver is still present)
452 We block updates of the ISA device to minimize the risk of concurrent
453 access to the same LM78 chip through different interfaces. */
454static int lm78_attach_adapter(struct i2c_adapter *adapter)
455{
456 struct lm78_data *data;
457 int err;
458
459 if (!(adapter->class & I2C_CLASS_HWMON))
460 return 0;
461
462 data = pdev ? platform_get_drvdata(pdev) : NULL;
463 if (data)
464 mutex_lock(&data->update_lock);
465 err = i2c_probe(adapter, &addr_data, lm78_detect);
466 if (data)
467 mutex_unlock(&data->update_lock);
468 return err;
469}
470
471static struct attribute *lm78_attributes[] = { 461static struct attribute *lm78_attributes[] = {
472 &sensor_dev_attr_in0_input.dev_attr.attr, 462 &sensor_dev_attr_in0_input.dev_attr.attr,
473 &sensor_dev_attr_in0_min.dev_attr.attr, 463 &sensor_dev_attr_in0_min.dev_attr.attr,
@@ -537,13 +527,11 @@ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
537/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */ 527/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
538static int lm78_alias_detect(struct i2c_client *client, u8 chipid) 528static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
539{ 529{
540 struct lm78_data *i2c, *isa; 530 struct lm78_data *isa;
541 int i; 531 int i;
542 532
543 if (!pdev) /* No ISA chip */ 533 if (!pdev) /* No ISA chip */
544 return 0; 534 return 0;
545
546 i2c = i2c_get_clientdata(client);
547 isa = platform_get_drvdata(pdev); 535 isa = platform_get_drvdata(pdev);
548 536
549 if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr) 537 if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr)
@@ -554,70 +542,55 @@ static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
554 /* We compare all the limit registers, the config register and the 542 /* We compare all the limit registers, the config register and the
555 * interrupt mask registers */ 543 * interrupt mask registers */
556 for (i = 0x2b; i <= 0x3d; i++) { 544 for (i = 0x2b; i <= 0x3d; i++) {
557 if (lm78_read_value(isa, i) != lm78_read_value(i2c, i)) 545 if (lm78_read_value(isa, i) !=
546 i2c_smbus_read_byte_data(client, i))
558 return 0; 547 return 0;
559 } 548 }
560 if (lm78_read_value(isa, LM78_REG_CONFIG) != 549 if (lm78_read_value(isa, LM78_REG_CONFIG) !=
561 lm78_read_value(i2c, LM78_REG_CONFIG)) 550 i2c_smbus_read_byte_data(client, LM78_REG_CONFIG))
562 return 0; 551 return 0;
563 for (i = 0x43; i <= 0x46; i++) { 552 for (i = 0x43; i <= 0x46; i++) {
564 if (lm78_read_value(isa, i) != lm78_read_value(i2c, i)) 553 if (lm78_read_value(isa, i) !=
554 i2c_smbus_read_byte_data(client, i))
565 return 0; 555 return 0;
566 } 556 }
567 557
568 return 1; 558 return 1;
569} 559}
570 560
571/* This function is called by i2c_probe */ 561static int lm78_i2c_detect(struct i2c_client *client, int kind,
572static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) 562 struct i2c_board_info *info)
573{ 563{
574 int i, err; 564 int i;
575 struct i2c_client *new_client; 565 struct lm78_data *isa = pdev ? platform_get_drvdata(pdev) : NULL;
576 struct lm78_data *data; 566 const char *client_name;
577 const char *client_name = ""; 567 struct i2c_adapter *adapter = client->adapter;
578 568 int address = client->addr;
579 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
580 err = -ENODEV;
581 goto ERROR1;
582 }
583
584 /* OK. For now, we presume we have a valid client. We now create the
585 client structure, even though we cannot fill it completely yet.
586 But it allows us to access lm78_{read,write}_value. */
587 569
588 if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) { 570 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
589 err = -ENOMEM; 571 return -ENODEV;
590 goto ERROR1;
591 }
592 572
593 new_client = &data->client; 573 /* We block updates of the ISA device to minimize the risk of
594 i2c_set_clientdata(new_client, data); 574 concurrent access to the same LM78 chip through different
595 new_client->addr = address; 575 interfaces. */
596 new_client->adapter = adapter; 576 if (isa)
597 new_client->driver = &lm78_driver; 577 mutex_lock(&isa->update_lock);
598 578
599 /* Now, we do the remaining detection. */
600 if (kind < 0) { 579 if (kind < 0) {
601 if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) { 580 if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
602 err = -ENODEV; 581 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR)
603 goto ERROR2; 582 != address)
604 } 583 goto err_nodev;
605 if (lm78_read_value(data, LM78_REG_I2C_ADDR) != 584
606 address) {
607 err = -ENODEV;
608 goto ERROR2;
609 }
610 /* Explicitly prevent the misdetection of Winbond chips */ 585 /* Explicitly prevent the misdetection of Winbond chips */
611 i = lm78_read_value(data, 0x4f); 586 i = i2c_smbus_read_byte_data(client, 0x4f);
612 if (i == 0xa3 || i == 0x5c) { 587 if (i == 0xa3 || i == 0x5c)
613 err = -ENODEV; 588 goto err_nodev;
614 goto ERROR2;
615 }
616 } 589 }
617 590
618 /* Determine the chip type. */ 591 /* Determine the chip type. */
619 if (kind <= 0) { 592 if (kind <= 0) {
620 i = lm78_read_value(data, LM78_REG_CHIPID); 593 i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
621 if (i == 0x00 || i == 0x20 /* LM78 */ 594 if (i == 0x00 || i == 0x20 /* LM78 */
622 || i == 0x40) /* LM78-J */ 595 || i == 0x40) /* LM78-J */
623 kind = lm78; 596 kind = lm78;
@@ -629,40 +602,59 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
629 "parameter for unknown chip at " 602 "parameter for unknown chip at "
630 "adapter %d, address 0x%02x\n", 603 "adapter %d, address 0x%02x\n",
631 i2c_adapter_id(adapter), address); 604 i2c_adapter_id(adapter), address);
632 err = -ENODEV; 605 goto err_nodev;
633 goto ERROR2;
634 } 606 }
635 607
636 if (lm78_alias_detect(new_client, i)) { 608 if (lm78_alias_detect(client, i)) {
637 dev_dbg(&adapter->dev, "Device at 0x%02x appears to " 609 dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
638 "be the same as ISA device\n", address); 610 "be the same as ISA device\n", address);
639 err = -ENODEV; 611 goto err_nodev;
640 goto ERROR2;
641 } 612 }
642 } 613 }
643 614
644 if (kind == lm78) { 615 if (isa)
645 client_name = "lm78"; 616 mutex_unlock(&isa->update_lock);
646 } else if (kind == lm79) { 617
618 switch (kind) {
619 case lm79:
647 client_name = "lm79"; 620 client_name = "lm79";
621 break;
622 default:
623 client_name = "lm78";
648 } 624 }
625 strlcpy(info->type, client_name, I2C_NAME_SIZE);
649 626
650 /* Fill in the remaining client fields and put into the global list */ 627 return 0;
651 strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
652 data->type = kind;
653 628
654 /* Tell the I2C layer a new client has arrived */ 629 err_nodev:
655 if ((err = i2c_attach_client(new_client))) 630 if (isa)
656 goto ERROR2; 631 mutex_unlock(&isa->update_lock);
632 return -ENODEV;
633}
634
635static int lm78_i2c_probe(struct i2c_client *client,
636 const struct i2c_device_id *id)
637{
638 struct lm78_data *data;
639 int err;
640
641 data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
642 if (!data)
643 return -ENOMEM;
644
645 i2c_set_clientdata(client, data);
646 data->client = client;
647 data->type = id->driver_data;
657 648
658 /* Initialize the LM78 chip */ 649 /* Initialize the LM78 chip */
659 lm78_init_device(data); 650 lm78_init_device(data);
660 651
661 /* Register sysfs hooks */ 652 /* Register sysfs hooks */
662 if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) 653 err = sysfs_create_group(&client->dev.kobj, &lm78_group);
654 if (err)
663 goto ERROR3; 655 goto ERROR3;
664 656
665 data->hwmon_dev = hwmon_device_register(&new_client->dev); 657 data->hwmon_dev = hwmon_device_register(&client->dev);
666 if (IS_ERR(data->hwmon_dev)) { 658 if (IS_ERR(data->hwmon_dev)) {
667 err = PTR_ERR(data->hwmon_dev); 659 err = PTR_ERR(data->hwmon_dev);
668 goto ERROR4; 660 goto ERROR4;
@@ -671,26 +663,18 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
671 return 0; 663 return 0;
672 664
673ERROR4: 665ERROR4:
674 sysfs_remove_group(&new_client->dev.kobj, &lm78_group); 666 sysfs_remove_group(&client->dev.kobj, &lm78_group);
675ERROR3: 667ERROR3:
676 i2c_detach_client(new_client);
677ERROR2:
678 kfree(data); 668 kfree(data);
679ERROR1:
680 return err; 669 return err;
681} 670}
682 671
683static int lm78_detach_client(struct i2c_client *client) 672static int lm78_i2c_remove(struct i2c_client *client)
684{ 673{
685 struct lm78_data *data = i2c_get_clientdata(client); 674 struct lm78_data *data = i2c_get_clientdata(client);
686 int err;
687 675
688 hwmon_device_unregister(data->hwmon_dev); 676 hwmon_device_unregister(data->hwmon_dev);
689 sysfs_remove_group(&client->dev.kobj, &lm78_group); 677 sysfs_remove_group(&client->dev.kobj, &lm78_group);
690
691 if ((err = i2c_detach_client(client)))
692 return err;
693
694 kfree(data); 678 kfree(data);
695 679
696 return 0; 680 return 0;
@@ -774,9 +758,9 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev)
774 would slow down the LM78 access and should not be necessary. */ 758 would slow down the LM78 access and should not be necessary. */
775static int lm78_read_value(struct lm78_data *data, u8 reg) 759static int lm78_read_value(struct lm78_data *data, u8 reg)
776{ 760{
777 struct i2c_client *client = &data->client; 761 struct i2c_client *client = data->client;
778 762
779 if (!client->driver) { /* ISA device */ 763 if (!client) { /* ISA device */
780 int res; 764 int res;
781 mutex_lock(&data->lock); 765 mutex_lock(&data->lock);
782 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); 766 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
@@ -796,9 +780,9 @@ static int lm78_read_value(struct lm78_data *data, u8 reg)
796 nowhere else be necessary! */ 780 nowhere else be necessary! */
797static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) 781static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
798{ 782{
799 struct i2c_client *client = &data->client; 783 struct i2c_client *client = data->client;
800 784
801 if (!client->driver) { /* ISA device */ 785 if (!client) { /* ISA device */
802 mutex_lock(&data->lock); 786 mutex_lock(&data->lock);
803 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); 787 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
804 outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET); 788 outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET);