diff options
Diffstat (limited to 'drivers/hwmon')
-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 | ||