diff options
| -rw-r--r-- | drivers/hwmon/it87.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 49022bd2a0a5..41b55a74ce89 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -751,6 +751,59 @@ static ssize_t set_pwm_freq(struct device *dev, | |||
| 751 | 751 | ||
| 752 | return count; | 752 | return count; |
| 753 | } | 753 | } |
| 754 | static ssize_t show_pwm_temp_map(struct device *dev, | ||
| 755 | struct device_attribute *attr, char *buf) | ||
| 756 | { | ||
| 757 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
| 758 | int nr = sensor_attr->index; | ||
| 759 | |||
| 760 | struct it87_data *data = it87_update_device(dev); | ||
| 761 | int map; | ||
| 762 | |||
| 763 | if (data->pwm_temp_map[nr] < 3) | ||
| 764 | map = 1 << data->pwm_temp_map[nr]; | ||
| 765 | else | ||
| 766 | map = 0; /* Should never happen */ | ||
| 767 | return sprintf(buf, "%d\n", map); | ||
| 768 | } | ||
| 769 | static ssize_t set_pwm_temp_map(struct device *dev, | ||
| 770 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 771 | { | ||
| 772 | struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); | ||
| 773 | int nr = sensor_attr->index; | ||
| 774 | |||
| 775 | struct it87_data *data = dev_get_drvdata(dev); | ||
| 776 | long val; | ||
| 777 | u8 reg; | ||
| 778 | |||
| 779 | if (strict_strtol(buf, 10, &val) < 0) | ||
| 780 | return -EINVAL; | ||
| 781 | |||
| 782 | switch (val) { | ||
| 783 | case (1 << 0): | ||
| 784 | reg = 0x00; | ||
| 785 | break; | ||
| 786 | case (1 << 1): | ||
| 787 | reg = 0x01; | ||
| 788 | break; | ||
| 789 | case (1 << 2): | ||
| 790 | reg = 0x02; | ||
| 791 | break; | ||
| 792 | default: | ||
| 793 | return -EINVAL; | ||
| 794 | } | ||
| 795 | |||
| 796 | mutex_lock(&data->update_lock); | ||
| 797 | data->pwm_temp_map[nr] = reg; | ||
| 798 | /* If we are in automatic mode, write the temp mapping immediately; | ||
| 799 | * otherwise, just store it for later use. */ | ||
| 800 | if (data->pwm_ctrl[nr] & 0x80) { | ||
| 801 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; | ||
| 802 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | ||
| 803 | } | ||
| 804 | mutex_unlock(&data->update_lock); | ||
| 805 | return count; | ||
| 806 | } | ||
| 754 | 807 | ||
| 755 | #define show_fan_offset(offset) \ | 808 | #define show_fan_offset(offset) \ |
| 756 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | 809 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
| @@ -771,7 +824,10 @@ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | |||
| 771 | show_pwm, set_pwm, offset - 1); \ | 824 | show_pwm, set_pwm, offset - 1); \ |
| 772 | static DEVICE_ATTR(pwm##offset##_freq, \ | 825 | static DEVICE_ATTR(pwm##offset##_freq, \ |
| 773 | (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \ | 826 | (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \ |
| 774 | show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); | 827 | show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); \ |
| 828 | static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels_temp, \ | ||
| 829 | S_IRUGO, show_pwm_temp_map, set_pwm_temp_map, \ | ||
| 830 | offset - 1); | ||
| 775 | 831 | ||
| 776 | show_pwm_offset(1); | 832 | show_pwm_offset(1); |
| 777 | show_pwm_offset(2); | 833 | show_pwm_offset(2); |
| @@ -995,6 +1051,9 @@ static struct attribute *it87_attributes_opt[] = { | |||
| 995 | &dev_attr_pwm1_freq.attr, | 1051 | &dev_attr_pwm1_freq.attr, |
| 996 | &dev_attr_pwm2_freq.attr, | 1052 | &dev_attr_pwm2_freq.attr, |
| 997 | &dev_attr_pwm3_freq.attr, | 1053 | &dev_attr_pwm3_freq.attr, |
| 1054 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | ||
| 1055 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | ||
| 1056 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | ||
| 998 | 1057 | ||
| 999 | &dev_attr_vrm.attr, | 1058 | &dev_attr_vrm.attr, |
| 1000 | &dev_attr_cpu0_vid.attr, | 1059 | &dev_attr_cpu0_vid.attr, |
| @@ -1268,7 +1327,9 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1268 | || (err = device_create_file(dev, | 1327 | || (err = device_create_file(dev, |
| 1269 | &sensor_dev_attr_pwm1.dev_attr)) | 1328 | &sensor_dev_attr_pwm1.dev_attr)) |
| 1270 | || (err = device_create_file(dev, | 1329 | || (err = device_create_file(dev, |
| 1271 | &dev_attr_pwm1_freq))) | 1330 | &dev_attr_pwm1_freq)) |
| 1331 | || (err = device_create_file(dev, | ||
| 1332 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr))) | ||
| 1272 | goto ERROR4; | 1333 | goto ERROR4; |
| 1273 | } | 1334 | } |
| 1274 | if (!(sio_data->skip_pwm & (1 << 1))) { | 1335 | if (!(sio_data->skip_pwm & (1 << 1))) { |
| @@ -1277,7 +1338,9 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1277 | || (err = device_create_file(dev, | 1338 | || (err = device_create_file(dev, |
| 1278 | &sensor_dev_attr_pwm2.dev_attr)) | 1339 | &sensor_dev_attr_pwm2.dev_attr)) |
| 1279 | || (err = device_create_file(dev, | 1340 | || (err = device_create_file(dev, |
| 1280 | &dev_attr_pwm2_freq))) | 1341 | &dev_attr_pwm2_freq)) |
| 1342 | || (err = device_create_file(dev, | ||
| 1343 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr))) | ||
| 1281 | goto ERROR4; | 1344 | goto ERROR4; |
| 1282 | } | 1345 | } |
| 1283 | if (!(sio_data->skip_pwm & (1 << 2))) { | 1346 | if (!(sio_data->skip_pwm & (1 << 2))) { |
| @@ -1286,7 +1349,9 @@ static int __devinit it87_probe(struct platform_device *pdev) | |||
| 1286 | || (err = device_create_file(dev, | 1349 | || (err = device_create_file(dev, |
| 1287 | &sensor_dev_attr_pwm3.dev_attr)) | 1350 | &sensor_dev_attr_pwm3.dev_attr)) |
| 1288 | || (err = device_create_file(dev, | 1351 | || (err = device_create_file(dev, |
| 1289 | &dev_attr_pwm3_freq))) | 1352 | &dev_attr_pwm3_freq)) |
| 1353 | || (err = device_create_file(dev, | ||
| 1354 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr))) | ||
| 1290 | goto ERROR4; | 1355 | goto ERROR4; |
| 1291 | } | 1356 | } |
| 1292 | } | 1357 | } |
