diff options
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index ec595c606ed4..a25350cf9554 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -240,6 +240,8 @@ static const u16 W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B[] = { 0x67, 0x69, 0x6b }; | |||
240 | static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[] | 240 | static const u16 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[] |
241 | = { 0x68, 0x6a, 0x6c }; | 241 | = { 0x68, 0x6a, 0x6c }; |
242 | 242 | ||
243 | static const u16 W83627EHF_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 }; | ||
244 | |||
243 | static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301 }; | 245 | static const u16 NCT6775_REG_TARGET[] = { 0x101, 0x201, 0x301 }; |
244 | static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302 }; | 246 | static const u16 NCT6775_REG_FAN_MODE[] = { 0x102, 0x202, 0x302 }; |
245 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 0x105, 0x205, 0x305 }; | 247 | static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = { 0x105, 0x205, 0x305 }; |
@@ -465,6 +467,7 @@ struct w83627ehf_data { | |||
465 | u8 has_fan_min; /* some fans don't have min register */ | 467 | u8 has_fan_min; /* some fans don't have min register */ |
466 | bool has_fan_div; | 468 | bool has_fan_div; |
467 | u8 temp_type[3]; | 469 | u8 temp_type[3]; |
470 | s8 temp_offset[3]; | ||
468 | s16 temp[9]; | 471 | s16 temp[9]; |
469 | s16 temp_max[9]; | 472 | s16 temp_max[9]; |
470 | s16 temp_max_hyst[9]; | 473 | s16 temp_max_hyst[9]; |
@@ -496,6 +499,7 @@ struct w83627ehf_data { | |||
496 | u8 vrm; | 499 | u8 vrm; |
497 | 500 | ||
498 | u16 have_temp; | 501 | u16 have_temp; |
502 | u16 have_temp_offset; | ||
499 | u8 in6_skip:1; | 503 | u8 in6_skip:1; |
500 | u8 temp3_val_only:1; | 504 | u8 temp3_val_only:1; |
501 | }; | 505 | }; |
@@ -893,6 +897,10 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
893 | data->temp_max_hyst[i] | 897 | data->temp_max_hyst[i] |
894 | = w83627ehf_read_temp(data, | 898 | = w83627ehf_read_temp(data, |
895 | 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]); | ||
896 | } | 904 | } |
897 | 905 | ||
898 | data->alarms = w83627ehf_read_value(data, | 906 | data->alarms = w83627ehf_read_value(data, |
@@ -1226,6 +1234,39 @@ store_temp_reg(reg_temp_over, temp_max); | |||
1226 | store_temp_reg(reg_temp_hyst, temp_max_hyst); | 1234 | store_temp_reg(reg_temp_hyst, temp_max_hyst); |
1227 | 1235 | ||
1228 | 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 | ||
1229 | 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) |
1230 | { | 1271 | { |
1231 | struct w83627ehf_data *data = w83627ehf_update_device(dev); | 1272 | struct w83627ehf_data *data = w83627ehf_update_device(dev); |
@@ -1312,6 +1353,15 @@ static struct sensor_device_attribute sda_temp_type[] = { | |||
1312 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), | 1353 | SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), |
1313 | }; | 1354 | }; |
1314 | 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 | |||
1315 | #define show_pwm_reg(reg) \ | 1365 | #define show_pwm_reg(reg) \ |
1316 | 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, \ |
1317 | char *buf) \ | 1367 | char *buf) \ |
@@ -1804,6 +1854,7 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1804 | continue; | 1854 | continue; |
1805 | device_remove_file(dev, &sda_temp_alarm[i].dev_attr); | 1855 | device_remove_file(dev, &sda_temp_alarm[i].dev_attr); |
1806 | 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); | ||
1807 | } | 1858 | } |
1808 | 1859 | ||
1809 | device_remove_file(dev, &sda_caseopen[0].dev_attr); | 1860 | device_remove_file(dev, &sda_caseopen[0].dev_attr); |
@@ -2126,6 +2177,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2126 | } else { | 2177 | } else { |
2127 | data->temp_label = nct6775_temp_label; | 2178 | data->temp_label = nct6775_temp_label; |
2128 | } | 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 | } | ||
2129 | } else if (sio_data->kind == w83667hg_b) { | 2185 | } else if (sio_data->kind == w83667hg_b) { |
2130 | u8 reg; | 2186 | u8 reg; |
2131 | 2187 | ||
@@ -2168,6 +2224,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2168 | data->in6_skip = 1; | 2224 | data->in6_skip = 1; |
2169 | 2225 | ||
2170 | 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 | } | ||
2171 | } else if (sio_data->kind == w83627uhg) { | 2232 | } else if (sio_data->kind == w83627uhg) { |
2172 | u8 reg; | 2233 | u8 reg; |
2173 | 2234 | ||
@@ -2204,6 +2265,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2204 | data->in6_skip = 1; /* No VIN3 */ | 2265 | data->in6_skip = 1; /* No VIN3 */ |
2205 | 2266 | ||
2206 | 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 | } | ||
2207 | } else { | 2273 | } else { |
2208 | w83627ehf_set_temp_reg_ehf(data, 3); | 2274 | w83627ehf_set_temp_reg_ehf(data, 3); |
2209 | 2275 | ||
@@ -2223,6 +2289,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2223 | else | 2289 | else |
2224 | data->in6_skip = 1; | 2290 | data->in6_skip = 1; |
2225 | } | 2291 | } |
2292 | data->have_temp_offset = data->have_temp & 0x07; | ||
2226 | } | 2293 | } |
2227 | 2294 | ||
2228 | if (sio_data->kind == nct6775) { | 2295 | if (sio_data->kind == nct6775) { |
@@ -2488,6 +2555,12 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2488 | || (err = device_create_file(dev, | 2555 | || (err = device_create_file(dev, |
2489 | &sda_temp_type[i].dev_attr))) | 2556 | &sda_temp_type[i].dev_attr))) |
2490 | 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 | } | ||
2491 | } | 2564 | } |
2492 | 2565 | ||
2493 | err = device_create_file(dev, &sda_caseopen[0].dev_attr); | 2566 | err = device_create_file(dev, &sda_caseopen[0].dev_attr); |