diff options
-rw-r--r-- | Documentation/hwmon/w83793 | 8 | ||||
-rw-r--r-- | drivers/hwmon/w83793.c | 63 |
2 files changed, 56 insertions, 15 deletions
diff --git a/Documentation/hwmon/w83793 b/Documentation/hwmon/w83793 index 45e5408340e0..51171a83165b 100644 --- a/Documentation/hwmon/w83793 +++ b/Documentation/hwmon/w83793 | |||
@@ -45,18 +45,14 @@ This driver implements support for Winbond W83793G/W83793R chips. | |||
45 | temp5-6 have a 1 degree Celsiis resolution. | 45 | temp5-6 have a 1 degree Celsiis resolution. |
46 | 46 | ||
47 | * Temperature sensor types | 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 | temp[1-4]_type. | 49 | temp[1-4]_type. |
50 | - If the value of 0, the related temperature channel stops | ||
51 | monitoring. | ||
52 | - If the value is 3, it starts monitoring using a remote termal diode | 50 | - If the value is 3, it starts monitoring using a remote termal diode |
53 | (default). | 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 | - If the value is 6, it starts monitoring using the temperature sensor | 52 | - If the value is 6, it starts monitoring using the temperature sensor |
57 | in Intel CPU and get result by PECI. | 53 | in Intel CPU and get result by PECI. |
58 | Temp5-6 can be connected to external thermistors (value of | 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 | * Alarm mechanism | 57 | * Alarm mechanism |
62 | For voltage sensors, an alarm triggers if the measured value is below | 58 | For voltage sensors, an alarm triggers if the measured value is below |
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 99e603a6a667..c2b7834ecaa9 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c | |||
@@ -204,6 +204,7 @@ struct w83793_data { | |||
204 | u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ | 204 | u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ |
205 | 205 | ||
206 | u8 has_pwm; | 206 | u8 has_pwm; |
207 | u8 has_temp; | ||
207 | u8 pwm_enable; /* Register value, each Temp has 1 bit */ | 208 | u8 pwm_enable; /* Register value, each Temp has 1 bit */ |
208 | u8 pwm_uptime; /* Register value */ | 209 | u8 pwm_uptime; /* Register value */ |
209 | u8 pwm_downtime; /* Register value */ | 210 | u8 pwm_downtime; /* Register value */ |
@@ -554,8 +555,7 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, | |||
554 | if ((val == 6) && (index < 4)) { | 555 | if ((val == 6) && (index < 4)) { |
555 | val -= 3; | 556 | val -= 3; |
556 | } else if ((val == 3 && index < 4) | 557 | } else if ((val == 3 && index < 4) |
557 | || (val == 4 && index >= 4) | 558 | || (val == 4 && index >= 4)) { |
558 | || val == 0) { | ||
559 | /* transform diode or thermistor into internal enable */ | 559 | /* transform diode or thermistor into internal enable */ |
560 | val = !!val; | 560 | val = !!val; |
561 | } else { | 561 | } else { |
@@ -986,12 +986,6 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { | |||
986 | SENSOR_ATTR_IN(7), | 986 | SENSOR_ATTR_IN(7), |
987 | SENSOR_ATTR_IN(8), | 987 | SENSOR_ATTR_IN(8), |
988 | SENSOR_ATTR_IN(9), | 988 | SENSOR_ATTR_IN(9), |
989 | SENSOR_ATTR_TEMP(1), | ||
990 | SENSOR_ATTR_TEMP(2), | ||
991 | SENSOR_ATTR_TEMP(3), | ||
992 | SENSOR_ATTR_TEMP(4), | ||
993 | SENSOR_ATTR_TEMP(5), | ||
994 | SENSOR_ATTR_TEMP(6), | ||
995 | SENSOR_ATTR_FAN(1), | 989 | SENSOR_ATTR_FAN(1), |
996 | SENSOR_ATTR_FAN(2), | 990 | SENSOR_ATTR_FAN(2), |
997 | SENSOR_ATTR_FAN(3), | 991 | SENSOR_ATTR_FAN(3), |
@@ -1002,6 +996,15 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { | |||
1002 | SENSOR_ATTR_PWM(3), | 996 | SENSOR_ATTR_PWM(3), |
1003 | }; | 997 | }; |
1004 | 998 | ||
999 | static struct sensor_device_attribute_2 w83793_temp[] = { | ||
1000 | SENSOR_ATTR_TEMP(1), | ||
1001 | SENSOR_ATTR_TEMP(2), | ||
1002 | SENSOR_ATTR_TEMP(3), | ||
1003 | SENSOR_ATTR_TEMP(4), | ||
1004 | SENSOR_ATTR_TEMP(5), | ||
1005 | SENSOR_ATTR_TEMP(6), | ||
1006 | }; | ||
1007 | |||
1005 | /* Fan6-Fan12 */ | 1008 | /* Fan6-Fan12 */ |
1006 | static struct sensor_device_attribute_2 w83793_left_fan[] = { | 1009 | static struct sensor_device_attribute_2 w83793_left_fan[] = { |
1007 | SENSOR_ATTR_FAN(6), | 1010 | SENSOR_ATTR_FAN(6), |
@@ -1082,6 +1085,9 @@ static int w83793_detach_client(struct i2c_client *client) | |||
1082 | 1085 | ||
1083 | for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) | 1086 | for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) |
1084 | device_remove_file(dev, &w83793_left_pwm[i].dev_attr); | 1087 | device_remove_file(dev, &w83793_left_pwm[i].dev_attr); |
1088 | |||
1089 | for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) | ||
1090 | device_remove_file(dev, &w83793_temp[i].dev_attr); | ||
1085 | } | 1091 | } |
1086 | 1092 | ||
1087 | if ((err = i2c_detach_client(client))) | 1093 | if ((err = i2c_detach_client(client))) |
@@ -1194,6 +1200,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1194 | struct w83793_data *data; | 1200 | struct w83793_data *data; |
1195 | int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; | 1201 | int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; |
1196 | int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; | 1202 | int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; |
1203 | int files_temp = ARRAY_SIZE(w83793_temp) / 6; | ||
1197 | int err = 0; | 1204 | int err = 0; |
1198 | 1205 | ||
1199 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { | 1206 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { |
@@ -1320,6 +1327,23 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1320 | data->has_pwm |= 0x80; | 1327 | data->has_pwm |= 0x80; |
1321 | } | 1328 | } |
1322 | 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 | |||
1323 | /* Register sysfs hooks */ | 1347 | /* Register sysfs hooks */ |
1324 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { | 1348 | for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { |
1325 | err = device_create_file(dev, | 1349 | err = device_create_file(dev, |
@@ -1335,6 +1359,19 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1335 | 1359 | ||
1336 | } | 1360 | } |
1337 | 1361 | ||
1362 | for (i = 0; i < 6; i++) { | ||
1363 | int j; | ||
1364 | if (!(data->has_temp & (1 << i))) | ||
1365 | continue; | ||
1366 | for (j = 0; j < files_temp; j++) { | ||
1367 | err = device_create_file(dev, | ||
1368 | &w83793_temp[(i) * files_temp | ||
1369 | + j].dev_attr); | ||
1370 | if (err) | ||
1371 | goto exit_remove; | ||
1372 | } | ||
1373 | } | ||
1374 | |||
1338 | for (i = 5; i < 12; i++) { | 1375 | for (i = 5; i < 12; i++) { |
1339 | int j; | 1376 | int j; |
1340 | if (!(data->has_fan & (1 << i))) | 1377 | if (!(data->has_fan & (1 << i))) |
@@ -1384,6 +1421,9 @@ exit_remove: | |||
1384 | for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) | 1421 | for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) |
1385 | device_remove_file(dev, &w83793_left_pwm[i].dev_attr); | 1422 | device_remove_file(dev, &w83793_left_pwm[i].dev_attr); |
1386 | 1423 | ||
1424 | for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) | ||
1425 | device_remove_file(dev, &w83793_temp[i].dev_attr); | ||
1426 | |||
1387 | if (data->lm75[0] != NULL) { | 1427 | if (data->lm75[0] != NULL) { |
1388 | i2c_detach_client(data->lm75[0]); | 1428 | i2c_detach_client(data->lm75[0]); |
1389 | kfree(data->lm75[0]); | 1429 | kfree(data->lm75[0]); |
@@ -1435,6 +1475,8 @@ static void w83793_update_nonvolatile(struct device *dev) | |||
1435 | } | 1475 | } |
1436 | 1476 | ||
1437 | for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { | 1477 | for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { |
1478 | if (!(data->has_temp & (1 << i))) | ||
1479 | continue; | ||
1438 | data->temp_fan_map[i] = | 1480 | data->temp_fan_map[i] = |
1439 | w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); | 1481 | w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); |
1440 | for (j = 1; j < 5; j++) { | 1482 | for (j = 1; j < 5; j++) { |
@@ -1517,9 +1559,12 @@ static struct w83793_data *w83793_update_device(struct device *dev) | |||
1517 | w83793_read_value(client, W83793_REG_FAN(i) + 1); | 1559 | w83793_read_value(client, W83793_REG_FAN(i) + 1); |
1518 | } | 1560 | } |
1519 | 1561 | ||
1520 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) | 1562 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { |
1563 | if (!(data->has_temp & (1 << i))) | ||
1564 | continue; | ||
1521 | data->temp[i][TEMP_READ] = | 1565 | data->temp[i][TEMP_READ] = |
1522 | w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); | 1566 | w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); |
1567 | } | ||
1523 | 1568 | ||
1524 | data->temp_low_bits = | 1569 | data->temp_low_bits = |
1525 | w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); | 1570 | w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); |