diff options
Diffstat (limited to 'drivers/hwmon/w83627hf.c')
-rw-r--r-- | drivers/hwmon/w83627hf.c | 134 |
1 files changed, 89 insertions, 45 deletions
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 7ea441d4da63..71fb7f1af8f5 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -28,6 +28,7 @@ | |||
28 | w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) | 28 | w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) |
29 | w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) | 29 | w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) |
30 | w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) | 30 | w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) |
31 | w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) | ||
31 | w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) | 32 | w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) |
32 | 33 | ||
33 | For other winbond chips, and for i2c support in the above chips, | 34 | For other winbond chips, and for i2c support in the above chips, |
@@ -46,6 +47,7 @@ | |||
46 | #include <linux/hwmon.h> | 47 | #include <linux/hwmon.h> |
47 | #include <linux/hwmon-vid.h> | 48 | #include <linux/hwmon-vid.h> |
48 | #include <linux/err.h> | 49 | #include <linux/err.h> |
50 | #include <linux/mutex.h> | ||
49 | #include <asm/io.h> | 51 | #include <asm/io.h> |
50 | #include "lm75.h" | 52 | #include "lm75.h" |
51 | 53 | ||
@@ -62,7 +64,7 @@ MODULE_PARM_DESC(force_i2c, | |||
62 | static unsigned short address; | 64 | static unsigned short address; |
63 | 65 | ||
64 | /* Insmod parameters */ | 66 | /* Insmod parameters */ |
65 | enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf }; | 67 | enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; |
66 | 68 | ||
67 | static int reset; | 69 | static int reset; |
68 | module_param(reset, bool, 0); | 70 | module_param(reset, bool, 0); |
@@ -100,6 +102,10 @@ static int VAL; /* The value to read/write */ | |||
100 | #define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ | 102 | #define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ |
101 | #define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ | 103 | #define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ |
102 | 104 | ||
105 | #define W83687THF_VID_EN 0x29 /* w83687thf only */ | ||
106 | #define W83687THF_VID_CFG 0xF0 /* w83687thf only */ | ||
107 | #define W83687THF_VID_DATA 0xF1 /* w83687thf only */ | ||
108 | |||
103 | static inline void | 109 | static inline void |
104 | superio_outb(int reg, int val) | 110 | superio_outb(int reg, int val) |
105 | { | 111 | { |
@@ -138,6 +144,7 @@ superio_exit(void) | |||
138 | #define W627THF_DEVID 0x82 | 144 | #define W627THF_DEVID 0x82 |
139 | #define W697_DEVID 0x60 | 145 | #define W697_DEVID 0x60 |
140 | #define W637_DEVID 0x70 | 146 | #define W637_DEVID 0x70 |
147 | #define W687THF_DEVID 0x85 | ||
141 | #define WINB_ACT_REG 0x30 | 148 | #define WINB_ACT_REG 0x30 |
142 | #define WINB_BASE_REG 0x60 | 149 | #define WINB_BASE_REG 0x60 |
143 | /* Constants specified below */ | 150 | /* Constants specified below */ |
@@ -201,11 +208,11 @@ superio_exit(void) | |||
201 | #define W83627HF_REG_PWM1 0x5A | 208 | #define W83627HF_REG_PWM1 0x5A |
202 | #define W83627HF_REG_PWM2 0x5B | 209 | #define W83627HF_REG_PWM2 0x5B |
203 | 210 | ||
204 | #define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */ | 211 | #define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ |
205 | #define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */ | 212 | #define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ |
206 | #define W83627THF_REG_PWM3 0x11 /* 637HF too */ | 213 | #define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ |
207 | 214 | ||
208 | #define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */ | 215 | #define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF/687THF too */ |
209 | 216 | ||
210 | static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; | 217 | static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; |
211 | static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, | 218 | static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, |
@@ -285,10 +292,10 @@ static inline u8 DIV_TO_REG(long val) | |||
285 | struct w83627hf_data { | 292 | struct w83627hf_data { |
286 | struct i2c_client client; | 293 | struct i2c_client client; |
287 | struct class_device *class_dev; | 294 | struct class_device *class_dev; |
288 | struct semaphore lock; | 295 | struct mutex lock; |
289 | enum chips type; | 296 | enum chips type; |
290 | 297 | ||
291 | struct semaphore update_lock; | 298 | struct mutex update_lock; |
292 | char valid; /* !=0 if following fields are valid */ | 299 | char valid; /* !=0 if following fields are valid */ |
293 | unsigned long last_updated; /* In jiffies */ | 300 | unsigned long last_updated; /* In jiffies */ |
294 | 301 | ||
@@ -318,16 +325,15 @@ struct w83627hf_data { | |||
318 | Default = 3435. | 325 | Default = 3435. |
319 | Other Betas unimplemented */ | 326 | Other Betas unimplemented */ |
320 | u8 vrm; | 327 | u8 vrm; |
321 | u8 vrm_ovt; /* Register value, 627thf & 637hf only */ | 328 | u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ |
322 | }; | 329 | }; |
323 | 330 | ||
324 | 331 | ||
325 | static int w83627hf_detect(struct i2c_adapter *adapter); | 332 | static int w83627hf_detect(struct i2c_adapter *adapter); |
326 | static int w83627hf_detach_client(struct i2c_client *client); | 333 | static int w83627hf_detach_client(struct i2c_client *client); |
327 | 334 | ||
328 | static int w83627hf_read_value(struct i2c_client *client, u16 register); | 335 | static int w83627hf_read_value(struct i2c_client *client, u16 reg); |
329 | static int w83627hf_write_value(struct i2c_client *client, u16 register, | 336 | static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value); |
330 | u16 value); | ||
331 | static struct w83627hf_data *w83627hf_update_device(struct device *dev); | 337 | static struct w83627hf_data *w83627hf_update_device(struct device *dev); |
332 | static void w83627hf_init_client(struct i2c_client *client); | 338 | static void w83627hf_init_client(struct i2c_client *client); |
333 | 339 | ||
@@ -360,12 +366,12 @@ store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | |||
360 | \ | 366 | \ |
361 | val = simple_strtoul(buf, NULL, 10); \ | 367 | val = simple_strtoul(buf, NULL, 10); \ |
362 | \ | 368 | \ |
363 | down(&data->update_lock); \ | 369 | mutex_lock(&data->update_lock); \ |
364 | data->in_##reg[nr] = IN_TO_REG(val); \ | 370 | data->in_##reg[nr] = IN_TO_REG(val); \ |
365 | w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \ | 371 | w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \ |
366 | data->in_##reg[nr]); \ | 372 | data->in_##reg[nr]); \ |
367 | \ | 373 | \ |
368 | up(&data->update_lock); \ | 374 | mutex_unlock(&data->update_lock); \ |
369 | return count; \ | 375 | return count; \ |
370 | } | 376 | } |
371 | store_in_reg(MIN, min) | 377 | store_in_reg(MIN, min) |
@@ -413,7 +419,8 @@ static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg) | |||
413 | long in0; | 419 | long in0; |
414 | 420 | ||
415 | if ((data->vrm_ovt & 0x01) && | 421 | if ((data->vrm_ovt & 0x01) && |
416 | (w83627thf == data->type || w83637hf == data->type)) | 422 | (w83627thf == data->type || w83637hf == data->type |
423 | || w83687thf == data->type)) | ||
417 | 424 | ||
418 | /* use VRM9 calculation */ | 425 | /* use VRM9 calculation */ |
419 | in0 = (long)((reg * 488 + 70000 + 50) / 100); | 426 | in0 = (long)((reg * 488 + 70000 + 50) / 100); |
@@ -451,10 +458,11 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a | |||
451 | 458 | ||
452 | val = simple_strtoul(buf, NULL, 10); | 459 | val = simple_strtoul(buf, NULL, 10); |
453 | 460 | ||
454 | down(&data->update_lock); | 461 | mutex_lock(&data->update_lock); |
455 | 462 | ||
456 | if ((data->vrm_ovt & 0x01) && | 463 | if ((data->vrm_ovt & 0x01) && |
457 | (w83627thf == data->type || w83637hf == data->type)) | 464 | (w83627thf == data->type || w83637hf == data->type |
465 | || w83687thf == data->type)) | ||
458 | 466 | ||
459 | /* use VRM9 calculation */ | 467 | /* use VRM9 calculation */ |
460 | data->in_min[0] = | 468 | data->in_min[0] = |
@@ -465,7 +473,7 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a | |||
465 | data->in_min[0] = IN_TO_REG(val); | 473 | data->in_min[0] = IN_TO_REG(val); |
466 | 474 | ||
467 | w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]); | 475 | w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]); |
468 | up(&data->update_lock); | 476 | mutex_unlock(&data->update_lock); |
469 | return count; | 477 | return count; |
470 | } | 478 | } |
471 | 479 | ||
@@ -478,10 +486,11 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a | |||
478 | 486 | ||
479 | val = simple_strtoul(buf, NULL, 10); | 487 | val = simple_strtoul(buf, NULL, 10); |
480 | 488 | ||
481 | down(&data->update_lock); | 489 | mutex_lock(&data->update_lock); |
482 | 490 | ||
483 | if ((data->vrm_ovt & 0x01) && | 491 | if ((data->vrm_ovt & 0x01) && |
484 | (w83627thf == data->type || w83637hf == data->type)) | 492 | (w83627thf == data->type || w83637hf == data->type |
493 | || w83687thf == data->type)) | ||
485 | 494 | ||
486 | /* use VRM9 calculation */ | 495 | /* use VRM9 calculation */ |
487 | data->in_max[0] = | 496 | data->in_max[0] = |
@@ -492,7 +501,7 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a | |||
492 | data->in_max[0] = IN_TO_REG(val); | 501 | data->in_max[0] = IN_TO_REG(val); |
493 | 502 | ||
494 | w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]); | 503 | w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]); |
495 | up(&data->update_lock); | 504 | mutex_unlock(&data->update_lock); |
496 | return count; | 505 | return count; |
497 | } | 506 | } |
498 | 507 | ||
@@ -529,13 +538,13 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr) | |||
529 | 538 | ||
530 | val = simple_strtoul(buf, NULL, 10); | 539 | val = simple_strtoul(buf, NULL, 10); |
531 | 540 | ||
532 | down(&data->update_lock); | 541 | mutex_lock(&data->update_lock); |
533 | data->fan_min[nr - 1] = | 542 | data->fan_min[nr - 1] = |
534 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); | 543 | FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); |
535 | w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr), | 544 | w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr), |
536 | data->fan_min[nr - 1]); | 545 | data->fan_min[nr - 1]); |
537 | 546 | ||
538 | up(&data->update_lock); | 547 | mutex_unlock(&data->update_lock); |
539 | return count; | 548 | return count; |
540 | } | 549 | } |
541 | 550 | ||
@@ -597,7 +606,7 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | |||
597 | \ | 606 | \ |
598 | val = simple_strtoul(buf, NULL, 10); \ | 607 | val = simple_strtoul(buf, NULL, 10); \ |
599 | \ | 608 | \ |
600 | down(&data->update_lock); \ | 609 | mutex_lock(&data->update_lock); \ |
601 | \ | 610 | \ |
602 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ | 611 | if (nr >= 2) { /* TEMP2 and TEMP3 */ \ |
603 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ | 612 | data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ |
@@ -609,7 +618,7 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ | |||
609 | data->temp_##reg); \ | 618 | data->temp_##reg); \ |
610 | } \ | 619 | } \ |
611 | \ | 620 | \ |
612 | up(&data->update_lock); \ | 621 | mutex_unlock(&data->update_lock); \ |
613 | return count; \ | 622 | return count; \ |
614 | } | 623 | } |
615 | store_temp_reg(OVER, max); | 624 | store_temp_reg(OVER, max); |
@@ -718,7 +727,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count, | |||
718 | 727 | ||
719 | val = simple_strtoul(buf, NULL, 10); | 728 | val = simple_strtoul(buf, NULL, 10); |
720 | 729 | ||
721 | down(&data->update_lock); | 730 | mutex_lock(&data->update_lock); |
722 | 731 | ||
723 | if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ | 732 | if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ |
724 | data->beep_mask = BEEP_MASK_TO_REG(val); | 733 | data->beep_mask = BEEP_MASK_TO_REG(val); |
@@ -736,7 +745,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count, | |||
736 | w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, | 745 | w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, |
737 | val2 | data->beep_enable << 7); | 746 | val2 | data->beep_enable << 7); |
738 | 747 | ||
739 | up(&data->update_lock); | 748 | mutex_unlock(&data->update_lock); |
740 | return count; | 749 | return count; |
741 | } | 750 | } |
742 | 751 | ||
@@ -783,7 +792,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
783 | u8 reg; | 792 | u8 reg; |
784 | unsigned long val = simple_strtoul(buf, NULL, 10); | 793 | unsigned long val = simple_strtoul(buf, NULL, 10); |
785 | 794 | ||
786 | down(&data->update_lock); | 795 | mutex_lock(&data->update_lock); |
787 | 796 | ||
788 | /* Save fan_min */ | 797 | /* Save fan_min */ |
789 | min = FAN_FROM_REG(data->fan_min[nr], | 798 | min = FAN_FROM_REG(data->fan_min[nr], |
@@ -805,7 +814,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
805 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 814 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
806 | w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 815 | w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); |
807 | 816 | ||
808 | up(&data->update_lock); | 817 | mutex_unlock(&data->update_lock); |
809 | return count; | 818 | return count; |
810 | } | 819 | } |
811 | 820 | ||
@@ -848,7 +857,7 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
848 | 857 | ||
849 | val = simple_strtoul(buf, NULL, 10); | 858 | val = simple_strtoul(buf, NULL, 10); |
850 | 859 | ||
851 | down(&data->update_lock); | 860 | mutex_lock(&data->update_lock); |
852 | 861 | ||
853 | if (data->type == w83627thf) { | 862 | if (data->type == w83627thf) { |
854 | /* bits 0-3 are reserved in 627THF */ | 863 | /* bits 0-3 are reserved in 627THF */ |
@@ -865,7 +874,7 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
865 | data->pwm[nr - 1]); | 874 | data->pwm[nr - 1]); |
866 | } | 875 | } |
867 | 876 | ||
868 | up(&data->update_lock); | 877 | mutex_unlock(&data->update_lock); |
869 | return count; | 878 | return count; |
870 | } | 879 | } |
871 | 880 | ||
@@ -907,7 +916,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
907 | 916 | ||
908 | val = simple_strtoul(buf, NULL, 10); | 917 | val = simple_strtoul(buf, NULL, 10); |
909 | 918 | ||
910 | down(&data->update_lock); | 919 | mutex_lock(&data->update_lock); |
911 | 920 | ||
912 | switch (val) { | 921 | switch (val) { |
913 | case 1: /* PII/Celeron diode */ | 922 | case 1: /* PII/Celeron diode */ |
@@ -941,7 +950,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) | |||
941 | break; | 950 | break; |
942 | } | 951 | } |
943 | 952 | ||
944 | up(&data->update_lock); | 953 | mutex_unlock(&data->update_lock); |
945 | return count; | 954 | return count; |
946 | } | 955 | } |
947 | 956 | ||
@@ -980,7 +989,8 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr) | |||
980 | if(val != W627_DEVID && | 989 | if(val != W627_DEVID && |
981 | val != W627THF_DEVID && | 990 | val != W627THF_DEVID && |
982 | val != W697_DEVID && | 991 | val != W697_DEVID && |
983 | val != W637_DEVID) { | 992 | val != W637_DEVID && |
993 | val != W687THF_DEVID) { | ||
984 | superio_exit(); | 994 | superio_exit(); |
985 | return -ENODEV; | 995 | return -ENODEV; |
986 | } | 996 | } |
@@ -1034,6 +1044,8 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1034 | kind = w83627thf; | 1044 | kind = w83627thf; |
1035 | else if(val == W637_DEVID) | 1045 | else if(val == W637_DEVID) |
1036 | kind = w83637hf; | 1046 | kind = w83637hf; |
1047 | else if (val == W687THF_DEVID) | ||
1048 | kind = w83687thf; | ||
1037 | else { | 1049 | else { |
1038 | dev_info(&adapter->dev, | 1050 | dev_info(&adapter->dev, |
1039 | "Unsupported chip (dev_id=0x%02X).\n", val); | 1051 | "Unsupported chip (dev_id=0x%02X).\n", val); |
@@ -1057,7 +1069,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1057 | new_client = &data->client; | 1069 | new_client = &data->client; |
1058 | i2c_set_clientdata(new_client, data); | 1070 | i2c_set_clientdata(new_client, data); |
1059 | new_client->addr = address; | 1071 | new_client->addr = address; |
1060 | init_MUTEX(&data->lock); | 1072 | mutex_init(&data->lock); |
1061 | new_client->adapter = adapter; | 1073 | new_client->adapter = adapter; |
1062 | new_client->driver = &w83627hf_driver; | 1074 | new_client->driver = &w83627hf_driver; |
1063 | new_client->flags = 0; | 1075 | new_client->flags = 0; |
@@ -1071,13 +1083,15 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1071 | client_name = "w83697hf"; | 1083 | client_name = "w83697hf"; |
1072 | } else if (kind == w83637hf) { | 1084 | } else if (kind == w83637hf) { |
1073 | client_name = "w83637hf"; | 1085 | client_name = "w83637hf"; |
1086 | } else if (kind == w83687thf) { | ||
1087 | client_name = "w83687thf"; | ||
1074 | } | 1088 | } |
1075 | 1089 | ||
1076 | /* Fill in the remaining client fields and put into the global list */ | 1090 | /* Fill in the remaining client fields and put into the global list */ |
1077 | strlcpy(new_client->name, client_name, I2C_NAME_SIZE); | 1091 | strlcpy(new_client->name, client_name, I2C_NAME_SIZE); |
1078 | data->type = kind; | 1092 | data->type = kind; |
1079 | data->valid = 0; | 1093 | data->valid = 0; |
1080 | init_MUTEX(&data->update_lock); | 1094 | mutex_init(&data->update_lock); |
1081 | 1095 | ||
1082 | /* Tell the I2C layer a new client has arrived */ | 1096 | /* Tell the I2C layer a new client has arrived */ |
1083 | if ((err = i2c_attach_client(new_client))) | 1097 | if ((err = i2c_attach_client(new_client))) |
@@ -1106,7 +1120,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1106 | device_create_file_in(new_client, 2); | 1120 | device_create_file_in(new_client, 2); |
1107 | device_create_file_in(new_client, 3); | 1121 | device_create_file_in(new_client, 3); |
1108 | device_create_file_in(new_client, 4); | 1122 | device_create_file_in(new_client, 4); |
1109 | if (kind != w83627thf && kind != w83637hf) { | 1123 | if (kind == w83627hf || kind == w83697hf) { |
1110 | device_create_file_in(new_client, 5); | 1124 | device_create_file_in(new_client, 5); |
1111 | device_create_file_in(new_client, 6); | 1125 | device_create_file_in(new_client, 6); |
1112 | } | 1126 | } |
@@ -1139,7 +1153,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter) | |||
1139 | 1153 | ||
1140 | device_create_file_pwm(new_client, 1); | 1154 | device_create_file_pwm(new_client, 1); |
1141 | device_create_file_pwm(new_client, 2); | 1155 | device_create_file_pwm(new_client, 2); |
1142 | if (kind == w83627thf || kind == w83637hf) | 1156 | if (kind == w83627thf || kind == w83637hf || kind == w83687thf) |
1143 | device_create_file_pwm(new_client, 3); | 1157 | device_create_file_pwm(new_client, 3); |
1144 | 1158 | ||
1145 | device_create_file_sensor(new_client, 1); | 1159 | device_create_file_sensor(new_client, 1); |
@@ -1187,7 +1201,7 @@ static int w83627hf_read_value(struct i2c_client *client, u16 reg) | |||
1187 | struct w83627hf_data *data = i2c_get_clientdata(client); | 1201 | struct w83627hf_data *data = i2c_get_clientdata(client); |
1188 | int res, word_sized; | 1202 | int res, word_sized; |
1189 | 1203 | ||
1190 | down(&data->lock); | 1204 | mutex_lock(&data->lock); |
1191 | word_sized = (((reg & 0xff00) == 0x100) | 1205 | word_sized = (((reg & 0xff00) == 0x100) |
1192 | || ((reg & 0xff00) == 0x200)) | 1206 | || ((reg & 0xff00) == 0x200)) |
1193 | && (((reg & 0x00ff) == 0x50) | 1207 | && (((reg & 0x00ff) == 0x50) |
@@ -1213,7 +1227,7 @@ static int w83627hf_read_value(struct i2c_client *client, u16 reg) | |||
1213 | client->addr + W83781D_ADDR_REG_OFFSET); | 1227 | client->addr + W83781D_ADDR_REG_OFFSET); |
1214 | outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); | 1228 | outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); |
1215 | } | 1229 | } |
1216 | up(&data->lock); | 1230 | mutex_unlock(&data->lock); |
1217 | return res; | 1231 | return res; |
1218 | } | 1232 | } |
1219 | 1233 | ||
@@ -1247,12 +1261,39 @@ exit: | |||
1247 | return res; | 1261 | return res; |
1248 | } | 1262 | } |
1249 | 1263 | ||
1264 | static int w83687thf_read_vid(struct i2c_client *client) | ||
1265 | { | ||
1266 | int res = 0xff; | ||
1267 | |||
1268 | superio_enter(); | ||
1269 | superio_select(W83627HF_LD_HWM); | ||
1270 | |||
1271 | /* Make sure these GPIO pins are enabled */ | ||
1272 | if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) { | ||
1273 | dev_dbg(&client->dev, "VID disabled, no VID function\n"); | ||
1274 | goto exit; | ||
1275 | } | ||
1276 | |||
1277 | /* Make sure the pins are configured for input */ | ||
1278 | if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) { | ||
1279 | dev_dbg(&client->dev, "VID configured as output, " | ||
1280 | "no VID function\n"); | ||
1281 | goto exit; | ||
1282 | } | ||
1283 | |||
1284 | res = superio_inb(W83687THF_VID_DATA) & 0x3f; | ||
1285 | |||
1286 | exit: | ||
1287 | superio_exit(); | ||
1288 | return res; | ||
1289 | } | ||
1290 | |||
1250 | static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) | 1291 | static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) |
1251 | { | 1292 | { |
1252 | struct w83627hf_data *data = i2c_get_clientdata(client); | 1293 | struct w83627hf_data *data = i2c_get_clientdata(client); |
1253 | int word_sized; | 1294 | int word_sized; |
1254 | 1295 | ||
1255 | down(&data->lock); | 1296 | mutex_lock(&data->lock); |
1256 | word_sized = (((reg & 0xff00) == 0x100) | 1297 | word_sized = (((reg & 0xff00) == 0x100) |
1257 | || ((reg & 0xff00) == 0x200)) | 1298 | || ((reg & 0xff00) == 0x200)) |
1258 | && (((reg & 0x00ff) == 0x53) | 1299 | && (((reg & 0x00ff) == 0x53) |
@@ -1277,7 +1318,7 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) | |||
1277 | client->addr + W83781D_ADDR_REG_OFFSET); | 1318 | client->addr + W83781D_ADDR_REG_OFFSET); |
1278 | outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); | 1319 | outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); |
1279 | } | 1320 | } |
1280 | up(&data->lock); | 1321 | mutex_unlock(&data->lock); |
1281 | return 0; | 1322 | return 0; |
1282 | } | 1323 | } |
1283 | 1324 | ||
@@ -1324,10 +1365,13 @@ static void w83627hf_init_client(struct i2c_client *client) | |||
1324 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); | 1365 | data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); |
1325 | } else if (w83627thf == data->type) { | 1366 | } else if (w83627thf == data->type) { |
1326 | data->vid = w83627thf_read_gpio5(client); | 1367 | data->vid = w83627thf_read_gpio5(client); |
1368 | } else if (w83687thf == data->type) { | ||
1369 | data->vid = w83687thf_read_vid(client); | ||
1327 | } | 1370 | } |
1328 | 1371 | ||
1329 | /* Read VRM & OVT Config only once */ | 1372 | /* Read VRM & OVT Config only once */ |
1330 | if (w83627thf == data->type || w83637hf == data->type) { | 1373 | if (w83627thf == data->type || w83637hf == data->type |
1374 | || w83687thf == data->type) { | ||
1331 | data->vrm_ovt = | 1375 | data->vrm_ovt = |
1332 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); | 1376 | w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); |
1333 | } | 1377 | } |
@@ -1387,14 +1431,14 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1387 | struct w83627hf_data *data = i2c_get_clientdata(client); | 1431 | struct w83627hf_data *data = i2c_get_clientdata(client); |
1388 | int i; | 1432 | int i; |
1389 | 1433 | ||
1390 | down(&data->update_lock); | 1434 | mutex_lock(&data->update_lock); |
1391 | 1435 | ||
1392 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | 1436 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
1393 | || !data->valid) { | 1437 | || !data->valid) { |
1394 | for (i = 0; i <= 8; i++) { | 1438 | for (i = 0; i <= 8; i++) { |
1395 | /* skip missing sensors */ | 1439 | /* skip missing sensors */ |
1396 | if (((data->type == w83697hf) && (i == 1)) || | 1440 | if (((data->type == w83697hf) && (i == 1)) || |
1397 | ((data->type == w83627thf || data->type == w83637hf) | 1441 | ((data->type != w83627hf && data->type != w83697hf) |
1398 | && (i == 5 || i == 6))) | 1442 | && (i == 5 || i == 6))) |
1399 | continue; | 1443 | continue; |
1400 | data->in[i] = | 1444 | data->in[i] = |
@@ -1470,7 +1514,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1470 | data->valid = 1; | 1514 | data->valid = 1; |
1471 | } | 1515 | } |
1472 | 1516 | ||
1473 | up(&data->update_lock); | 1517 | mutex_unlock(&data->update_lock); |
1474 | 1518 | ||
1475 | return data; | 1519 | return data; |
1476 | } | 1520 | } |