diff options
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 261 |
1 files changed, 179 insertions, 82 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index a658d62c5e10..a25350cf9554 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -1,50 +1,49 @@ | |||
1 | /* | 1 | /* |
2 | w83627ehf - Driver for the hardware monitoring functionality of | 2 | * w83627ehf - Driver for the hardware monitoring functionality of |
3 | the Winbond W83627EHF Super-I/O chip | 3 | * the Winbond W83627EHF Super-I/O chip |
4 | Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2005-2011 Jean Delvare <khali@linux-fr.org> |
5 | Copyright (C) 2006 Yuan Mu (Winbond), | 5 | * Copyright (C) 2006 Yuan Mu (Winbond), |
6 | Rudolf Marek <r.marek@assembler.cz> | 6 | * Rudolf Marek <r.marek@assembler.cz> |
7 | David Hubbard <david.c.hubbard@gmail.com> | 7 | * David Hubbard <david.c.hubbard@gmail.com> |
8 | Daniel J Blueman <daniel.blueman@gmail.com> | 8 | * Daniel J Blueman <daniel.blueman@gmail.com> |
9 | Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) | 9 | * Copyright (C) 2010 Sheng-Yuan Huang (Nuvoton) (PS00) |
10 | 10 | * | |
11 | Shamelessly ripped from the w83627hf driver | 11 | * Shamelessly ripped from the w83627hf driver |
12 | Copyright (C) 2003 Mark Studebaker | 12 | * Copyright (C) 2003 Mark Studebaker |
13 | 13 | * | |
14 | Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help | 14 | * Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help |
15 | in testing and debugging this driver. | 15 | * in testing and debugging this driver. |
16 | 16 | * | |
17 | This driver also supports the W83627EHG, which is the lead-free | 17 | * This driver also supports the W83627EHG, which is the lead-free |
18 | version of the W83627EHF. | 18 | * version of the W83627EHF. |
19 | 19 | * | |
20 | This program is free software; you can redistribute it and/or modify | 20 | * This program is free software; you can redistribute it and/or modify |
21 | it under the terms of the GNU General Public License as published by | 21 | * it under the terms of the GNU General Public License as published by |
22 | the Free Software Foundation; either version 2 of the License, or | 22 | * the Free Software Foundation; either version 2 of the License, or |
23 | (at your option) any later version. | 23 | * (at your option) any later version. |
24 | 24 | * | |
25 | This program is distributed in the hope that it will be useful, | 25 | * This program is distributed in the hope that it will be useful, |
26 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
28 | GNU General Public License for more details. | 28 | * GNU General Public License for more details. |
29 | 29 | * | |
30 | You should have received a copy of the GNU General Public License | 30 | * You should have received a copy of the GNU General Public License |
31 | along with this program; if not, write to the Free Software | 31 | * along with this program; if not, write to the Free Software |
32 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 32 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
33 | 33 | * | |
34 | 34 | * Supports the following chips: | |
35 | Supports the following chips: | 35 | * |
36 | 36 | * Chip #vin #fan #pwm #temp chip IDs man ID | |
37 | Chip #vin #fan #pwm #temp chip IDs man ID | 37 | * w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 |
38 | w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 | 38 | * 0x8860 0xa1 |
39 | 0x8860 0xa1 | 39 | * w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 |
40 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | 40 | * w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 |
41 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 | 41 | * w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 |
42 | w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 | 42 | * w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 |
43 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 | 43 | * w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 |
44 | w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 | 44 | * nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 |
45 | nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 | 45 | * nct6776f 9 5 3 9 0xC330 0xc1 0x5ca3 |
46 | nct6776f 9 5 3 9 0xC330 0xc1 0x5ca3 | 46 | */ |
47 | */ | ||
48 | 47 | ||
49 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 48 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
50 | 49 | ||
@@ -164,11 +163,13 @@ superio_exit(int ioreg) | |||
164 | #define W83627EHF_REG_BANK 0x4E | 163 | #define W83627EHF_REG_BANK 0x4E |
165 | #define W83627EHF_REG_CONFIG 0x40 | 164 | #define W83627EHF_REG_CONFIG 0x40 |
166 | 165 | ||
167 | /* Not currently used: | 166 | /* |
167 | * Not currently used: | ||
168 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. | 168 | * REG_MAN_ID has the value 0x5ca3 for all supported chips. |
169 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. | 169 | * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model. |
170 | * REG_MAN_ID is at port 0x4f | 170 | * REG_MAN_ID is at port 0x4f |
171 | * REG_CHIP_ID is at port 0x58 */ | 171 | * REG_CHIP_ID is at port 0x58 |
172 | */ | ||
172 | 173 | ||
173 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; | 174 | static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 }; |
174 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; | 175 | static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c }; |
@@ -239,6 +240,8 @@ static const u16 W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B[] = { 0x67, 0x69, 0x6b }; | |||
239 | static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[] | 240 | static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[] |
240 | = { 0x68, 0x6a, 0x6c }; | 241 | = { 0x68, 0x6a, 0x6c }; |
241 | 242 | ||
243 | static const u16 W83627EHF_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; | ||
244 | |||
242 | static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301 }; | 245 | static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301 }; |
243 | static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302 }; | 246 | static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302 }; |
244 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 0x105, 0x205, 0x305 }; | 247 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 0x105, 0x205, 0x305 }; |
@@ -393,8 +396,10 @@ div_from_reg(u8 reg) | |||
393 | return 1 << reg; | 396 | return 1 << reg; |
394 | } | 397 | } |
395 | 398 | ||
396 | /* Some of the voltage inputs have internal scaling, the tables below | 399 | /* |
397 | * contain 8 (the ADC LSB in mV) * scaling factor * 100 */ | 400 | * Some of the voltage inputs have internal scaling, the tables below |
401 | * contain 8 (the ADC LSB in mV) * scaling factor * 100 | ||
402 | */ | ||
398 | static const u16 scale_in_common[10] = { | 403 | static const u16 scale_in_common[10] = { |
399 | 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800 | 404 | 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800 |
400 | }; | 405 | }; |
@@ -462,6 +467,7 @@ struct w83627ehf_data { | |||
462 | u8 has_fan_min; /* some fans don't have min register */ | 467 | u8 has_fan_min; /* some fans don't have min register */ |
463 | bool has_fan_div; | 468 | bool has_fan_div; |
464 | u8 temp_type[3]; | 469 | u8 temp_type[3]; |
470 | s8 temp_offset[3]; | ||
465 | s16 temp[9]; | 471 | s16 temp[9]; |
466 | s16 temp_max[9]; | 472 | s16 temp_max[9]; |
467 | s16 temp_max_hyst[9]; | 473 | s16 temp_max_hyst[9]; |
@@ -470,12 +476,13 @@ struct w83627ehf_data { | |||
470 | 476 | ||
471 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ | 477 | u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ |
472 | u8 pwm_enable[4]; /* 1->manual | 478 | u8 pwm_enable[4]; /* 1->manual |
473 | 2->thermal cruise mode (also called SmartFan I) | 479 | * 2->thermal cruise mode (also called SmartFan I) |
474 | 3->fan speed cruise mode | 480 | * 3->fan speed cruise mode |
475 | 4->variable thermal cruise (also called | 481 | * 4->variable thermal cruise (also called |
476 | SmartFan III) | 482 | * SmartFan III) |
477 | 5->enhanced variable thermal cruise (also called | 483 | * 5->enhanced variable thermal cruise (also called |
478 | SmartFan IV) */ | 484 | * SmartFan IV) |
485 | */ | ||
479 | u8 pwm_enable_orig[4]; /* original value of pwm_enable */ | 486 | u8 pwm_enable_orig[4]; /* original value of pwm_enable */ |
480 | u8 pwm_num; /* number of pwm */ | 487 | u8 pwm_num; /* number of pwm */ |
481 | u8 pwm[4]; | 488 | u8 pwm[4]; |
@@ -492,6 +499,7 @@ struct w83627ehf_data { | |||
492 | u8 vrm; | 499 | u8 vrm; |
493 | 500 | ||
494 | u16 have_temp; | 501 | u16 have_temp; |
502 | u16 have_temp_offset; | ||
495 | u8 in6_skip:1; | 503 | u8 in6_skip:1; |
496 | u8 temp3_val_only:1; | 504 | u8 temp3_val_only:1; |
497 | }; | 505 | }; |
@@ -816,9 +824,11 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
816 | data->fan_min[i] = w83627ehf_read_value(data, | 824 | data->fan_min[i] = w83627ehf_read_value(data, |
817 | data->REG_FAN_MIN[i]); | 825 | data->REG_FAN_MIN[i]); |
818 | 826 | ||
819 | /* If we failed to measure the fan speed and clock | 827 | /* |
820 | divider can be increased, let's try that for next | 828 | * If we failed to measure the fan speed and clock |
821 | time */ | 829 | * divider can be increased, let's try that for next |
830 | * time | ||
831 | */ | ||
822 | if (data->has_fan_div | 832 | if (data->has_fan_div |
823 | && (reg >= 0xff || (sio_data->kind == nct6775 | 833 | && (reg >= 0xff || (sio_data->kind == nct6775 |
824 | && reg == 0x00)) | 834 | && reg == 0x00)) |
@@ -887,6 +897,10 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
887 | data->temp_max_hyst[i] | 897 | data->temp_max_hyst[i] |
888 | = w83627ehf_read_temp(data, | 898 | = w83627ehf_read_temp(data, |
889 | data->reg_temp_hyst[i]); | 899 | data->reg_temp_hyst[i]); |
900 | if (data->have_temp_offset & (1 << i)) | ||
901 | data->temp_offset[i] | ||
902 | = w83627ehf_read_value(data, | ||
903 | W83627EHF_REG_TEMP_OFFSET[i]); | ||
890 | } | 904 | } |
891 | 905 | ||
892 | data->alarms = w83627ehf_read_value(data, | 906 | data->alarms = w83627ehf_read_value(data, |
@@ -1081,25 +1095,31 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1081 | new_div = data->fan_div[nr]; /* No change */ | 1095 | new_div = data->fan_div[nr]; /* No change */ |
1082 | dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); | 1096 | dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1); |
1083 | } else if ((reg = 1350000U / val) >= 128 * 255) { | 1097 | } else if ((reg = 1350000U / val) >= 128 * 255) { |
1084 | /* Speed below this value cannot possibly be represented, | 1098 | /* |
1085 | even with the highest divider (128) */ | 1099 | * Speed below this value cannot possibly be represented, |
1100 | * even with the highest divider (128) | ||
1101 | */ | ||
1086 | data->fan_min[nr] = 254; | 1102 | data->fan_min[nr] = 254; |
1087 | new_div = 7; /* 128 == (1 << 7) */ | 1103 | new_div = 7; /* 128 == (1 << 7) */ |
1088 | dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " | 1104 | dev_warn(dev, "fan%u low limit %lu below minimum %u, set to " |
1089 | "minimum\n", nr + 1, val, | 1105 | "minimum\n", nr + 1, val, |
1090 | data->fan_from_reg_min(254, 7)); | 1106 | data->fan_from_reg_min(254, 7)); |
1091 | } else if (!reg) { | 1107 | } else if (!reg) { |
1092 | /* Speed above this value cannot possibly be represented, | 1108 | /* |
1093 | even with the lowest divider (1) */ | 1109 | * Speed above this value cannot possibly be represented, |
1110 | * even with the lowest divider (1) | ||
1111 | */ | ||
1094 | data->fan_min[nr] = 1; | 1112 | data->fan_min[nr] = 1; |
1095 | new_div = 0; /* 1 == (1 << 0) */ | 1113 | new_div = 0; /* 1 == (1 << 0) */ |
1096 | dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " | 1114 | dev_warn(dev, "fan%u low limit %lu above maximum %u, set to " |
1097 | "maximum\n", nr + 1, val, | 1115 | "maximum\n", nr + 1, val, |
1098 | data->fan_from_reg_min(1, 0)); | 1116 | data->fan_from_reg_min(1, 0)); |
1099 | } else { | 1117 | } else { |
1100 | /* Automatically pick the best divider, i.e. the one such | 1118 | /* |
1101 | that the min limit will correspond to a register value | 1119 | * Automatically pick the best divider, i.e. the one such |
1102 | in the 96..192 range */ | 1120 | * that the min limit will correspond to a register value |
1121 | * in the 96..192 range | ||
1122 | */ | ||
1103 | new_div = 0; | 1123 | new_div = 0; |
1104 | while (reg > 192 && new_div < 7) { | 1124 | while (reg > 192 && new_div < 7) { |
1105 | reg >>= 1; | 1125 | reg >>= 1; |
@@ -1108,8 +1128,10 @@ store_fan_min(struct device *dev, struct device_attribute *attr, | |||
1108 | data->fan_min[nr] = reg; | 1128 | data->fan_min[nr] = reg; |
1109 | } | 1129 | } |
1110 | 1130 | ||
1111 | /* Write both the fan clock divider (if it changed) and the new | 1131 | /* |
1112 | fan min (unconditionally) */ | 1132 | * Write both the fan clock divider (if it changed) and the new |
1133 | * fan min (unconditionally) | ||
1134 | */ | ||
1113 | if (new_div != data->fan_div[nr]) { | 1135 | if (new_div != data->fan_div[nr]) { |
1114 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", | 1136 | dev_dbg(dev, "fan%u clock divider changed from %u to %u\n", |
1115 | nr + 1, div_from_reg(data->fan_div[nr]), | 1137 | nr + 1, div_from_reg(data->fan_div[nr]), |
@@ -1212,6 +1234,39 @@ store_temp_reg(reg_temp_over, temp_max); | |||
1212 | store_temp_reg(reg_temp_hyst, temp_max_hyst); | 1234 | store_temp_reg(reg_temp_hyst, temp_max_hyst); |
1213 | 1235 | ||
1214 | static ssize_t | 1236 | static ssize_t |
1237 | show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) | ||
1238 | { | ||
1239 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | ||
1240 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
1241 | |||
1242 | return sprintf(buf, "%d\n", | ||
1243 | data->temp_offset[sensor_attr->index] * 1000); | ||
1244 | } | ||
1245 | |||
1246 | static ssize_t | ||
1247 | store_temp_offset(struct device *dev, struct device_attribute *attr, | ||
1248 | const char *buf, size_t count) | ||
1249 | { | ||
1250 | struct w83627ehf_data *data = dev_get_drvdata(dev); | ||
1251 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
1252 | int nr = sensor_attr->index; | ||
1253 | long val; | ||
1254 | int err; | ||
1255 | |||
1256 | err = kstrtol(buf, 10, &val); | ||
1257 | if (err < 0) | ||
1258 | return err; | ||
1259 | |||
1260 | val = SENSORS_LIMIT(DIV_ROUND_CLOSEST(val, 1000), -128, 127); | ||
1261 | |||
1262 | mutex_lock(&data->update_lock); | ||
1263 | data->temp_offset[nr] = val; | ||
1264 | w83627ehf_write_value(data, W83627EHF_REG_TEMP_OFFSET[nr], val); | ||
1265 | mutex_unlock(&data->update_lock); | ||
1266 | return count; | ||
1267 | } | ||
1268 | |||
1269 | static ssize_t | ||
1215 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) | 1270 | show_temp_type(struct device *dev, struct device_attribute *attr, char *buf) |
1216 | { | 1271 | { |
1217 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | 1272 | struct w83627ehf_data *data = w83627ehf_update_device(dev); |
@@ -1298,6 +1353,15 @@ static struct sensor_device_attribute sda_temp_type[] = { | |||
1298 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | 1353 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), |
1299 | }; | 1354 | }; |
1300 | 1355 | ||
1356 | static struct sensor_device_attribute sda_temp_offset[] = { | ||
1357 | SENSOR_ATTR(temp1_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1358 | store_temp_offset, 0), | ||
1359 | SENSOR_ATTR(temp2_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1360 | store_temp_offset, 1), | ||
1361 | SENSOR_ATTR(temp3_offset, S_IRUGO | S_IWUSR, show_temp_offset, | ||
1362 | store_temp_offset, 2), | ||
1363 | }; | ||
1364 | |||
1301 | #define show_pwm_reg(reg) \ | 1365 | #define show_pwm_reg(reg) \ |
1302 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ | 1366 | static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ |
1303 | char *buf) \ | 1367 | char *buf) \ |
@@ -1736,8 +1800,10 @@ static struct sensor_device_attribute_2 sda_caseopen[] = { | |||
1736 | 1800 | ||
1737 | static void w83627ehf_device_remove_files(struct device *dev) | 1801 | static void w83627ehf_device_remove_files(struct device *dev) |
1738 | { | 1802 | { |
1739 | /* some entries in the following arrays may not have been used in | 1803 | /* |
1740 | * device_create_file(), but device_remove_file() will ignore them */ | 1804 | * some entries in the following arrays may not have been used in |
1805 | * device_create_file(), but device_remove_file() will ignore them | ||
1806 | */ | ||
1741 | int i; | 1807 | int i; |
1742 | struct w83627ehf_data *data = dev_get_drvdata(dev); | 1808 | struct w83627ehf_data *data = dev_get_drvdata(dev); |
1743 | 1809 | ||
@@ -1788,6 +1854,7 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1788 | continue; | 1854 | continue; |
1789 | device_remove_file(dev, &sda_temp_alarm[i].dev_attr); | 1855 | device_remove_file(dev, &sda_temp_alarm[i].dev_attr); |
1790 | device_remove_file(dev, &sda_temp_type[i].dev_attr); | 1856 | device_remove_file(dev, &sda_temp_type[i].dev_attr); |
1857 | device_remove_file(dev, &sda_temp_offset[i].dev_attr); | ||
1791 | } | 1858 | } |
1792 | 1859 | ||
1793 | device_remove_file(dev, &sda_caseopen[0].dev_attr); | 1860 | device_remove_file(dev, &sda_caseopen[0].dev_attr); |
@@ -2110,6 +2177,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2110 | } else { | 2177 | } else { |
2111 | data->temp_label = nct6775_temp_label; | 2178 | data->temp_label = nct6775_temp_label; |
2112 | } | 2179 | } |
2180 | data->have_temp_offset = data->have_temp & 0x07; | ||
2181 | for (i = 0; i < 3; i++) { | ||
2182 | if (data->temp_src[i] > 3) | ||
2183 | data->have_temp_offset &= ~(1 << i); | ||
2184 | } | ||
2113 | } else if (sio_data->kind == w83667hg_b) { | 2185 | } else if (sio_data->kind == w83667hg_b) { |
2114 | u8 reg; | 2186 | u8 reg; |
2115 | 2187 | ||
@@ -2152,6 +2224,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2152 | data->in6_skip = 1; | 2224 | data->in6_skip = 1; |
2153 | 2225 | ||
2154 | data->temp_label = w83667hg_b_temp_label; | 2226 | data->temp_label = w83667hg_b_temp_label; |
2227 | data->have_temp_offset = data->have_temp & 0x07; | ||
2228 | for (i = 0; i < 3; i++) { | ||
2229 | if (data->temp_src[i] > 2) | ||
2230 | data->have_temp_offset &= ~(1 << i); | ||
2231 | } | ||
2155 | } else if (sio_data->kind == w83627uhg) { | 2232 | } else if (sio_data->kind == w83627uhg) { |
2156 | u8 reg; | 2233 | u8 reg; |
2157 | 2234 | ||
@@ -2188,6 +2265,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2188 | data->in6_skip = 1; /* No VIN3 */ | 2265 | data->in6_skip = 1; /* No VIN3 */ |
2189 | 2266 | ||
2190 | data->temp_label = w83667hg_b_temp_label; | 2267 | data->temp_label = w83667hg_b_temp_label; |
2268 | data->have_temp_offset = data->have_temp & 0x03; | ||
2269 | for (i = 0; i < 3; i++) { | ||
2270 | if (data->temp_src[i] > 1) | ||
2271 | data->have_temp_offset &= ~(1 << i); | ||
2272 | } | ||
2191 | } else { | 2273 | } else { |
2192 | w83627ehf_set_temp_reg_ehf(data, 3); | 2274 | w83627ehf_set_temp_reg_ehf(data, 3); |
2193 | 2275 | ||
@@ -2207,6 +2289,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2207 | else | 2289 | else |
2208 | data->in6_skip = 1; | 2290 | data->in6_skip = 1; |
2209 | } | 2291 | } |
2292 | data->have_temp_offset = data->have_temp & 0x07; | ||
2210 | } | 2293 | } |
2211 | 2294 | ||
2212 | if (sio_data->kind == nct6775) { | 2295 | if (sio_data->kind == nct6775) { |
@@ -2279,9 +2362,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2279 | /* Read VID value */ | 2362 | /* Read VID value */ |
2280 | if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b || | 2363 | if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b || |
2281 | sio_data->kind == nct6775 || sio_data->kind == nct6776) { | 2364 | sio_data->kind == nct6775 || sio_data->kind == nct6776) { |
2282 | /* W83667HG has different pins for VID input and output, so | 2365 | /* |
2283 | we can get the VID input values directly at logical device D | 2366 | * W83667HG has different pins for VID input and output, so |
2284 | 0xe3. */ | 2367 | * we can get the VID input values directly at logical device D |
2368 | * 0xe3. | ||
2369 | */ | ||
2285 | superio_select(sio_data->sioreg, W83667HG_LD_VID); | 2370 | superio_select(sio_data->sioreg, W83667HG_LD_VID); |
2286 | data->vid = superio_inb(sio_data->sioreg, 0xe3); | 2371 | data->vid = superio_inb(sio_data->sioreg, 0xe3); |
2287 | err = device_create_file(dev, &dev_attr_cpu0_vid); | 2372 | err = device_create_file(dev, &dev_attr_cpu0_vid); |
@@ -2290,11 +2375,13 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2290 | } else if (sio_data->kind != w83627uhg) { | 2375 | } else if (sio_data->kind != w83627uhg) { |
2291 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); | 2376 | superio_select(sio_data->sioreg, W83627EHF_LD_HWM); |
2292 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { | 2377 | if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { |
2293 | /* Set VID input sensibility if needed. In theory the | 2378 | /* |
2294 | BIOS should have set it, but in practice it's not | 2379 | * Set VID input sensibility if needed. In theory the |
2295 | always the case. We only do it for the W83627EHF/EHG | 2380 | * BIOS should have set it, but in practice it's not |
2296 | because the W83627DHG is more complex in this | 2381 | * always the case. We only do it for the W83627EHF/EHG |
2297 | respect. */ | 2382 | * because the W83627DHG is more complex in this |
2383 | * respect. | ||
2384 | */ | ||
2298 | if (sio_data->kind == w83627ehf) { | 2385 | if (sio_data->kind == w83627ehf) { |
2299 | en_vrm10 = superio_inb(sio_data->sioreg, | 2386 | en_vrm10 = superio_inb(sio_data->sioreg, |
2300 | SIO_REG_EN_VRM10); | 2387 | SIO_REG_EN_VRM10); |
@@ -2468,6 +2555,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2468 | || (err = device_create_file(dev, | 2555 | || (err = device_create_file(dev, |
2469 | &sda_temp_type[i].dev_attr))) | 2556 | &sda_temp_type[i].dev_attr))) |
2470 | goto exit_remove; | 2557 | goto exit_remove; |
2558 | if (data->have_temp_offset & (1 << i)) { | ||
2559 | err = device_create_file(dev, | ||
2560 | &sda_temp_offset[i].dev_attr); | ||
2561 | if (err) | ||
2562 | goto exit_remove; | ||
2563 | } | ||
2471 | } | 2564 | } |
2472 | 2565 | ||
2473 | err = device_create_file(dev, &sda_caseopen[0].dev_attr); | 2566 | err = device_create_file(dev, &sda_caseopen[0].dev_attr); |
@@ -2616,10 +2709,12 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr, | |||
2616 | return 0; | 2709 | return 0; |
2617 | } | 2710 | } |
2618 | 2711 | ||
2619 | /* when Super-I/O functions move to a separate file, the Super-I/O | 2712 | /* |
2713 | * when Super-I/O functions move to a separate file, the Super-I/O | ||
2620 | * bus will manage the lifetime of the device and this module will only keep | 2714 | * bus will manage the lifetime of the device and this module will only keep |
2621 | * track of the w83627ehf driver. But since we platform_device_alloc(), we | 2715 | * track of the w83627ehf driver. But since we platform_device_alloc(), we |
2622 | * must keep track of the device */ | 2716 | * must keep track of the device |
2717 | */ | ||
2623 | static struct platform_device *pdev; | 2718 | static struct platform_device *pdev; |
2624 | 2719 | ||
2625 | static int __init sensors_w83627ehf_init(void) | 2720 | static int __init sensors_w83627ehf_init(void) |
@@ -2629,11 +2724,13 @@ static int __init sensors_w83627ehf_init(void) | |||
2629 | struct resource res; | 2724 | struct resource res; |
2630 | struct w83627ehf_sio_data sio_data; | 2725 | struct w83627ehf_sio_data sio_data; |
2631 | 2726 | ||
2632 | /* initialize sio_data->kind and sio_data->sioreg. | 2727 | /* |
2728 | * initialize sio_data->kind and sio_data->sioreg. | ||
2633 | * | 2729 | * |
2634 | * when Super-I/O functions move to a separate file, the Super-I/O | 2730 | * when Super-I/O functions move to a separate file, the Super-I/O |
2635 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a | 2731 | * driver will probe 0x2e and 0x4e and auto-detect the presence of a |
2636 | * w83627ehf hardware monitor, and call probe() */ | 2732 | * w83627ehf hardware monitor, and call probe() |
2733 | */ | ||
2637 | if (w83627ehf_find(0x2e, &address, &sio_data) && | 2734 | if (w83627ehf_find(0x2e, &address, &sio_data) && |
2638 | w83627ehf_find(0x4e, &address, &sio_data)) | 2735 | w83627ehf_find(0x4e, &address, &sio_data)) |
2639 | return -ENODEV; | 2736 | return -ENODEV; |