diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-07-16 13:30:16 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-07-16 13:30:16 -0400 |
commit | 8fb597bb6ec80d53836229bf3576c7b848b909e3 (patch) | |
tree | 58f4586fe51a151404ebf056ad64ee23aa7401e0 | |
parent | 0d57abd5b87e2e82d8d2e8d5c9a3b56743ffa5ab (diff) |
hwmon: (smsc47m192) Convert to a new-style i2c driver
The new-style smsc47m192 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: Hartmut Rick <linux@rick.claranet.de>
-rw-r--r-- | drivers/hwmon/smsc47m192.c | 102 |
1 files changed, 46 insertions, 56 deletions
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c index 3c9db6598ba7..8bb5cb532d4d 100644 --- a/drivers/hwmon/smsc47m192.c +++ b/drivers/hwmon/smsc47m192.c | |||
@@ -96,7 +96,6 @@ static inline int TEMP_FROM_REG(s8 val) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | struct smsc47m192_data { | 98 | struct smsc47m192_data { |
99 | struct i2c_client client; | ||
100 | struct device *hwmon_dev; | 99 | struct device *hwmon_dev; |
101 | struct mutex update_lock; | 100 | struct mutex update_lock; |
102 | char valid; /* !=0 if following fields are valid */ | 101 | char valid; /* !=0 if following fields are valid */ |
@@ -114,18 +113,29 @@ struct smsc47m192_data { | |||
114 | u8 vrm; | 113 | u8 vrm; |
115 | }; | 114 | }; |
116 | 115 | ||
117 | static int smsc47m192_attach_adapter(struct i2c_adapter *adapter); | 116 | static int smsc47m192_probe(struct i2c_client *client, |
118 | static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | 117 | const struct i2c_device_id *id); |
119 | int kind); | 118 | static int smsc47m192_detect(struct i2c_client *client, int kind, |
120 | static int smsc47m192_detach_client(struct i2c_client *client); | 119 | struct i2c_board_info *info); |
120 | static int smsc47m192_remove(struct i2c_client *client); | ||
121 | static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); | 121 | static struct smsc47m192_data *smsc47m192_update_device(struct device *dev); |
122 | 122 | ||
123 | static const struct i2c_device_id smsc47m192_id[] = { | ||
124 | { "smsc47m192", smsc47m192 }, | ||
125 | { } | ||
126 | }; | ||
127 | MODULE_DEVICE_TABLE(i2c, smsc47m192_id); | ||
128 | |||
123 | static struct i2c_driver smsc47m192_driver = { | 129 | static struct i2c_driver smsc47m192_driver = { |
130 | .class = I2C_CLASS_HWMON, | ||
124 | .driver = { | 131 | .driver = { |
125 | .name = "smsc47m192", | 132 | .name = "smsc47m192", |
126 | }, | 133 | }, |
127 | .attach_adapter = smsc47m192_attach_adapter, | 134 | .probe = smsc47m192_probe, |
128 | .detach_client = smsc47m192_detach_client, | 135 | .remove = smsc47m192_remove, |
136 | .id_table = smsc47m192_id, | ||
137 | .detect = smsc47m192_detect, | ||
138 | .address_data = &addr_data, | ||
129 | }; | 139 | }; |
130 | 140 | ||
131 | /* Voltages */ | 141 | /* Voltages */ |
@@ -440,17 +450,6 @@ static const struct attribute_group smsc47m192_group_in4 = { | |||
440 | .attrs = smsc47m192_attributes_in4, | 450 | .attrs = smsc47m192_attributes_in4, |
441 | }; | 451 | }; |
442 | 452 | ||
443 | /* This function is called when: | ||
444 | * smsc47m192_driver is inserted (when this module is loaded), for each | ||
445 | available adapter | ||
446 | * when a new adapter is inserted (and smsc47m192_driver is still present) */ | ||
447 | static int smsc47m192_attach_adapter(struct i2c_adapter *adapter) | ||
448 | { | ||
449 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
450 | return 0; | ||
451 | return i2c_probe(adapter, &addr_data, smsc47m192_detect); | ||
452 | } | ||
453 | |||
454 | static void smsc47m192_init_client(struct i2c_client *client) | 453 | static void smsc47m192_init_client(struct i2c_client *client) |
455 | { | 454 | { |
456 | int i; | 455 | int i; |
@@ -481,31 +480,15 @@ static void smsc47m192_init_client(struct i2c_client *client) | |||
481 | } | 480 | } |
482 | } | 481 | } |
483 | 482 | ||
484 | /* This function is called by i2c_probe */ | 483 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
485 | static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | 484 | static int smsc47m192_detect(struct i2c_client *client, int kind, |
486 | int kind) | 485 | struct i2c_board_info *info) |
487 | { | 486 | { |
488 | struct i2c_client *client; | 487 | struct i2c_adapter *adapter = client->adapter; |
489 | struct smsc47m192_data *data; | 488 | int version; |
490 | int err = 0; | ||
491 | int version, config; | ||
492 | 489 | ||
493 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 490 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
494 | goto exit; | 491 | return -ENODEV; |
495 | |||
496 | if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) { | ||
497 | err = -ENOMEM; | ||
498 | goto exit; | ||
499 | } | ||
500 | |||
501 | client = &data->client; | ||
502 | i2c_set_clientdata(client, data); | ||
503 | client->addr = address; | ||
504 | client->adapter = adapter; | ||
505 | client->driver = &smsc47m192_driver; | ||
506 | |||
507 | if (kind == 0) | ||
508 | kind = smsc47m192; | ||
509 | 492 | ||
510 | /* Detection criteria from sensors_detect script */ | 493 | /* Detection criteria from sensors_detect script */ |
511 | if (kind < 0) { | 494 | if (kind < 0) { |
@@ -523,26 +506,39 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | |||
523 | } else { | 506 | } else { |
524 | dev_dbg(&adapter->dev, | 507 | dev_dbg(&adapter->dev, |
525 | "SMSC47M192 detection failed at 0x%02x\n", | 508 | "SMSC47M192 detection failed at 0x%02x\n", |
526 | address); | 509 | client->addr); |
527 | goto exit_free; | 510 | return -ENODEV; |
528 | } | 511 | } |
529 | } | 512 | } |
530 | 513 | ||
531 | /* Fill in the remaining client fields and put into the global list */ | 514 | strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE); |
532 | strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE); | 515 | |
516 | return 0; | ||
517 | } | ||
518 | |||
519 | static int smsc47m192_probe(struct i2c_client *client, | ||
520 | const struct i2c_device_id *id) | ||
521 | { | ||
522 | struct smsc47m192_data *data; | ||
523 | int config; | ||
524 | int err; | ||
525 | |||
526 | data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL); | ||
527 | if (!data) { | ||
528 | err = -ENOMEM; | ||
529 | goto exit; | ||
530 | } | ||
531 | |||
532 | i2c_set_clientdata(client, data); | ||
533 | data->vrm = vid_which_vrm(); | 533 | data->vrm = vid_which_vrm(); |
534 | mutex_init(&data->update_lock); | 534 | mutex_init(&data->update_lock); |
535 | 535 | ||
536 | /* Tell the I2C layer a new client has arrived */ | ||
537 | if ((err = i2c_attach_client(client))) | ||
538 | goto exit_free; | ||
539 | |||
540 | /* Initialize the SMSC47M192 chip */ | 536 | /* Initialize the SMSC47M192 chip */ |
541 | smsc47m192_init_client(client); | 537 | smsc47m192_init_client(client); |
542 | 538 | ||
543 | /* Register sysfs hooks */ | 539 | /* Register sysfs hooks */ |
544 | if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group))) | 540 | if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group))) |
545 | goto exit_detach; | 541 | goto exit_free; |
546 | 542 | ||
547 | /* Pin 110 is either in4 (+12V) or VID4 */ | 543 | /* Pin 110 is either in4 (+12V) or VID4 */ |
548 | config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); | 544 | config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG); |
@@ -563,26 +559,20 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, | |||
563 | exit_remove_files: | 559 | exit_remove_files: |
564 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); | 560 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); |
565 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); | 561 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); |
566 | exit_detach: | ||
567 | i2c_detach_client(client); | ||
568 | exit_free: | 562 | exit_free: |
569 | kfree(data); | 563 | kfree(data); |
570 | exit: | 564 | exit: |
571 | return err; | 565 | return err; |
572 | } | 566 | } |
573 | 567 | ||
574 | static int smsc47m192_detach_client(struct i2c_client *client) | 568 | static int smsc47m192_remove(struct i2c_client *client) |
575 | { | 569 | { |
576 | struct smsc47m192_data *data = i2c_get_clientdata(client); | 570 | struct smsc47m192_data *data = i2c_get_clientdata(client); |
577 | int err; | ||
578 | 571 | ||
579 | hwmon_device_unregister(data->hwmon_dev); | 572 | hwmon_device_unregister(data->hwmon_dev); |
580 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); | 573 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group); |
581 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); | 574 | sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4); |
582 | 575 | ||
583 | if ((err = i2c_detach_client(client))) | ||
584 | return err; | ||
585 | |||
586 | kfree(data); | 576 | kfree(data); |
587 | 577 | ||
588 | return 0; | 578 | return 0; |