aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:11 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:11 -0400
commit063675b15608dfbb8404b3a19546d579bd039d02 (patch)
treee3d00f1e141ef0e2718983ad27f48ea18ee5c2ac
parenteea54766c6e3f9850affa91061164aeb6bba44b6 (diff)
hwmon: (asb100) Convert to a new-style i2c driver
The new-style asb100 driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/hwmon/asb100.c207
1 files changed, 83 insertions, 124 deletions
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index fe2eea4d799b..8a45a2e6ba8a 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -176,10 +176,8 @@ static u8 DIV_TO_REG(long val)
176 data is pointed to by client->data. The structure itself is 176 data is pointed to by client->data. The structure itself is
177 dynamically allocated, at the same time the client itself is allocated. */ 177 dynamically allocated, at the same time the client itself is allocated. */
178struct asb100_data { 178struct asb100_data {
179 struct i2c_client client;
180 struct device *hwmon_dev; 179 struct device *hwmon_dev;
181 struct mutex lock; 180 struct mutex lock;
182 enum chips type;
183 181
184 struct mutex update_lock; 182 struct mutex update_lock;
185 unsigned long last_updated; /* In jiffies */ 183 unsigned long last_updated; /* In jiffies */
@@ -206,18 +204,30 @@ struct asb100_data {
206static int asb100_read_value(struct i2c_client *client, u16 reg); 204static int asb100_read_value(struct i2c_client *client, u16 reg);
207static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val); 205static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val);
208 206
209static int asb100_attach_adapter(struct i2c_adapter *adapter); 207static int asb100_probe(struct i2c_client *client,
210static int asb100_detect(struct i2c_adapter *adapter, int address, int kind); 208 const struct i2c_device_id *id);
211static int asb100_detach_client(struct i2c_client *client); 209static int asb100_detect(struct i2c_client *client, int kind,
210 struct i2c_board_info *info);
211static int asb100_remove(struct i2c_client *client);
212static struct asb100_data *asb100_update_device(struct device *dev); 212static struct asb100_data *asb100_update_device(struct device *dev);
213static void asb100_init_client(struct i2c_client *client); 213static void asb100_init_client(struct i2c_client *client);
214 214
215static const struct i2c_device_id asb100_id[] = {
216 { "asb100", asb100 },
217 { }
218};
219MODULE_DEVICE_TABLE(i2c, asb100_id);
220
215static struct i2c_driver asb100_driver = { 221static struct i2c_driver asb100_driver = {
222 .class = I2C_CLASS_HWMON,
216 .driver = { 223 .driver = {
217 .name = "asb100", 224 .name = "asb100",
218 }, 225 },
219 .attach_adapter = asb100_attach_adapter, 226 .probe = asb100_probe,
220 .detach_client = asb100_detach_client, 227 .remove = asb100_remove,
228 .id_table = asb100_id,
229 .detect = asb100_detect,
230 .address_data = &addr_data,
221}; 231};
222 232
223/* 7 Voltages */ 233/* 7 Voltages */
@@ -619,35 +629,13 @@ static const struct attribute_group asb100_group = {
619 .attrs = asb100_attributes, 629 .attrs = asb100_attributes,
620}; 630};
621 631
622/* This function is called when: 632static int asb100_detect_subclients(struct i2c_client *client)
623 asb100_driver is inserted (when this module is loaded), for each
624 available adapter
625 when a new adapter is inserted (and asb100_driver is still present)
626 */
627static int asb100_attach_adapter(struct i2c_adapter *adapter)
628{
629 if (!(adapter->class & I2C_CLASS_HWMON))
630 return 0;
631 return i2c_probe(adapter, &addr_data, asb100_detect);
632}
633
634static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
635 int kind, struct i2c_client *client)
636{ 633{
637 int i, id, err; 634 int i, id, err;
635 int address = client->addr;
636 unsigned short sc_addr[2];
638 struct asb100_data *data = i2c_get_clientdata(client); 637 struct asb100_data *data = i2c_get_clientdata(client);
639 638 struct i2c_adapter *adapter = client->adapter;
640 data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
641 if (!(data->lm75[0])) {
642 err = -ENOMEM;
643 goto ERROR_SC_0;
644 }
645
646 data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
647 if (!(data->lm75[1])) {
648 err = -ENOMEM;
649 goto ERROR_SC_1;
650 }
651 639
652 id = i2c_adapter_id(adapter); 640 id = i2c_adapter_id(adapter);
653 641
@@ -665,37 +653,34 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
665 asb100_write_value(client, ASB100_REG_I2C_SUBADDR, 653 asb100_write_value(client, ASB100_REG_I2C_SUBADDR,
666 (force_subclients[2] & 0x07) | 654 (force_subclients[2] & 0x07) |
667 ((force_subclients[3] & 0x07) << 4)); 655 ((force_subclients[3] & 0x07) << 4));
668 data->lm75[0]->addr = force_subclients[2]; 656 sc_addr[0] = force_subclients[2];
669 data->lm75[1]->addr = force_subclients[3]; 657 sc_addr[1] = force_subclients[3];
670 } else { 658 } else {
671 int val = asb100_read_value(client, ASB100_REG_I2C_SUBADDR); 659 int val = asb100_read_value(client, ASB100_REG_I2C_SUBADDR);
672 data->lm75[0]->addr = 0x48 + (val & 0x07); 660 sc_addr[0] = 0x48 + (val & 0x07);
673 data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07); 661 sc_addr[1] = 0x48 + ((val >> 4) & 0x07);
674 } 662 }
675 663
676 if (data->lm75[0]->addr == data->lm75[1]->addr) { 664 if (sc_addr[0] == sc_addr[1]) {
677 dev_err(&client->dev, "duplicate addresses 0x%x " 665 dev_err(&client->dev, "duplicate addresses 0x%x "
678 "for subclients\n", data->lm75[0]->addr); 666 "for subclients\n", sc_addr[0]);
679 err = -ENODEV; 667 err = -ENODEV;
680 goto ERROR_SC_2; 668 goto ERROR_SC_2;
681 } 669 }
682 670
683 for (i = 0; i <= 1; i++) { 671 data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]);
684 i2c_set_clientdata(data->lm75[i], NULL); 672 if (!data->lm75[0]) {
685 data->lm75[i]->adapter = adapter;
686 data->lm75[i]->driver = &asb100_driver;
687 strlcpy(data->lm75[i]->name, "asb100 subclient", I2C_NAME_SIZE);
688 }
689
690 if ((err = i2c_attach_client(data->lm75[0]))) {
691 dev_err(&client->dev, "subclient %d registration " 673 dev_err(&client->dev, "subclient %d registration "
692 "at address 0x%x failed.\n", i, data->lm75[0]->addr); 674 "at address 0x%x failed.\n", 1, sc_addr[0]);
675 err = -ENOMEM;
693 goto ERROR_SC_2; 676 goto ERROR_SC_2;
694 } 677 }
695 678
696 if ((err = i2c_attach_client(data->lm75[1]))) { 679 data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]);
680 if (!data->lm75[1]) {
697 dev_err(&client->dev, "subclient %d registration " 681 dev_err(&client->dev, "subclient %d registration "
698 "at address 0x%x failed.\n", i, data->lm75[1]->addr); 682 "at address 0x%x failed.\n", 2, sc_addr[1]);
683 err = -ENOMEM;
699 goto ERROR_SC_3; 684 goto ERROR_SC_3;
700 } 685 }
701 686
@@ -703,55 +688,31 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
703 688
704/* Undo inits in case of errors */ 689/* Undo inits in case of errors */
705ERROR_SC_3: 690ERROR_SC_3:
706 i2c_detach_client(data->lm75[0]); 691 i2c_unregister_device(data->lm75[0]);
707ERROR_SC_2: 692ERROR_SC_2:
708 kfree(data->lm75[1]);
709ERROR_SC_1:
710 kfree(data->lm75[0]);
711ERROR_SC_0:
712 return err; 693 return err;
713} 694}
714 695
715static int asb100_detect(struct i2c_adapter *adapter, int address, int kind) 696/* Return 0 if detection is successful, -ENODEV otherwise */
697static int asb100_detect(struct i2c_client *client, int kind,
698 struct i2c_board_info *info)
716{ 699{
717 int err; 700 struct i2c_adapter *adapter = client->adapter;
718 struct i2c_client *client;
719 struct asb100_data *data;
720 701
721 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 702 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
722 pr_debug("asb100.o: detect failed, " 703 pr_debug("asb100.o: detect failed, "
723 "smbus byte data not supported!\n"); 704 "smbus byte data not supported!\n");
724 err = -ENODEV; 705 return -ENODEV;
725 goto ERROR0;
726 } 706 }
727 707
728 /* OK. For now, we presume we have a valid client. We now create the
729 client structure, even though we cannot fill it completely yet.
730 But it allows us to access asb100_{read,write}_value. */
731
732 if (!(data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
733 pr_debug("asb100.o: detect failed, kzalloc failed!\n");
734 err = -ENOMEM;
735 goto ERROR0;
736 }
737
738 client = &data->client;
739 mutex_init(&data->lock);
740 i2c_set_clientdata(client, data);
741 client->addr = address;
742 client->adapter = adapter;
743 client->driver = &asb100_driver;
744
745 /* Now, we do the remaining detection. */
746
747 /* The chip may be stuck in some other bank than bank 0. This may 708 /* The chip may be stuck in some other bank than bank 0. This may
748 make reading other information impossible. Specify a force=... or 709 make reading other information impossible. Specify a force=... or
749 force_*=... parameter, and the chip will be reset to the right 710 force_*=... parameter, and the chip will be reset to the right
750 bank. */ 711 bank. */
751 if (kind < 0) { 712 if (kind < 0) {
752 713
753 int val1 = asb100_read_value(client, ASB100_REG_BANK); 714 int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK);
754 int val2 = asb100_read_value(client, ASB100_REG_CHIPMAN); 715 int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
755 716
756 /* If we're in bank 0 */ 717 /* If we're in bank 0 */
757 if ((!(val1 & 0x07)) && 718 if ((!(val1 & 0x07)) &&
@@ -761,48 +722,60 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
761 ((val1 & 0x80) && (val2 != 0x06)))) { 722 ((val1 & 0x80) && (val2 != 0x06)))) {
762 pr_debug("asb100.o: detect failed, " 723 pr_debug("asb100.o: detect failed, "
763 "bad chip id 0x%02x!\n", val2); 724 "bad chip id 0x%02x!\n", val2);
764 err = -ENODEV; 725 return -ENODEV;
765 goto ERROR1;
766 } 726 }
767 727
768 } /* kind < 0 */ 728 } /* kind < 0 */
769 729
770 /* We have either had a force parameter, or we have already detected 730 /* We have either had a force parameter, or we have already detected
771 Winbond. Put it now into bank 0 and Vendor ID High Byte */ 731 Winbond. Put it now into bank 0 and Vendor ID High Byte */
772 asb100_write_value(client, ASB100_REG_BANK, 732 i2c_smbus_write_byte_data(client, ASB100_REG_BANK,
773 (asb100_read_value(client, ASB100_REG_BANK) & 0x78) | 0x80); 733 (i2c_smbus_read_byte_data(client, ASB100_REG_BANK) & 0x78)
734 | 0x80);
774 735
775 /* Determine the chip type. */ 736 /* Determine the chip type. */
776 if (kind <= 0) { 737 if (kind <= 0) {
777 int val1 = asb100_read_value(client, ASB100_REG_WCHIPID); 738 int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID);
778 int val2 = asb100_read_value(client, ASB100_REG_CHIPMAN); 739 int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
779 740
780 if ((val1 == 0x31) && (val2 == 0x06)) 741 if ((val1 == 0x31) && (val2 == 0x06))
781 kind = asb100; 742 kind = asb100;
782 else { 743 else {
783 if (kind == 0) 744 if (kind == 0)
784 dev_warn(&client->dev, "ignoring " 745 dev_warn(&adapter->dev, "ignoring "
785 "'force' parameter for unknown chip " 746 "'force' parameter for unknown chip "
786 "at adapter %d, address 0x%02x.\n", 747 "at adapter %d, address 0x%02x.\n",
787 i2c_adapter_id(adapter), address); 748 i2c_adapter_id(adapter), client->addr);
788 err = -ENODEV; 749 return -ENODEV;
789 goto ERROR1;
790 } 750 }
791 } 751 }
792 752
793 /* Fill in remaining client fields and put it into the global list */ 753 strlcpy(info->type, "asb100", I2C_NAME_SIZE);
794 strlcpy(client->name, "asb100", I2C_NAME_SIZE);
795 data->type = kind;
796 mutex_init(&data->update_lock);
797 754
798 /* Tell the I2C layer a new client has arrived */ 755 return 0;
799 if ((err = i2c_attach_client(client))) 756}
800 goto ERROR1; 757
758static int asb100_probe(struct i2c_client *client,
759 const struct i2c_device_id *id)
760{
761 int err;
762 struct asb100_data *data;
763
764 data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL);
765 if (!data) {
766 pr_debug("asb100.o: probe failed, kzalloc failed!\n");
767 err = -ENOMEM;
768 goto ERROR0;
769 }
770
771 i2c_set_clientdata(client, data);
772 mutex_init(&data->lock);
773 mutex_init(&data->update_lock);
801 774
802 /* Attach secondary lm75 clients */ 775 /* Attach secondary lm75 clients */
803 if ((err = asb100_detect_subclients(adapter, address, kind, 776 err = asb100_detect_subclients(client);
804 client))) 777 if (err)
805 goto ERROR2; 778 goto ERROR1;
806 779
807 /* Initialize the chip */ 780 /* Initialize the chip */
808 asb100_init_client(client); 781 asb100_init_client(client);
@@ -827,39 +800,25 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
827ERROR4: 800ERROR4:
828 sysfs_remove_group(&client->dev.kobj, &asb100_group); 801 sysfs_remove_group(&client->dev.kobj, &asb100_group);
829ERROR3: 802ERROR3:
830 i2c_detach_client(data->lm75[1]); 803 i2c_unregister_device(data->lm75[1]);
831 i2c_detach_client(data->lm75[0]); 804 i2c_unregister_device(data->lm75[0]);
832 kfree(data->lm75[1]);
833 kfree(data->lm75[0]);
834ERROR2:
835 i2c_detach_client(client);
836ERROR1: 805ERROR1:
837 kfree(data); 806 kfree(data);
838ERROR0: 807ERROR0:
839 return err; 808 return err;
840} 809}
841 810
842static int asb100_detach_client(struct i2c_client *client) 811static int asb100_remove(struct i2c_client *client)
843{ 812{
844 struct asb100_data *data = i2c_get_clientdata(client); 813 struct asb100_data *data = i2c_get_clientdata(client);
845 int err;
846
847 /* main client */
848 if (data) {
849 hwmon_device_unregister(data->hwmon_dev);
850 sysfs_remove_group(&client->dev.kobj, &asb100_group);
851 }
852 814
853 if ((err = i2c_detach_client(client))) 815 hwmon_device_unregister(data->hwmon_dev);
854 return err; 816 sysfs_remove_group(&client->dev.kobj, &asb100_group);
855 817
856 /* main client */ 818 i2c_unregister_device(data->lm75[1]);
857 if (data) 819 i2c_unregister_device(data->lm75[0]);
858 kfree(data);
859 820
860 /* subclient */ 821 kfree(data);
861 else
862 kfree(client);
863 822
864 return 0; 823 return 0;
865} 824}