diff options
| -rw-r--r-- | drivers/hwmon/lm78.c | 86 |
1 files changed, 40 insertions, 46 deletions
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index cfb08978459d..cc68c85e1561 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
| @@ -159,10 +159,10 @@ static int lm78_detach_client(struct i2c_client *client); | |||
| 159 | static int __devinit lm78_isa_probe(struct platform_device *pdev); | 159 | static int __devinit lm78_isa_probe(struct platform_device *pdev); |
| 160 | static int __devexit lm78_isa_remove(struct platform_device *pdev); | 160 | static int __devexit lm78_isa_remove(struct platform_device *pdev); |
| 161 | 161 | ||
| 162 | static int lm78_read_value(struct i2c_client *client, u8 reg); | 162 | static int lm78_read_value(struct lm78_data *data, u8 reg); |
| 163 | static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value); | 163 | static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value); |
| 164 | static struct lm78_data *lm78_update_device(struct device *dev); | 164 | static struct lm78_data *lm78_update_device(struct device *dev); |
| 165 | static void lm78_init_client(struct i2c_client *client); | 165 | static void lm78_init_device(struct lm78_data *data); |
| 166 | 166 | ||
| 167 | 167 | ||
| 168 | static struct i2c_driver lm78_driver = { | 168 | static struct i2c_driver lm78_driver = { |
| @@ -207,12 +207,11 @@ static ssize_t set_in_min(struct device *dev, const char *buf, | |||
| 207 | size_t count, int nr) | 207 | size_t count, int nr) |
| 208 | { | 208 | { |
| 209 | struct lm78_data *data = dev_get_drvdata(dev); | 209 | struct lm78_data *data = dev_get_drvdata(dev); |
| 210 | struct i2c_client *client = &data->client; | ||
| 211 | unsigned long val = simple_strtoul(buf, NULL, 10); | 210 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 212 | 211 | ||
| 213 | mutex_lock(&data->update_lock); | 212 | mutex_lock(&data->update_lock); |
| 214 | data->in_min[nr] = IN_TO_REG(val); | 213 | data->in_min[nr] = IN_TO_REG(val); |
| 215 | lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]); | 214 | lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]); |
| 216 | mutex_unlock(&data->update_lock); | 215 | mutex_unlock(&data->update_lock); |
| 217 | return count; | 216 | return count; |
| 218 | } | 217 | } |
| @@ -221,12 +220,11 @@ static ssize_t set_in_max(struct device *dev, const char *buf, | |||
| 221 | size_t count, int nr) | 220 | size_t count, int nr) |
| 222 | { | 221 | { |
| 223 | struct lm78_data *data = dev_get_drvdata(dev); | 222 | struct lm78_data *data = dev_get_drvdata(dev); |
| 224 | struct i2c_client *client = &data->client; | ||
| 225 | unsigned long val = simple_strtoul(buf, NULL, 10); | 223 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 226 | 224 | ||
| 227 | mutex_lock(&data->update_lock); | 225 | mutex_lock(&data->update_lock); |
| 228 | data->in_max[nr] = IN_TO_REG(val); | 226 | data->in_max[nr] = IN_TO_REG(val); |
| 229 | lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]); | 227 | lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]); |
| 230 | mutex_unlock(&data->update_lock); | 228 | mutex_unlock(&data->update_lock); |
| 231 | return count; | 229 | return count; |
| 232 | } | 230 | } |
| @@ -288,12 +286,11 @@ static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, | |||
| 288 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 286 | static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| 289 | { | 287 | { |
| 290 | struct lm78_data *data = dev_get_drvdata(dev); | 288 | struct lm78_data *data = dev_get_drvdata(dev); |
| 291 | struct i2c_client *client = &data->client; | ||
| 292 | long val = simple_strtol(buf, NULL, 10); | 289 | long val = simple_strtol(buf, NULL, 10); |
| 293 | 290 | ||
| 294 | mutex_lock(&data->update_lock); | 291 | mutex_lock(&data->update_lock); |
| 295 | data->temp_over = TEMP_TO_REG(val); | 292 | data->temp_over = TEMP_TO_REG(val); |
| 296 | lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over); | 293 | lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over); |
| 297 | mutex_unlock(&data->update_lock); | 294 | mutex_unlock(&data->update_lock); |
| 298 | return count; | 295 | return count; |
| 299 | } | 296 | } |
| @@ -307,12 +304,11 @@ static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, | |||
| 307 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 304 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
| 308 | { | 305 | { |
| 309 | struct lm78_data *data = dev_get_drvdata(dev); | 306 | struct lm78_data *data = dev_get_drvdata(dev); |
| 310 | struct i2c_client *client = &data->client; | ||
| 311 | long val = simple_strtol(buf, NULL, 10); | 307 | long val = simple_strtol(buf, NULL, 10); |
| 312 | 308 | ||
| 313 | mutex_lock(&data->update_lock); | 309 | mutex_lock(&data->update_lock); |
| 314 | data->temp_hyst = TEMP_TO_REG(val); | 310 | data->temp_hyst = TEMP_TO_REG(val); |
| 315 | lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst); | 311 | lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst); |
| 316 | mutex_unlock(&data->update_lock); | 312 | mutex_unlock(&data->update_lock); |
| 317 | return count; | 313 | return count; |
| 318 | } | 314 | } |
| @@ -342,12 +338,11 @@ static ssize_t set_fan_min(struct device *dev, const char *buf, | |||
| 342 | size_t count, int nr) | 338 | size_t count, int nr) |
| 343 | { | 339 | { |
| 344 | struct lm78_data *data = dev_get_drvdata(dev); | 340 | struct lm78_data *data = dev_get_drvdata(dev); |
| 345 | struct i2c_client *client = &data->client; | ||
| 346 | unsigned long val = simple_strtoul(buf, NULL, 10); | 341 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 347 | 342 | ||
| 348 | mutex_lock(&data->update_lock); | 343 | mutex_lock(&data->update_lock); |
| 349 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 344 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
| 350 | lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); | 345 | lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 351 | mutex_unlock(&data->update_lock); | 346 | mutex_unlock(&data->update_lock); |
| 352 | return count; | 347 | return count; |
| 353 | } | 348 | } |
| @@ -366,7 +361,6 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
| 366 | size_t count, int nr) | 361 | size_t count, int nr) |
| 367 | { | 362 | { |
| 368 | struct lm78_data *data = dev_get_drvdata(dev); | 363 | struct lm78_data *data = dev_get_drvdata(dev); |
| 369 | struct i2c_client *client = &data->client; | ||
| 370 | unsigned long val = simple_strtoul(buf, NULL, 10); | 364 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 371 | unsigned long min; | 365 | unsigned long min; |
| 372 | u8 reg; | 366 | u8 reg; |
| @@ -387,7 +381,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
| 387 | return -EINVAL; | 381 | return -EINVAL; |
| 388 | } | 382 | } |
| 389 | 383 | ||
| 390 | reg = lm78_read_value(client, LM78_REG_VID_FANDIV); | 384 | reg = lm78_read_value(data, LM78_REG_VID_FANDIV); |
| 391 | switch (nr) { | 385 | switch (nr) { |
| 392 | case 0: | 386 | case 0: |
| 393 | reg = (reg & 0xcf) | (data->fan_div[nr] << 4); | 387 | reg = (reg & 0xcf) | (data->fan_div[nr] << 4); |
| @@ -396,11 +390,11 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, | |||
| 396 | reg = (reg & 0x3f) | (data->fan_div[nr] << 6); | 390 | reg = (reg & 0x3f) | (data->fan_div[nr] << 6); |
| 397 | break; | 391 | break; |
| 398 | } | 392 | } |
| 399 | lm78_write_value(client, LM78_REG_VID_FANDIV, reg); | 393 | lm78_write_value(data, LM78_REG_VID_FANDIV, reg); |
| 400 | 394 | ||
| 401 | data->fan_min[nr] = | 395 | data->fan_min[nr] = |
| 402 | FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 396 | FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
| 403 | lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); | 397 | lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); |
| 404 | mutex_unlock(&data->update_lock); | 398 | mutex_unlock(&data->update_lock); |
| 405 | 399 | ||
| 406 | return count; | 400 | return count; |
| @@ -563,11 +557,11 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 563 | 557 | ||
| 564 | /* Now, we do the remaining detection. */ | 558 | /* Now, we do the remaining detection. */ |
| 565 | if (kind < 0) { | 559 | if (kind < 0) { |
| 566 | if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) { | 560 | if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) { |
| 567 | err = -ENODEV; | 561 | err = -ENODEV; |
| 568 | goto ERROR2; | 562 | goto ERROR2; |
| 569 | } | 563 | } |
| 570 | if (lm78_read_value(new_client, LM78_REG_I2C_ADDR) != | 564 | if (lm78_read_value(data, LM78_REG_I2C_ADDR) != |
| 571 | address) { | 565 | address) { |
| 572 | err = -ENODEV; | 566 | err = -ENODEV; |
| 573 | goto ERROR2; | 567 | goto ERROR2; |
| @@ -576,7 +570,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 576 | 570 | ||
| 577 | /* Determine the chip type. */ | 571 | /* Determine the chip type. */ |
| 578 | if (kind <= 0) { | 572 | if (kind <= 0) { |
| 579 | i = lm78_read_value(new_client, LM78_REG_CHIPID); | 573 | i = lm78_read_value(data, LM78_REG_CHIPID); |
| 580 | if (i == 0x00 || i == 0x20 /* LM78 */ | 574 | if (i == 0x00 || i == 0x20 /* LM78 */ |
| 581 | || i == 0x40) /* LM78-J */ | 575 | || i == 0x40) /* LM78-J */ |
| 582 | kind = lm78; | 576 | kind = lm78; |
| @@ -608,7 +602,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 608 | goto ERROR2; | 602 | goto ERROR2; |
| 609 | 603 | ||
| 610 | /* Initialize the LM78 chip */ | 604 | /* Initialize the LM78 chip */ |
| 611 | lm78_init_client(new_client); | 605 | lm78_init_device(data); |
| 612 | 606 | ||
| 613 | /* Register sysfs hooks */ | 607 | /* Register sysfs hooks */ |
| 614 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) | 608 | if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) |
| @@ -671,7 +665,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
| 671 | i2c_set_clientdata(&data->client, data); | 665 | i2c_set_clientdata(&data->client, data); |
| 672 | platform_set_drvdata(pdev, data); | 666 | platform_set_drvdata(pdev, data); |
| 673 | 667 | ||
| 674 | if (lm78_read_value(&data->client, LM78_REG_CHIPID) & 0x80) { | 668 | if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) { |
| 675 | data->type = lm79; | 669 | data->type = lm79; |
| 676 | name = "lm79"; | 670 | name = "lm79"; |
| 677 | } else { | 671 | } else { |
| @@ -681,7 +675,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev) | |||
| 681 | strlcpy(data->client.name, name, I2C_NAME_SIZE); | 675 | strlcpy(data->client.name, name, I2C_NAME_SIZE); |
| 682 | 676 | ||
| 683 | /* Initialize the LM78 chip */ | 677 | /* Initialize the LM78 chip */ |
| 684 | lm78_init_client(&data->client); | 678 | lm78_init_device(data); |
| 685 | 679 | ||
| 686 | /* Register sysfs hooks */ | 680 | /* Register sysfs hooks */ |
| 687 | if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group)) | 681 | if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group)) |
| @@ -724,11 +718,12 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev) | |||
| 724 | separately. | 718 | separately. |
| 725 | We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, | 719 | We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, |
| 726 | would slow down the LM78 access and should not be necessary. */ | 720 | would slow down the LM78 access and should not be necessary. */ |
| 727 | static int lm78_read_value(struct i2c_client *client, u8 reg) | 721 | static int lm78_read_value(struct lm78_data *data, u8 reg) |
| 728 | { | 722 | { |
| 729 | int res; | 723 | struct i2c_client *client = &data->client; |
| 724 | |||
| 730 | if (!client->driver) { /* ISA device */ | 725 | if (!client->driver) { /* ISA device */ |
| 731 | struct lm78_data *data = i2c_get_clientdata(client); | 726 | int res; |
| 732 | mutex_lock(&data->lock); | 727 | mutex_lock(&data->lock); |
| 733 | outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); | 728 | outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); |
| 734 | res = inb_p(client->addr + LM78_DATA_REG_OFFSET); | 729 | res = inb_p(client->addr + LM78_DATA_REG_OFFSET); |
| @@ -745,10 +740,11 @@ static int lm78_read_value(struct i2c_client *client, u8 reg) | |||
| 745 | would slow down the LM78 access and should not be necessary. | 740 | would slow down the LM78 access and should not be necessary. |
| 746 | There are some ugly typecasts here, but the good new is - they should | 741 | There are some ugly typecasts here, but the good new is - they should |
| 747 | nowhere else be necessary! */ | 742 | nowhere else be necessary! */ |
| 748 | static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value) | 743 | static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) |
| 749 | { | 744 | { |
| 745 | struct i2c_client *client = &data->client; | ||
| 746 | |||
| 750 | if (!client->driver) { /* ISA device */ | 747 | if (!client->driver) { /* ISA device */ |
| 751 | struct lm78_data *data = i2c_get_clientdata(client); | ||
| 752 | mutex_lock(&data->lock); | 748 | mutex_lock(&data->lock); |
| 753 | outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); | 749 | outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); |
| 754 | outb_p(value, client->addr + LM78_DATA_REG_OFFSET); | 750 | outb_p(value, client->addr + LM78_DATA_REG_OFFSET); |
| @@ -758,21 +754,20 @@ static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value) | |||
| 758 | return i2c_smbus_write_byte_data(client, reg, value); | 754 | return i2c_smbus_write_byte_data(client, reg, value); |
| 759 | } | 755 | } |
| 760 | 756 | ||
| 761 | static void lm78_init_client(struct i2c_client *client) | 757 | static void lm78_init_device(struct lm78_data *data) |
| 762 | { | 758 | { |
| 763 | struct lm78_data *data = i2c_get_clientdata(client); | ||
| 764 | u8 config; | 759 | u8 config; |
| 765 | int i; | 760 | int i; |
| 766 | 761 | ||
| 767 | /* Start monitoring */ | 762 | /* Start monitoring */ |
| 768 | config = lm78_read_value(client, LM78_REG_CONFIG); | 763 | config = lm78_read_value(data, LM78_REG_CONFIG); |
| 769 | if ((config & 0x09) != 0x01) | 764 | if ((config & 0x09) != 0x01) |
| 770 | lm78_write_value(client, LM78_REG_CONFIG, | 765 | lm78_write_value(data, LM78_REG_CONFIG, |
| 771 | (config & 0xf7) | 0x01); | 766 | (config & 0xf7) | 0x01); |
| 772 | 767 | ||
| 773 | /* A few vars need to be filled upon startup */ | 768 | /* A few vars need to be filled upon startup */ |
| 774 | for (i = 0; i < 3; i++) { | 769 | for (i = 0; i < 3; i++) { |
| 775 | data->fan_min[i] = lm78_read_value(client, | 770 | data->fan_min[i] = lm78_read_value(data, |
| 776 | LM78_REG_FAN_MIN(i)); | 771 | LM78_REG_FAN_MIN(i)); |
| 777 | } | 772 | } |
| 778 | 773 | ||
| @@ -782,7 +777,6 @@ static void lm78_init_client(struct i2c_client *client) | |||
| 782 | static struct lm78_data *lm78_update_device(struct device *dev) | 777 | static struct lm78_data *lm78_update_device(struct device *dev) |
| 783 | { | 778 | { |
| 784 | struct lm78_data *data = dev_get_drvdata(dev); | 779 | struct lm78_data *data = dev_get_drvdata(dev); |
| 785 | struct i2c_client *client = &data->client; | ||
| 786 | int i; | 780 | int i; |
| 787 | 781 | ||
| 788 | mutex_lock(&data->update_lock); | 782 | mutex_lock(&data->update_lock); |
| @@ -794,35 +788,35 @@ static struct lm78_data *lm78_update_device(struct device *dev) | |||
| 794 | 788 | ||
| 795 | for (i = 0; i <= 6; i++) { | 789 | for (i = 0; i <= 6; i++) { |
| 796 | data->in[i] = | 790 | data->in[i] = |
| 797 | lm78_read_value(client, LM78_REG_IN(i)); | 791 | lm78_read_value(data, LM78_REG_IN(i)); |
| 798 | data->in_min[i] = | 792 | data->in_min[i] = |
| 799 | lm78_read_value(client, LM78_REG_IN_MIN(i)); | 793 | lm78_read_value(data, LM78_REG_IN_MIN(i)); |
| 800 | data->in_max[i] = | 794 | data->in_max[i] = |
| 801 | lm78_read_value(client, LM78_REG_IN_MAX(i)); | 795 | lm78_read_value(data, LM78_REG_IN_MAX(i)); |
| 802 | } | 796 | } |
| 803 | for (i = 0; i < 3; i++) { | 797 | for (i = 0; i < 3; i++) { |
| 804 | data->fan[i] = | 798 | data->fan[i] = |
| 805 | lm78_read_value(client, LM78_REG_FAN(i)); | 799 | lm78_read_value(data, LM78_REG_FAN(i)); |
| 806 | data->fan_min[i] = | 800 | data->fan_min[i] = |
| 807 | lm78_read_value(client, LM78_REG_FAN_MIN(i)); | 801 | lm78_read_value(data, LM78_REG_FAN_MIN(i)); |
| 808 | } | 802 | } |
| 809 | data->temp = lm78_read_value(client, LM78_REG_TEMP); | 803 | data->temp = lm78_read_value(data, LM78_REG_TEMP); |
| 810 | data->temp_over = | 804 | data->temp_over = |
| 811 | lm78_read_value(client, LM78_REG_TEMP_OVER); | 805 | lm78_read_value(data, LM78_REG_TEMP_OVER); |
| 812 | data->temp_hyst = | 806 | data->temp_hyst = |
| 813 | lm78_read_value(client, LM78_REG_TEMP_HYST); | 807 | lm78_read_value(data, LM78_REG_TEMP_HYST); |
| 814 | i = lm78_read_value(client, LM78_REG_VID_FANDIV); | 808 | i = lm78_read_value(data, LM78_REG_VID_FANDIV); |
| 815 | data->vid = i & 0x0f; | 809 | data->vid = i & 0x0f; |
| 816 | if (data->type == lm79) | 810 | if (data->type == lm79) |
| 817 | data->vid |= | 811 | data->vid |= |
| 818 | (lm78_read_value(client, LM78_REG_CHIPID) & | 812 | (lm78_read_value(data, LM78_REG_CHIPID) & |
| 819 | 0x01) << 4; | 813 | 0x01) << 4; |
| 820 | else | 814 | else |
| 821 | data->vid |= 0x10; | 815 | data->vid |= 0x10; |
| 822 | data->fan_div[0] = (i >> 4) & 0x03; | 816 | data->fan_div[0] = (i >> 4) & 0x03; |
| 823 | data->fan_div[1] = i >> 6; | 817 | data->fan_div[1] = i >> 6; |
| 824 | data->alarms = lm78_read_value(client, LM78_REG_ALARM1) + | 818 | data->alarms = lm78_read_value(data, LM78_REG_ALARM1) + |
| 825 | (lm78_read_value(client, LM78_REG_ALARM2) << 8); | 819 | (lm78_read_value(data, LM78_REG_ALARM2) << 8); |
| 826 | data->last_updated = jiffies; | 820 | data->last_updated = jiffies; |
| 827 | data->valid = 1; | 821 | data->valid = 1; |
| 828 | 822 | ||
