diff options
-rw-r--r-- | Documentation/hwmon/it87 | 10 | ||||
-rw-r--r-- | Documentation/hwmon/sysfs-interface | 15 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 56 |
3 files changed, 74 insertions, 7 deletions
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 74a80992d237..c0528d6f9ace 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
@@ -135,6 +135,16 @@ Give 0 for unused sensor. Any other value is invalid. To configure this at | |||
135 | startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor; | 135 | startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor; |
136 | 3 = thermal diode) | 136 | 3 = thermal diode) |
137 | 137 | ||
138 | |||
139 | Fan speed control | ||
140 | ----------------- | ||
141 | |||
138 | The fan speed control features are limited to manual PWM mode. Automatic | 142 | The fan speed control features are limited to manual PWM mode. Automatic |
139 | "Smart Guardian" mode control handling is not implemented. However | 143 | "Smart Guardian" mode control handling is not implemented. However |
140 | if you want to go for "manual mode" just write 1 to pwmN_enable. | 144 | if you want to go for "manual mode" just write 1 to pwmN_enable. |
145 | |||
146 | If you are only able to control the fan speed with very small PWM values, | ||
147 | try lowering the PWM base frequency (pwm1_freq). Depending on the fan, | ||
148 | it may give you a somewhat greater control range. The same frequency is | ||
149 | used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are | ||
150 | read-only. | ||
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index efef3b962cd3..d73d2e8c7534 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
@@ -166,16 +166,21 @@ pwm[1-*] Pulse width modulation fan control. | |||
166 | 166 | ||
167 | pwm[1-*]_enable | 167 | pwm[1-*]_enable |
168 | Switch PWM on and off. | 168 | Switch PWM on and off. |
169 | Not always present even if fan*_pwm is. | 169 | Not always present even if pwmN is. |
170 | 0: turn off | 170 | 0: turn off |
171 | 1: turn on in manual mode | 171 | 1: turn on in manual mode |
172 | 2+: turn on in automatic mode | 172 | 2+: turn on in automatic mode |
173 | Check individual chip documentation files for automatic mode details. | 173 | Check individual chip documentation files for automatic mode |
174 | details. | ||
174 | RW | 175 | RW |
175 | 176 | ||
176 | pwm[1-*]_mode | 177 | pwm[1-*]_mode 0: DC mode (direct current) |
177 | 0: DC mode | 178 | 1: PWM mode (pulse-width modulation) |
178 | 1: PWM mode | 179 | RW |
180 | |||
181 | pwm[1-*]_freq Base PWM frequency in Hz. | ||
182 | Only possibly available when pwmN_mode is PWM, but not always | ||
183 | present even then. | ||
179 | RW | 184 | RW |
180 | 185 | ||
181 | pwm[1-*]_auto_channels_temp | 186 | pwm[1-*]_auto_channels_temp |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 1ed8b7e2c35d..bb16668ad2bd 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -202,6 +202,17 @@ static int DIV_TO_REG(int val) | |||
202 | } | 202 | } |
203 | #define DIV_FROM_REG(val) (1 << (val)) | 203 | #define DIV_FROM_REG(val) (1 << (val)) |
204 | 204 | ||
205 | static const unsigned int pwm_freq[8] = { | ||
206 | 48000000 / 128, | ||
207 | 24000000 / 128, | ||
208 | 12000000 / 128, | ||
209 | 8000000 / 128, | ||
210 | 6000000 / 128, | ||
211 | 3000000 / 128, | ||
212 | 1500000 / 128, | ||
213 | 750000 / 128, | ||
214 | }; | ||
215 | |||
205 | 216 | ||
206 | /* For each registered IT87, we need to keep some data in memory. That | 217 | /* For each registered IT87, we need to keep some data in memory. That |
207 | data is pointed to by it87_list[NR]->data. The structure itself is | 218 | data is pointed to by it87_list[NR]->data. The structure itself is |
@@ -232,6 +243,7 @@ struct it87_data { | |||
232 | u8 vrm; | 243 | u8 vrm; |
233 | u32 alarms; /* Register encoding, combined */ | 244 | u32 alarms; /* Register encoding, combined */ |
234 | u8 fan_main_ctrl; /* Register value */ | 245 | u8 fan_main_ctrl; /* Register value */ |
246 | u8 fan_ctl; /* Register value */ | ||
235 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ | 247 | u8 manual_pwm_ctl[3]; /* manual PWM value set by user */ |
236 | }; | 248 | }; |
237 | 249 | ||
@@ -519,6 +531,14 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, | |||
519 | struct it87_data *data = it87_update_device(dev); | 531 | struct it87_data *data = it87_update_device(dev); |
520 | return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]); | 532 | return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]); |
521 | } | 533 | } |
534 | static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, | ||
535 | char *buf) | ||
536 | { | ||
537 | struct it87_data *data = it87_update_device(dev); | ||
538 | int index = (data->fan_ctl >> 4) & 0x07; | ||
539 | |||
540 | return sprintf(buf, "%u\n", pwm_freq[index]); | ||
541 | } | ||
522 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | 542 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
523 | const char *buf, size_t count) | 543 | const char *buf, size_t count) |
524 | { | 544 | { |
@@ -639,6 +659,28 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
639 | mutex_unlock(&data->update_lock); | 659 | mutex_unlock(&data->update_lock); |
640 | return count; | 660 | return count; |
641 | } | 661 | } |
662 | static ssize_t set_pwm_freq(struct device *dev, | ||
663 | struct device_attribute *attr, const char *buf, size_t count) | ||
664 | { | ||
665 | struct i2c_client *client = to_i2c_client(dev); | ||
666 | struct it87_data *data = i2c_get_clientdata(client); | ||
667 | unsigned long val = simple_strtoul(buf, NULL, 10); | ||
668 | int i; | ||
669 | |||
670 | /* Search for the nearest available frequency */ | ||
671 | for (i = 0; i < 7; i++) { | ||
672 | if (val > (pwm_freq[i] + pwm_freq[i+1]) / 2) | ||
673 | break; | ||
674 | } | ||
675 | |||
676 | mutex_lock(&data->update_lock); | ||
677 | data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL) & 0x8f; | ||
678 | data->fan_ctl |= i << 4; | ||
679 | it87_write_value(client, IT87_REG_FAN_CTL, data->fan_ctl); | ||
680 | mutex_unlock(&data->update_lock); | ||
681 | |||
682 | return count; | ||
683 | } | ||
642 | 684 | ||
643 | #define show_fan_offset(offset) \ | 685 | #define show_fan_offset(offset) \ |
644 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | 686 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ |
@@ -656,7 +698,10 @@ show_fan_offset(3); | |||
656 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ | 698 | static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ |
657 | show_pwm_enable, set_pwm_enable, offset - 1); \ | 699 | show_pwm_enable, set_pwm_enable, offset - 1); \ |
658 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ | 700 | static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ |
659 | show_pwm, set_pwm, offset - 1); | 701 | show_pwm, set_pwm, offset - 1); \ |
702 | static DEVICE_ATTR(pwm##offset##_freq, \ | ||
703 | (offset == 1 ? S_IRUGO | S_IWUSR : S_IRUGO), \ | ||
704 | show_pwm_freq, (offset == 1 ? set_pwm_freq : NULL)); | ||
660 | 705 | ||
661 | show_pwm_offset(1); | 706 | show_pwm_offset(1); |
662 | show_pwm_offset(2); | 707 | show_pwm_offset(2); |
@@ -1021,7 +1066,13 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
1021 | || (err = device_create_file(&new_client->dev, | 1066 | || (err = device_create_file(&new_client->dev, |
1022 | &sensor_dev_attr_pwm2.dev_attr)) | 1067 | &sensor_dev_attr_pwm2.dev_attr)) |
1023 | || (err = device_create_file(&new_client->dev, | 1068 | || (err = device_create_file(&new_client->dev, |
1024 | &sensor_dev_attr_pwm3.dev_attr))) | 1069 | &sensor_dev_attr_pwm3.dev_attr)) |
1070 | || (err = device_create_file(&new_client->dev, | ||
1071 | &dev_attr_pwm1_freq)) | ||
1072 | || (err = device_create_file(&new_client->dev, | ||
1073 | &dev_attr_pwm2_freq)) | ||
1074 | || (err = device_create_file(&new_client->dev, | ||
1075 | &dev_attr_pwm3_freq))) | ||
1025 | goto ERROR4; | 1076 | goto ERROR4; |
1026 | } | 1077 | } |
1027 | 1078 | ||
@@ -1316,6 +1367,7 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1316 | (it87_read_value(client, IT87_REG_ALARM2) << 8) | | 1367 | (it87_read_value(client, IT87_REG_ALARM2) << 8) | |
1317 | (it87_read_value(client, IT87_REG_ALARM3) << 16); | 1368 | (it87_read_value(client, IT87_REG_ALARM3) << 16); |
1318 | data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); | 1369 | data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL); |
1370 | data->fan_ctl = it87_read_value(client, IT87_REG_FAN_CTL); | ||
1319 | 1371 | ||
1320 | data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); | 1372 | data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE); |
1321 | /* The 8705 does not have VID capability */ | 1373 | /* The 8705 does not have VID capability */ |