Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
hwmon/w83793: Hide invalid VID readings
hwmon/w83793: Fix the fan input detection
hwmon/w83793: Ignore disabled temperature channels
hwmon: Fix the VRD 11 decoding
hwmon/w83793: Remove the description of AMDSI and update the voltage formula

+113 -24
+2 -6
Documentation/hwmon/w83793
··· 45 45 temp5-6 have a 1 degree Celsiis resolution. 46 46 47 47 * Temperature sensor types 48 - Temp1-4 have 3 possible types. It can be read from (and written to) 48 + Temp1-4 have 2 possible types. It can be read from (and written to) 49 49 temp[1-4]_type. 50 - - If the value of 0, the related temperature channel stops 51 - monitoring. 52 50 - If the value is 3, it starts monitoring using a remote termal diode 53 51 (default). 54 - - If the value is 5, it starts monitoring using the temperature sensor 55 - in AMD CPU and get result by AMDSI. 56 52 - If the value is 6, it starts monitoring using the temperature sensor 57 53 in Intel CPU and get result by PECI. 58 54 Temp5-6 can be connected to external thermistors (value of 59 - temp[5-6]_type is 4). They can also be disabled (value is 0). 55 + temp[5-6]_type is 4). 60 56 61 57 * Alarm mechanism 62 58 For voltage sensors, an alarm triggers if the measured value is below
+1 -1
drivers/hwmon/hwmon-vid.c
··· 93 93 case 110: /* Intel Conroe */ 94 94 /* compute in uV, round to mV */ 95 95 val &= 0xff; 96 - if(((val & 0x7e) == 0xfe) || (!(val & 0x7e))) 96 + if (val < 0x02 || val > 0xb2) 97 97 return 0; 98 98 return((1600000 - (val - 2) * 6250 + 500) / 1000); 99 99 case 24: /* Opteron processor */
+110 -17
drivers/hwmon/w83793.c
··· 117 117 /* Low Bits of Vcore A/B Vtt Read/High/Low */ 118 118 static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 }; 119 119 static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 }; 120 + static u8 scale_in_add[] = { 0, 0, 0, 0, 0, 0, 0, 150, 150, 0 }; 120 121 121 122 #define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */ 122 123 #define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */ ··· 204 203 u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ 205 204 206 205 u8 has_pwm; 206 + u8 has_temp; 207 + u8 has_vid; 207 208 u8 pwm_enable; /* Register value, each Temp has 1 bit */ 208 209 u8 pwm_uptime; /* Register value */ 209 210 u8 pwm_downtime; /* Register value */ ··· 503 500 each has 4 mode:(2 bits) 504 501 0: Stop monitor 505 502 1: Use internal temp sensor(default) 506 - 2: Use sensor in AMD CPU and get result by AMDSI 503 + 2: Reserved 507 504 3: Use sensor in Intel CPU and get result by PECI 508 505 509 506 TR1-TR2 ··· 512 509 1: To enable temp sensors monitor 513 510 */ 514 511 515 - /* 0 disable, 5 AMDSI, 6 PECI */ 516 - static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 }; 512 + /* 0 disable, 6 PECI */ 513 + static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; 517 514 518 515 static ssize_t 519 516 show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) ··· 553 550 u8 val = simple_strtoul(buf, NULL, 10); 554 551 555 552 /* transform the sysfs interface values into table above */ 556 - if ((val == 5 || val == 6) && (index < 4)) { 553 + if ((val == 6) && (index < 4)) { 557 554 val -= 3; 558 555 } else if ((val == 3 && index < 4) 559 - || (val == 4 && index >= 4) 560 - || val == 0) { 556 + || (val == 4 && index >= 4)) { 561 557 /* transform diode or thermistor into internal enable */ 562 558 val = !!val; 563 559 } else { ··· 841 839 val <<= 2; 842 840 val += (data->in_low_bits[nr] >> (index * 2)) & 0x3; 843 841 } 844 - return sprintf(buf, "%d\n", val * scale_in[index]); 842 + /* voltage inputs 5VDD and 5VSB needs 150mV offset */ 843 + val = val * scale_in[index] + scale_in_add[index]; 844 + return sprintf(buf, "%d\n", val); 845 845 } 846 846 847 847 static ssize_t ··· 863 859 scale_in[index] / 2) / scale_in[index]; 864 860 mutex_lock(&data->update_lock); 865 861 if (index > 2) { 862 + /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ 863 + if (1 == nr || 2 == nr) { 864 + val -= scale_in_add[index] / scale_in[index]; 865 + } 866 866 val = SENSORS_LIMIT(val, 0, 255); 867 867 } else { 868 868 val = SENSORS_LIMIT(val, 0, 0x3FF); ··· 987 979 SENSOR_ATTR_IN(7), 988 980 SENSOR_ATTR_IN(8), 989 981 SENSOR_ATTR_IN(9), 990 - SENSOR_ATTR_TEMP(1), 991 - SENSOR_ATTR_TEMP(2), 992 - SENSOR_ATTR_TEMP(3), 993 - SENSOR_ATTR_TEMP(4), 994 - SENSOR_ATTR_TEMP(5), 995 - SENSOR_ATTR_TEMP(6), 996 982 SENSOR_ATTR_FAN(1), 997 983 SENSOR_ATTR_FAN(2), 998 984 SENSOR_ATTR_FAN(3), ··· 995 993 SENSOR_ATTR_PWM(1), 996 994 SENSOR_ATTR_PWM(2), 997 995 SENSOR_ATTR_PWM(3), 996 + }; 997 + 998 + static struct sensor_device_attribute_2 w83793_temp[] = { 999 + SENSOR_ATTR_TEMP(1), 1000 + SENSOR_ATTR_TEMP(2), 1001 + SENSOR_ATTR_TEMP(3), 1002 + SENSOR_ATTR_TEMP(4), 1003 + SENSOR_ATTR_TEMP(5), 1004 + SENSOR_ATTR_TEMP(6), 998 1005 }; 999 1006 1000 1007 /* Fan6-Fan12 */ ··· 1026 1015 SENSOR_ATTR_PWM(8), 1027 1016 }; 1028 1017 1029 - static struct sensor_device_attribute_2 sda_single_files[] = { 1018 + static struct sensor_device_attribute_2 w83793_vid[] = { 1030 1019 SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0), 1031 1020 SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1), 1021 + }; 1022 + 1023 + static struct sensor_device_attribute_2 sda_single_files[] = { 1032 1024 SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm, 1033 1025 NOT_USED, NOT_USED), 1034 1026 SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, ··· 1084 1070 for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) 1085 1071 device_remove_file(dev, &sda_single_files[i].dev_attr); 1086 1072 1073 + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) 1074 + device_remove_file(dev, &w83793_vid[i].dev_attr); 1075 + 1087 1076 for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) 1088 1077 device_remove_file(dev, &w83793_left_fan[i].dev_attr); 1089 1078 1090 1079 for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) 1091 1080 device_remove_file(dev, &w83793_left_pwm[i].dev_attr); 1081 + 1082 + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) 1083 + device_remove_file(dev, &w83793_temp[i].dev_attr); 1092 1084 } 1093 1085 1094 1086 if ((err = i2c_detach_client(client))) ··· 1207 1187 struct w83793_data *data; 1208 1188 int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; 1209 1189 int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; 1190 + int files_temp = ARRAY_SIZE(w83793_temp) / 6; 1210 1191 int err = 0; 1211 1192 1212 1193 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { ··· 1334 1313 data->has_pwm |= 0x80; 1335 1314 } 1336 1315 1316 + tmp = w83793_read_value(client, W83793_REG_FANIN_SEL); 1317 + if ((tmp & 0x01) && (val & 0x08)) { /* fan 9, second location */ 1318 + data->has_fan |= 0x100; 1319 + } 1320 + if ((tmp & 0x02) && (val & 0x10)) { /* fan 10, second location */ 1321 + data->has_fan |= 0x200; 1322 + } 1323 + if ((tmp & 0x04) && (val & 0x20)) { /* fan 11, second location */ 1324 + data->has_fan |= 0x400; 1325 + } 1326 + if ((tmp & 0x08) && (val & 0x40)) { /* fan 12, second location */ 1327 + data->has_fan |= 0x800; 1328 + } 1329 + 1330 + /* check the temp1-6 mode, ignore former AMDSI selected inputs */ 1331 + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); 1332 + if (tmp & 0x01) 1333 + data->has_temp |= 0x01; 1334 + if (tmp & 0x04) 1335 + data->has_temp |= 0x02; 1336 + if (tmp & 0x10) 1337 + data->has_temp |= 0x04; 1338 + if (tmp & 0x40) 1339 + data->has_temp |= 0x08; 1340 + 1341 + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); 1342 + if (tmp & 0x01) 1343 + data->has_temp |= 0x10; 1344 + if (tmp & 0x02) 1345 + data->has_temp |= 0x20; 1346 + 1347 + /* Detect the VID usage and ignore unused input */ 1348 + tmp = w83793_read_value(client, W83793_REG_MFC); 1349 + if (!(tmp & 0x29)) 1350 + data->has_vid |= 0x1; /* has VIDA */ 1351 + if (tmp & 0x80) 1352 + data->has_vid |= 0x2; /* has VIDB */ 1353 + 1337 1354 /* Register sysfs hooks */ 1338 1355 for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { 1339 1356 err = device_create_file(dev, 1340 1357 &w83793_sensor_attr_2[i].dev_attr); 1358 + if (err) 1359 + goto exit_remove; 1360 + } 1361 + 1362 + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) { 1363 + if (!(data->has_vid & (1 << i))) 1364 + continue; 1365 + err = device_create_file(dev, &w83793_vid[i].dev_attr); 1341 1366 if (err) 1342 1367 goto exit_remove; 1343 1368 } ··· 1393 1326 if (err) 1394 1327 goto exit_remove; 1395 1328 1329 + } 1330 + 1331 + for (i = 0; i < 6; i++) { 1332 + int j; 1333 + if (!(data->has_temp & (1 << i))) 1334 + continue; 1335 + for (j = 0; j < files_temp; j++) { 1336 + err = device_create_file(dev, 1337 + &w83793_temp[(i) * files_temp 1338 + + j].dev_attr); 1339 + if (err) 1340 + goto exit_remove; 1341 + } 1396 1342 } 1397 1343 1398 1344 for (i = 5; i < 12; i++) { ··· 1451 1371 for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) 1452 1372 device_remove_file(dev, &sda_single_files[i].dev_attr); 1453 1373 1374 + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) 1375 + device_remove_file(dev, &w83793_vid[i].dev_attr); 1376 + 1454 1377 for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) 1455 1378 device_remove_file(dev, &w83793_left_fan[i].dev_attr); 1456 1379 1457 1380 for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) 1458 1381 device_remove_file(dev, &w83793_left_pwm[i].dev_attr); 1382 + 1383 + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) 1384 + device_remove_file(dev, &w83793_temp[i].dev_attr); 1459 1385 1460 1386 if (data->lm75[0] != NULL) { 1461 1387 i2c_detach_client(data->lm75[0]); ··· 1514 1428 } 1515 1429 1516 1430 for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { 1431 + if (!(data->has_temp & (1 << i))) 1432 + continue; 1517 1433 data->temp_fan_map[i] = 1518 1434 w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); 1519 1435 for (j = 1; j < 5; j++) { ··· 1598 1510 w83793_read_value(client, W83793_REG_FAN(i) + 1); 1599 1511 } 1600 1512 1601 - for (i = 0; i < ARRAY_SIZE(data->temp); i++) 1513 + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { 1514 + if (!(data->has_temp & (1 << i))) 1515 + continue; 1602 1516 data->temp[i][TEMP_READ] = 1603 1517 w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); 1518 + } 1604 1519 1605 1520 data->temp_low_bits = 1606 1521 w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); ··· 1618 1527 for (i = 0; i < ARRAY_SIZE(data->alarms); i++) 1619 1528 data->alarms[i] = 1620 1529 w83793_read_value(client, W83793_REG_ALARM(i)); 1621 - data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); 1622 - data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); 1530 + if (data->has_vid & 0x01) 1531 + data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); 1532 + if (data->has_vid & 0x02) 1533 + data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); 1623 1534 w83793_update_nonvolatile(dev); 1624 1535 data->last_updated = jiffies; 1625 1536 data->valid = 1;