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) |
