diff options
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 0dcaba9b7189..e01a3e97aa17 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -277,6 +277,11 @@ struct w83627ehf_data { | |||
277 | struct device *hwmon_dev; | 277 | struct device *hwmon_dev; |
278 | struct mutex lock; | 278 | struct mutex lock; |
279 | 279 | ||
280 | const u8 *REG_FAN_START_OUTPUT; | ||
281 | const u8 *REG_FAN_STOP_OUTPUT; | ||
282 | const u8 *REG_FAN_MAX_OUTPUT; | ||
283 | const u8 *REG_FAN_STEP_OUTPUT; | ||
284 | |||
280 | struct mutex update_lock; | 285 | struct mutex update_lock; |
281 | char valid; /* !=0 if following fields are valid */ | 286 | char valid; /* !=0 if following fields are valid */ |
282 | unsigned long last_updated; /* In jiffies */ | 287 | unsigned long last_updated; /* In jiffies */ |
@@ -524,7 +529,10 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
524 | } | 529 | } |
525 | } | 530 | } |
526 | 531 | ||
527 | for (i = 0; i < 4; i++) { | 532 | for (i = 0; i < data->pwm_num; i++) { |
533 | if (!(data->has_fan & (1 << i))) | ||
534 | continue; | ||
535 | |||
528 | /* pwmcfg, tolerance mapped for i=0, i=1 to same reg */ | 536 | /* pwmcfg, tolerance mapped for i=0, i=1 to same reg */ |
529 | if (i != 1) { | 537 | if (i != 1) { |
530 | pwmcfg = w83627ehf_read_value(data, | 538 | pwmcfg = w83627ehf_read_value(data, |
@@ -546,6 +554,17 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) | |||
546 | W83627EHF_REG_FAN_STOP_OUTPUT[i]); | 554 | W83627EHF_REG_FAN_STOP_OUTPUT[i]); |
547 | data->fan_stop_time[i] = w83627ehf_read_value(data, | 555 | data->fan_stop_time[i] = w83627ehf_read_value(data, |
548 | W83627EHF_REG_FAN_STOP_TIME[i]); | 556 | W83627EHF_REG_FAN_STOP_TIME[i]); |
557 | |||
558 | if (data->REG_FAN_MAX_OUTPUT[i] != 0xff) | ||
559 | data->fan_max_output[i] = | ||
560 | w83627ehf_read_value(data, | ||
561 | data->REG_FAN_MAX_OUTPUT[i]); | ||
562 | |||
563 | if (data->REG_FAN_STEP_OUTPUT[i] != 0xff) | ||
564 | data->fan_step_output[i] = | ||
565 | w83627ehf_read_value(data, | ||
566 | data->REG_FAN_STEP_OUTPUT[i]); | ||
567 | |||
549 | data->target_temp[i] = | 568 | data->target_temp[i] = |
550 | w83627ehf_read_value(data, | 569 | w83627ehf_read_value(data, |
551 | W83627EHF_REG_TARGET[i]) & | 570 | W83627EHF_REG_TARGET[i]) & |
@@ -1126,7 +1145,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
1126 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ | 1145 | u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \ |
1127 | mutex_lock(&data->update_lock); \ | 1146 | mutex_lock(&data->update_lock); \ |
1128 | data->reg[nr] = val; \ | 1147 | data->reg[nr] = val; \ |
1129 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ | 1148 | w83627ehf_write_value(data, data->REG_##REG[nr], val); \ |
1130 | mutex_unlock(&data->update_lock); \ | 1149 | mutex_unlock(&data->update_lock); \ |
1131 | return count; \ | 1150 | return count; \ |
1132 | } | 1151 | } |
@@ -1206,12 +1225,26 @@ static struct sensor_device_attribute sda_sf3_arrays[] = { | |||
1206 | store_fan_stop_output, 1), | 1225 | store_fan_stop_output, 1), |
1207 | SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, | 1226 | SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output, |
1208 | store_fan_stop_output, 2), | 1227 | store_fan_stop_output, 2), |
1228 | }; | ||
1209 | 1229 | ||
1210 | /* pwm1 and pwm3 don't support max and step settings */ | 1230 | |
1231 | /* | ||
1232 | * pwm1 and pwm3 don't support max and step settings on all chips. | ||
1233 | * Need to check support while generating/removing attribute files. | ||
1234 | */ | ||
1235 | static struct sensor_device_attribute sda_sf3_max_step_arrays[] = { | ||
1236 | SENSOR_ATTR(pwm1_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, | ||
1237 | store_fan_max_output, 0), | ||
1238 | SENSOR_ATTR(pwm1_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, | ||
1239 | store_fan_step_output, 0), | ||
1211 | SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, | 1240 | SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, |
1212 | store_fan_max_output, 1), | 1241 | store_fan_max_output, 1), |
1213 | SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, | 1242 | SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, |
1214 | store_fan_step_output, 1), | 1243 | store_fan_step_output, 1), |
1244 | SENSOR_ATTR(pwm3_max_output, S_IWUSR | S_IRUGO, show_fan_max_output, | ||
1245 | store_fan_max_output, 2), | ||
1246 | SENSOR_ATTR(pwm3_step_output, S_IWUSR | S_IRUGO, show_fan_step_output, | ||
1247 | store_fan_step_output, 2), | ||
1215 | }; | 1248 | }; |
1216 | 1249 | ||
1217 | static ssize_t | 1250 | static ssize_t |
@@ -1235,6 +1268,12 @@ static void w83627ehf_device_remove_files(struct device *dev) | |||
1235 | 1268 | ||
1236 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) | 1269 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) |
1237 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); | 1270 | device_remove_file(dev, &sda_sf3_arrays[i].dev_attr); |
1271 | for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) { | ||
1272 | struct sensor_device_attribute *attr = | ||
1273 | &sda_sf3_max_step_arrays[i]; | ||
1274 | if (data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) | ||
1275 | device_remove_file(dev, &attr->dev_attr); | ||
1276 | } | ||
1238 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) | 1277 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) |
1239 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); | 1278 | device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); |
1240 | for (i = 0; i < data->in_num; i++) { | 1279 | for (i = 0; i < data->in_num; i++) { |
@@ -1352,6 +1391,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1352 | data->in6_skip = !data->temp3_disable; | 1391 | data->in6_skip = !data->temp3_disable; |
1353 | } | 1392 | } |
1354 | 1393 | ||
1394 | data->REG_FAN_START_OUTPUT = W83627EHF_REG_FAN_START_OUTPUT; | ||
1395 | data->REG_FAN_STOP_OUTPUT = W83627EHF_REG_FAN_STOP_OUTPUT; | ||
1396 | data->REG_FAN_MAX_OUTPUT = W83627EHF_REG_FAN_MAX_OUTPUT; | ||
1397 | data->REG_FAN_STEP_OUTPUT = W83627EHF_REG_FAN_STEP_OUTPUT; | ||
1398 | |||
1355 | /* Initialize the chip */ | 1399 | /* Initialize the chip */ |
1356 | w83627ehf_init_device(data); | 1400 | w83627ehf_init_device(data); |
1357 | 1401 | ||
@@ -1440,6 +1484,15 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
1440 | &sda_sf3_arrays[i].dev_attr))) | 1484 | &sda_sf3_arrays[i].dev_attr))) |
1441 | goto exit_remove; | 1485 | goto exit_remove; |
1442 | 1486 | ||
1487 | for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) { | ||
1488 | struct sensor_device_attribute *attr = | ||
1489 | &sda_sf3_max_step_arrays[i]; | ||
1490 | if (data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) { | ||
1491 | err = device_create_file(dev, &attr->dev_attr); | ||
1492 | if (err) | ||
1493 | goto exit_remove; | ||
1494 | } | ||
1495 | } | ||
1443 | /* if fan4 is enabled create the sf3 files for it */ | 1496 | /* if fan4 is enabled create the sf3 files for it */ |
1444 | if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) | 1497 | if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4) |
1445 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { | 1498 | for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { |