diff options
| -rw-r--r-- | drivers/hwmon/lm90.c | 119 |
1 files changed, 63 insertions, 56 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index d1a3da3dd8e0..c24fe36ac787 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
| @@ -187,23 +187,44 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680); | |||
| 187 | * Functions declaration | 187 | * Functions declaration |
| 188 | */ | 188 | */ |
| 189 | 189 | ||
| 190 | static int lm90_attach_adapter(struct i2c_adapter *adapter); | 190 | static int lm90_detect(struct i2c_client *client, int kind, |
| 191 | static int lm90_detect(struct i2c_adapter *adapter, int address, | 191 | struct i2c_board_info *info); |
| 192 | int kind); | 192 | static int lm90_probe(struct i2c_client *client, |
| 193 | const struct i2c_device_id *id); | ||
| 193 | static void lm90_init_client(struct i2c_client *client); | 194 | static void lm90_init_client(struct i2c_client *client); |
| 194 | static int lm90_detach_client(struct i2c_client *client); | 195 | static int lm90_remove(struct i2c_client *client); |
| 195 | static struct lm90_data *lm90_update_device(struct device *dev); | 196 | static struct lm90_data *lm90_update_device(struct device *dev); |
| 196 | 197 | ||
| 197 | /* | 198 | /* |
| 198 | * Driver data (common to all clients) | 199 | * Driver data (common to all clients) |
| 199 | */ | 200 | */ |
| 200 | 201 | ||
| 202 | static const struct i2c_device_id lm90_id[] = { | ||
| 203 | { "adm1032", adm1032 }, | ||
| 204 | { "adt7461", adt7461 }, | ||
| 205 | { "lm90", lm90 }, | ||
| 206 | { "lm86", lm86 }, | ||
| 207 | { "lm89", lm99 }, | ||
| 208 | { "lm99", lm99 }, /* Missing temperature offset */ | ||
| 209 | { "max6657", max6657 }, | ||
| 210 | { "max6658", max6657 }, | ||
| 211 | { "max6659", max6657 }, | ||
| 212 | { "max6680", max6680 }, | ||
| 213 | { "max6681", max6680 }, | ||
| 214 | { } | ||
| 215 | }; | ||
| 216 | MODULE_DEVICE_TABLE(i2c, lm90_id); | ||
| 217 | |||
| 201 | static struct i2c_driver lm90_driver = { | 218 | static struct i2c_driver lm90_driver = { |
| 219 | .class = I2C_CLASS_HWMON, | ||
| 202 | .driver = { | 220 | .driver = { |
| 203 | .name = "lm90", | 221 | .name = "lm90", |
| 204 | }, | 222 | }, |
| 205 | .attach_adapter = lm90_attach_adapter, | 223 | .probe = lm90_probe, |
| 206 | .detach_client = lm90_detach_client, | 224 | .remove = lm90_remove, |
| 225 | .id_table = lm90_id, | ||
| 226 | .detect = lm90_detect, | ||
| 227 | .address_data = &addr_data, | ||
| 207 | }; | 228 | }; |
| 208 | 229 | ||
| 209 | /* | 230 | /* |
| @@ -211,7 +232,6 @@ static struct i2c_driver lm90_driver = { | |||
| 211 | */ | 232 | */ |
| 212 | 233 | ||
| 213 | struct lm90_data { | 234 | struct lm90_data { |
| 214 | struct i2c_client client; | ||
| 215 | struct device *hwmon_dev; | 235 | struct device *hwmon_dev; |
| 216 | struct mutex update_lock; | 236 | struct mutex update_lock; |
| 217 | char valid; /* zero until following fields are valid */ | 237 | char valid; /* zero until following fields are valid */ |
| @@ -477,40 +497,16 @@ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value) | |||
| 477 | return 0; | 497 | return 0; |
| 478 | } | 498 | } |
| 479 | 499 | ||
| 480 | static int lm90_attach_adapter(struct i2c_adapter *adapter) | 500 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 481 | { | 501 | static int lm90_detect(struct i2c_client *new_client, int kind, |
| 482 | if (!(adapter->class & I2C_CLASS_HWMON)) | 502 | struct i2c_board_info *info) |
| 483 | return 0; | ||
| 484 | return i2c_probe(adapter, &addr_data, lm90_detect); | ||
| 485 | } | ||
| 486 | |||
| 487 | /* | ||
| 488 | * The following function does more than just detection. If detection | ||
| 489 | * succeeds, it also registers the new chip. | ||
| 490 | */ | ||
| 491 | static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | ||
| 492 | { | 503 | { |
| 493 | struct i2c_client *new_client; | 504 | struct i2c_adapter *adapter = new_client->adapter; |
| 494 | struct lm90_data *data; | 505 | int address = new_client->addr; |
| 495 | int err = 0; | ||
| 496 | const char *name = ""; | 506 | const char *name = ""; |
| 497 | 507 | ||
| 498 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 508 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
| 499 | goto exit; | 509 | return -ENODEV; |
| 500 | |||
| 501 | if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) { | ||
| 502 | err = -ENOMEM; | ||
| 503 | goto exit; | ||
| 504 | } | ||
| 505 | |||
| 506 | /* The common I2C client data is placed right before the | ||
| 507 | LM90-specific data. */ | ||
| 508 | new_client = &data->client; | ||
| 509 | i2c_set_clientdata(new_client, data); | ||
| 510 | new_client->addr = address; | ||
| 511 | new_client->adapter = adapter; | ||
| 512 | new_client->driver = &lm90_driver; | ||
| 513 | new_client->flags = 0; | ||
| 514 | 510 | ||
| 515 | /* | 511 | /* |
| 516 | * Now we do the remaining detection. A negative kind means that | 512 | * Now we do the remaining detection. A negative kind means that |
| @@ -538,7 +534,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 538 | LM90_REG_R_CONFIG1)) < 0 | 534 | LM90_REG_R_CONFIG1)) < 0 |
| 539 | || (reg_convrate = i2c_smbus_read_byte_data(new_client, | 535 | || (reg_convrate = i2c_smbus_read_byte_data(new_client, |
| 540 | LM90_REG_R_CONVRATE)) < 0) | 536 | LM90_REG_R_CONVRATE)) < 0) |
| 541 | goto exit_free; | 537 | return -ENODEV; |
| 542 | 538 | ||
| 543 | if ((address == 0x4C || address == 0x4D) | 539 | if ((address == 0x4C || address == 0x4D) |
| 544 | && man_id == 0x01) { /* National Semiconductor */ | 540 | && man_id == 0x01) { /* National Semiconductor */ |
| @@ -546,7 +542,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 546 | 542 | ||
| 547 | if ((reg_config2 = i2c_smbus_read_byte_data(new_client, | 543 | if ((reg_config2 = i2c_smbus_read_byte_data(new_client, |
| 548 | LM90_REG_R_CONFIG2)) < 0) | 544 | LM90_REG_R_CONFIG2)) < 0) |
| 549 | goto exit_free; | 545 | return -ENODEV; |
| 550 | 546 | ||
| 551 | if ((reg_config1 & 0x2A) == 0x00 | 547 | if ((reg_config1 & 0x2A) == 0x00 |
| 552 | && (reg_config2 & 0xF8) == 0x00 | 548 | && (reg_config2 & 0xF8) == 0x00 |
| @@ -610,10 +606,11 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 610 | dev_info(&adapter->dev, | 606 | dev_info(&adapter->dev, |
| 611 | "Unsupported chip (man_id=0x%02X, " | 607 | "Unsupported chip (man_id=0x%02X, " |
| 612 | "chip_id=0x%02X).\n", man_id, chip_id); | 608 | "chip_id=0x%02X).\n", man_id, chip_id); |
| 613 | goto exit_free; | 609 | return -ENODEV; |
| 614 | } | 610 | } |
| 615 | } | 611 | } |
| 616 | 612 | ||
| 613 | /* Fill the i2c board info */ | ||
| 617 | if (kind == lm90) { | 614 | if (kind == lm90) { |
| 618 | name = "lm90"; | 615 | name = "lm90"; |
| 619 | } else if (kind == adm1032) { | 616 | } else if (kind == adm1032) { |
| @@ -621,7 +618,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 621 | /* The ADM1032 supports PEC, but only if combined | 618 | /* The ADM1032 supports PEC, but only if combined |
| 622 | transactions are not used. */ | 619 | transactions are not used. */ |
| 623 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | 620 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) |
| 624 | new_client->flags |= I2C_CLIENT_PEC; | 621 | info->flags |= I2C_CLIENT_PEC; |
| 625 | } else if (kind == lm99) { | 622 | } else if (kind == lm99) { |
| 626 | name = "lm99"; | 623 | name = "lm99"; |
| 627 | } else if (kind == lm86) { | 624 | } else if (kind == lm86) { |
| @@ -633,23 +630,39 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 633 | } else if (kind == adt7461) { | 630 | } else if (kind == adt7461) { |
| 634 | name = "adt7461"; | 631 | name = "adt7461"; |
| 635 | } | 632 | } |
| 633 | strlcpy(info->type, name, I2C_NAME_SIZE); | ||
| 634 | |||
| 635 | return 0; | ||
| 636 | } | ||
| 637 | |||
| 638 | static int lm90_probe(struct i2c_client *new_client, | ||
| 639 | const struct i2c_device_id *id) | ||
| 640 | { | ||
| 641 | struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent); | ||
| 642 | struct lm90_data *data; | ||
| 643 | int err; | ||
| 636 | 644 | ||
| 637 | /* We can fill in the remaining client fields */ | 645 | data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL); |
| 638 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | 646 | if (!data) { |
| 639 | data->valid = 0; | 647 | err = -ENOMEM; |
| 640 | data->kind = kind; | 648 | goto exit; |
| 649 | } | ||
| 650 | i2c_set_clientdata(new_client, data); | ||
| 641 | mutex_init(&data->update_lock); | 651 | mutex_init(&data->update_lock); |
| 642 | 652 | ||
| 643 | /* Tell the I2C layer a new client has arrived */ | 653 | /* Set the device type */ |
| 644 | if ((err = i2c_attach_client(new_client))) | 654 | data->kind = id->driver_data; |
| 645 | goto exit_free; | 655 | if (data->kind == adm1032) { |
| 656 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | ||
| 657 | new_client->flags &= ~I2C_CLIENT_PEC; | ||
| 658 | } | ||
| 646 | 659 | ||
| 647 | /* Initialize the LM90 chip */ | 660 | /* Initialize the LM90 chip */ |
| 648 | lm90_init_client(new_client); | 661 | lm90_init_client(new_client); |
| 649 | 662 | ||
| 650 | /* Register sysfs hooks */ | 663 | /* Register sysfs hooks */ |
| 651 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group))) | 664 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group))) |
| 652 | goto exit_detach; | 665 | goto exit_free; |
| 653 | if (new_client->flags & I2C_CLIENT_PEC) { | 666 | if (new_client->flags & I2C_CLIENT_PEC) { |
| 654 | if ((err = device_create_file(&new_client->dev, | 667 | if ((err = device_create_file(&new_client->dev, |
| 655 | &dev_attr_pec))) | 668 | &dev_attr_pec))) |
| @@ -672,8 +685,6 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 672 | exit_remove_files: | 685 | exit_remove_files: |
| 673 | sysfs_remove_group(&new_client->dev.kobj, &lm90_group); | 686 | sysfs_remove_group(&new_client->dev.kobj, &lm90_group); |
| 674 | device_remove_file(&new_client->dev, &dev_attr_pec); | 687 | device_remove_file(&new_client->dev, &dev_attr_pec); |
| 675 | exit_detach: | ||
| 676 | i2c_detach_client(new_client); | ||
| 677 | exit_free: | 688 | exit_free: |
| 678 | kfree(data); | 689 | kfree(data); |
| 679 | exit: | 690 | exit: |
| @@ -710,10 +721,9 @@ static void lm90_init_client(struct i2c_client *client) | |||
| 710 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); | 721 | i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); |
| 711 | } | 722 | } |
| 712 | 723 | ||
| 713 | static int lm90_detach_client(struct i2c_client *client) | 724 | static int lm90_remove(struct i2c_client *client) |
| 714 | { | 725 | { |
| 715 | struct lm90_data *data = i2c_get_clientdata(client); | 726 | struct lm90_data *data = i2c_get_clientdata(client); |
| 716 | int err; | ||
| 717 | 727 | ||
| 718 | hwmon_device_unregister(data->hwmon_dev); | 728 | hwmon_device_unregister(data->hwmon_dev); |
| 719 | sysfs_remove_group(&client->dev.kobj, &lm90_group); | 729 | sysfs_remove_group(&client->dev.kobj, &lm90_group); |
| @@ -722,9 +732,6 @@ static int lm90_detach_client(struct i2c_client *client) | |||
| 722 | device_remove_file(&client->dev, | 732 | device_remove_file(&client->dev, |
| 723 | &sensor_dev_attr_temp2_offset.dev_attr); | 733 | &sensor_dev_attr_temp2_offset.dev_attr); |
| 724 | 734 | ||
| 725 | if ((err = i2c_detach_client(client))) | ||
| 726 | return err; | ||
| 727 | |||
| 728 | kfree(data); | 735 | kfree(data); |
| 729 | return 0; | 736 | return 0; |
| 730 | } | 737 | } |
