aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-07-16 13:30:18 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-07-16 13:30:18 -0400
commit33468e7637c53b5516902422d66ca3d3fe64a9c3 (patch)
tree0411a29792dd84cfcbff414a8a5a49e8629b0a93 /drivers/hwmon
parentdc18a4184d6794e2e5c6f05142f3f8aaeeaee506 (diff)
hwmon: (w83l786ng) Convert to a new-style i2c driver
The new-style w83l786ng driver implements the optional detect() callback to cover the use cases of the legacy driver. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Kevin Lo <kevlo@kevlo.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/w83l786ng.c98
1 files changed, 45 insertions, 53 deletions
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index 41e22ddb568a..badca769f350 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -121,7 +121,6 @@ DIV_TO_REG(long val)
121} 121}
122 122
123struct w83l786ng_data { 123struct w83l786ng_data {
124 struct i2c_client client;
125 struct device *hwmon_dev; 124 struct device *hwmon_dev;
126 struct mutex update_lock; 125 struct mutex update_lock;
127 char valid; /* !=0 if following fields are valid */ 126 char valid; /* !=0 if following fields are valid */
@@ -146,18 +145,30 @@ struct w83l786ng_data {
146 u8 tolerance[2]; 145 u8 tolerance[2];
147}; 146};
148 147
149static int w83l786ng_attach_adapter(struct i2c_adapter *adapter); 148static int w83l786ng_probe(struct i2c_client *client,
150static int w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind); 149 const struct i2c_device_id *id);
151static int w83l786ng_detach_client(struct i2c_client *client); 150static int w83l786ng_detect(struct i2c_client *client, int kind,
151 struct i2c_board_info *info);
152static int w83l786ng_remove(struct i2c_client *client);
152static void w83l786ng_init_client(struct i2c_client *client); 153static void w83l786ng_init_client(struct i2c_client *client);
153static struct w83l786ng_data *w83l786ng_update_device(struct device *dev); 154static struct w83l786ng_data *w83l786ng_update_device(struct device *dev);
154 155
156static const struct i2c_device_id w83l786ng_id[] = {
157 { "w83l786ng", w83l786ng },
158 { }
159};
160MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
161
155static struct i2c_driver w83l786ng_driver = { 162static struct i2c_driver w83l786ng_driver = {
163 .class = I2C_CLASS_HWMON,
156 .driver = { 164 .driver = {
157 .name = "w83l786ng", 165 .name = "w83l786ng",
158 }, 166 },
159 .attach_adapter = w83l786ng_attach_adapter, 167 .probe = w83l786ng_probe,
160 .detach_client = w83l786ng_detach_client, 168 .remove = w83l786ng_remove,
169 .id_table = w83l786ng_id,
170 .detect = w83l786ng_detect,
171 .address_data = &addr_data,
161}; 172};
162 173
163static u8 174static u8
@@ -575,42 +586,15 @@ static const struct attribute_group w83l786ng_group = {
575}; 586};
576 587
577static int 588static int
578w83l786ng_attach_adapter(struct i2c_adapter *adapter) 589w83l786ng_detect(struct i2c_client *client, int kind,
590 struct i2c_board_info *info)
579{ 591{
580 if (!(adapter->class & I2C_CLASS_HWMON)) 592 struct i2c_adapter *adapter = client->adapter;
581 return 0;
582 return i2c_probe(adapter, &addr_data, w83l786ng_detect);
583}
584
585static int
586w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
587{
588 struct i2c_client *client;
589 struct device *dev;
590 struct w83l786ng_data *data;
591 int i, err = 0;
592 u8 reg_tmp;
593 593
594 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 594 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
595 goto exit; 595 return -ENODEV;
596 }
597
598 /* OK. For now, we presume we have a valid client. We now create the
599 client structure, even though we cannot fill it completely yet.
600 But it allows us to access w83l786ng_{read,write}_value. */
601
602 if (!(data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL))) {
603 err = -ENOMEM;
604 goto exit;
605 } 596 }
606 597
607 client = &data->client;
608 dev = &client->dev;
609 i2c_set_clientdata(client, data);
610 client->addr = address;
611 client->adapter = adapter;
612 client->driver = &w83l786ng_driver;
613
614 /* 598 /*
615 * Now we do the remaining detection. A negative kind means that 599 * Now we do the remaining detection. A negative kind means that
616 * the driver was loaded with no force parameter (default), so we 600 * the driver was loaded with no force parameter (default), so we
@@ -627,8 +611,8 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
627 W83L786NG_REG_CONFIG) & 0x80) != 0x00)) { 611 W83L786NG_REG_CONFIG) & 0x80) != 0x00)) {
628 dev_dbg(&adapter->dev, 612 dev_dbg(&adapter->dev,
629 "W83L786NG detection failed at 0x%02x.\n", 613 "W83L786NG detection failed at 0x%02x.\n",
630 address); 614 client->addr);
631 goto exit_free; 615 return -ENODEV;
632 } 616 }
633 } 617 }
634 618
@@ -651,17 +635,31 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
651 dev_info(&adapter->dev, 635 dev_info(&adapter->dev,
652 "Unsupported chip (man_id=0x%04X, " 636 "Unsupported chip (man_id=0x%04X, "
653 "chip_id=0x%02X).\n", man_id, chip_id); 637 "chip_id=0x%02X).\n", man_id, chip_id);
654 goto exit_free; 638 return -ENODEV;
655 } 639 }
656 } 640 }
657 641
658 /* Fill in the remaining client fields and put into the global list */ 642 strlcpy(info->type, "w83l786ng", I2C_NAME_SIZE);
659 strlcpy(client->name, "w83l786ng", I2C_NAME_SIZE);
660 mutex_init(&data->update_lock);
661 643
662 /* Tell the I2C layer a new client has arrived */ 644 return 0;
663 if ((err = i2c_attach_client(client))) 645}
664 goto exit_free; 646
647static int
648w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
649{
650 struct device *dev = &client->dev;
651 struct w83l786ng_data *data;
652 int i, err = 0;
653 u8 reg_tmp;
654
655 data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL);
656 if (!data) {
657 err = -ENOMEM;
658 goto exit;
659 }
660
661 i2c_set_clientdata(client, data);
662 mutex_init(&data->update_lock);
665 663
666 /* Initialize the chip */ 664 /* Initialize the chip */
667 w83l786ng_init_client(client); 665 w83l786ng_init_client(client);
@@ -693,25 +691,19 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
693 691
694exit_remove: 692exit_remove:
695 sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); 693 sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
696 i2c_detach_client(client);
697exit_free:
698 kfree(data); 694 kfree(data);
699exit: 695exit:
700 return err; 696 return err;
701} 697}
702 698
703static int 699static int
704w83l786ng_detach_client(struct i2c_client *client) 700w83l786ng_remove(struct i2c_client *client)
705{ 701{
706 struct w83l786ng_data *data = i2c_get_clientdata(client); 702 struct w83l786ng_data *data = i2c_get_clientdata(client);
707 int err;
708 703
709 hwmon_device_unregister(data->hwmon_dev); 704 hwmon_device_unregister(data->hwmon_dev);
710 sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); 705 sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
711 706
712 if ((err = i2c_detach_client(client)))
713 return err;
714
715 kfree(data); 707 kfree(data);
716 708
717 return 0; 709 return 0;