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 | 0d57abd5b87e2e82d8d2e8d5c9a3b56743ffa5ab (patch) | |
tree | 9eb35de4d5cf45de2e273d92de8f569b6e5af155 | |
parent | c6d3f6fa1b0b984991d6e2a261c7dd7f2685c7bd (diff) |
hwmon: (max6650) Convert to a new-style i2c driver
The new-style max6650 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: Hans J. Koch <hjk@linutronix.de>
-rw-r--r-- | drivers/hwmon/max6650.c | 102 |
1 files changed, 47 insertions, 55 deletions
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 52d528b76cc3..f27af6a9da41 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -104,22 +104,34 @@ I2C_CLIENT_INSMOD_1(max6650); | |||
104 | 104 | ||
105 | #define DIV_FROM_REG(reg) (1 << (reg & 7)) | 105 | #define DIV_FROM_REG(reg) (1 << (reg & 7)) |
106 | 106 | ||
107 | static int max6650_attach_adapter(struct i2c_adapter *adapter); | 107 | static int max6650_probe(struct i2c_client *client, |
108 | static int max6650_detect(struct i2c_adapter *adapter, int address, int kind); | 108 | const struct i2c_device_id *id); |
109 | static int max6650_detect(struct i2c_client *client, int kind, | ||
110 | struct i2c_board_info *info); | ||
109 | static int max6650_init_client(struct i2c_client *client); | 111 | static int max6650_init_client(struct i2c_client *client); |
110 | static int max6650_detach_client(struct i2c_client *client); | 112 | static int max6650_remove(struct i2c_client *client); |
111 | static struct max6650_data *max6650_update_device(struct device *dev); | 113 | static struct max6650_data *max6650_update_device(struct device *dev); |
112 | 114 | ||
113 | /* | 115 | /* |
114 | * Driver data (common to all clients) | 116 | * Driver data (common to all clients) |
115 | */ | 117 | */ |
116 | 118 | ||
119 | static const struct i2c_device_id max6650_id[] = { | ||
120 | { "max6650", max6650 }, | ||
121 | { } | ||
122 | }; | ||
123 | MODULE_DEVICE_TABLE(i2c, max6650_id); | ||
124 | |||
117 | static struct i2c_driver max6650_driver = { | 125 | static struct i2c_driver max6650_driver = { |
126 | .class = I2C_CLASS_HWMON, | ||
118 | .driver = { | 127 | .driver = { |
119 | .name = "max6650", | 128 | .name = "max6650", |
120 | }, | 129 | }, |
121 | .attach_adapter = max6650_attach_adapter, | 130 | .probe = max6650_probe, |
122 | .detach_client = max6650_detach_client, | 131 | .remove = max6650_remove, |
132 | .id_table = max6650_id, | ||
133 | .detect = max6650_detect, | ||
134 | .address_data = &addr_data, | ||
123 | }; | 135 | }; |
124 | 136 | ||
125 | /* | 137 | /* |
@@ -128,7 +140,6 @@ static struct i2c_driver max6650_driver = { | |||
128 | 140 | ||
129 | struct max6650_data | 141 | struct max6650_data |
130 | { | 142 | { |
131 | struct i2c_client client; | ||
132 | struct device *hwmon_dev; | 143 | struct device *hwmon_dev; |
133 | struct mutex update_lock; | 144 | struct mutex update_lock; |
134 | char valid; /* zero until following fields are valid */ | 145 | char valid; /* zero until following fields are valid */ |
@@ -437,47 +448,21 @@ static struct attribute_group max6650_attr_grp = { | |||
437 | * Real code | 448 | * Real code |
438 | */ | 449 | */ |
439 | 450 | ||
440 | static int max6650_attach_adapter(struct i2c_adapter *adapter) | 451 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
452 | static int max6650_detect(struct i2c_client *client, int kind, | ||
453 | struct i2c_board_info *info) | ||
441 | { | 454 | { |
442 | if (!(adapter->class & I2C_CLASS_HWMON)) { | 455 | struct i2c_adapter *adapter = client->adapter; |
443 | dev_dbg(&adapter->dev, | 456 | int address = client->addr; |
444 | "FATAL: max6650_attach_adapter class HWMON not set\n"); | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | return i2c_probe(adapter, &addr_data, max6650_detect); | ||
449 | } | ||
450 | |||
451 | /* | ||
452 | * The following function does more than just detection. If detection | ||
453 | * succeeds, it also registers the new chip. | ||
454 | */ | ||
455 | |||
456 | static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) | ||
457 | { | ||
458 | struct i2c_client *client; | ||
459 | struct max6650_data *data; | ||
460 | int err = -ENODEV; | ||
461 | 457 | ||
462 | dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind); | 458 | dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind); |
463 | 459 | ||
464 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 460 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
465 | dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " | 461 | dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " |
466 | "byte read mode, skipping.\n"); | 462 | "byte read mode, skipping.\n"); |
467 | return 0; | 463 | return -ENODEV; |
468 | } | ||
469 | |||
470 | if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { | ||
471 | dev_err(&adapter->dev, "max6650: out of memory.\n"); | ||
472 | return -ENOMEM; | ||
473 | } | 464 | } |
474 | 465 | ||
475 | client = &data->client; | ||
476 | i2c_set_clientdata(client, data); | ||
477 | client->addr = address; | ||
478 | client->adapter = adapter; | ||
479 | client->driver = &max6650_driver; | ||
480 | |||
481 | /* | 466 | /* |
482 | * Now we do the remaining detection. A negative kind means that | 467 | * Now we do the remaining detection. A negative kind means that |
483 | * the driver was loaded with no force parameter (default), so we | 468 | * the driver was loaded with no force parameter (default), so we |
@@ -501,28 +486,40 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) | |||
501 | ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { | 486 | ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { |
502 | dev_dbg(&adapter->dev, | 487 | dev_dbg(&adapter->dev, |
503 | "max6650: detection failed at 0x%02x.\n", address); | 488 | "max6650: detection failed at 0x%02x.\n", address); |
504 | goto err_free; | 489 | return -ENODEV; |
505 | } | 490 | } |
506 | 491 | ||
507 | dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); | 492 | dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); |
508 | 493 | ||
509 | strlcpy(client->name, "max6650", I2C_NAME_SIZE); | 494 | strlcpy(info->type, "max6650", I2C_NAME_SIZE); |
510 | mutex_init(&data->update_lock); | ||
511 | 495 | ||
512 | if ((err = i2c_attach_client(client))) { | 496 | return 0; |
513 | dev_err(&adapter->dev, "max6650: failed to attach client.\n"); | 497 | } |
514 | goto err_free; | 498 | |
499 | static int max6650_probe(struct i2c_client *client, | ||
500 | const struct i2c_device_id *id) | ||
501 | { | ||
502 | struct max6650_data *data; | ||
503 | int err; | ||
504 | |||
505 | if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { | ||
506 | dev_err(&client->dev, "out of memory.\n"); | ||
507 | return -ENOMEM; | ||
515 | } | 508 | } |
516 | 509 | ||
510 | i2c_set_clientdata(client, data); | ||
511 | mutex_init(&data->update_lock); | ||
512 | |||
517 | /* | 513 | /* |
518 | * Initialize the max6650 chip | 514 | * Initialize the max6650 chip |
519 | */ | 515 | */ |
520 | if (max6650_init_client(client)) | 516 | err = max6650_init_client(client); |
521 | goto err_detach; | 517 | if (err) |
518 | goto err_free; | ||
522 | 519 | ||
523 | err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); | 520 | err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); |
524 | if (err) | 521 | if (err) |
525 | goto err_detach; | 522 | goto err_free; |
526 | 523 | ||
527 | data->hwmon_dev = hwmon_device_register(&client->dev); | 524 | data->hwmon_dev = hwmon_device_register(&client->dev); |
528 | if (!IS_ERR(data->hwmon_dev)) | 525 | if (!IS_ERR(data->hwmon_dev)) |
@@ -531,24 +528,19 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) | |||
531 | err = PTR_ERR(data->hwmon_dev); | 528 | err = PTR_ERR(data->hwmon_dev); |
532 | dev_err(&client->dev, "error registering hwmon device.\n"); | 529 | dev_err(&client->dev, "error registering hwmon device.\n"); |
533 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 530 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
534 | err_detach: | ||
535 | i2c_detach_client(client); | ||
536 | err_free: | 531 | err_free: |
537 | kfree(data); | 532 | kfree(data); |
538 | return err; | 533 | return err; |
539 | } | 534 | } |
540 | 535 | ||
541 | static int max6650_detach_client(struct i2c_client *client) | 536 | static int max6650_remove(struct i2c_client *client) |
542 | { | 537 | { |
543 | struct max6650_data *data = i2c_get_clientdata(client); | 538 | struct max6650_data *data = i2c_get_clientdata(client); |
544 | int err; | ||
545 | 539 | ||
546 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); | 540 | sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); |
547 | hwmon_device_unregister(data->hwmon_dev); | 541 | hwmon_device_unregister(data->hwmon_dev); |
548 | err = i2c_detach_client(client); | 542 | kfree(data); |
549 | if (!err) | 543 | return 0; |
550 | kfree(data); | ||
551 | return err; | ||
552 | } | 544 | } |
553 | 545 | ||
554 | static int max6650_init_client(struct i2c_client *client) | 546 | static int max6650_init_client(struct i2c_client *client) |