aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-02-14 15:15:02 -0500
committerJean Delvare <khali@arrakis.delvare>2007-02-14 15:15:02 -0500
commitf8d0c19a93cea3a26a90f2462295e1e01a4cd250 (patch)
tree6d874a35f611a1c344896ef13a911a80a3d10017
parentac98695d6c1508b724f246f38ce57fb4e3cec356 (diff)
hwmon/it87: Add PWM base frequency control
Let the user select the base PWM frequency when using the it87 hardware monitoring driver. Different frequencies can give better control on some fans. Also update the documentation to mention the PWM frequency control files, with misc cleanups to the PWM section. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--Documentation/hwmon/it8710
-rw-r--r--Documentation/hwmon/sysfs-interface15
-rw-r--r--drivers/hwmon/it87.c56
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
135startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor; 135startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor;
1363 = thermal diode) 1363 = thermal diode)
137 137
138
139Fan speed control
140-----------------
141
138The fan speed control features are limited to manual PWM mode. Automatic 142The 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
140if you want to go for "manual mode" just write 1 to pwmN_enable. 144if you want to go for "manual mode" just write 1 to pwmN_enable.
145
146If you are only able to control the fan speed with very small PWM values,
147try lowering the PWM base frequency (pwm1_freq). Depending on the fan,
148it may give you a somewhat greater control range. The same frequency is
149used to drive all fan outputs, which is why pwm2_freq and pwm3_freq are
150read-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
167pwm[1-*]_enable 167pwm[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
176pwm[1-*]_mode 177pwm[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
181pwm[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
181pwm[1-*]_auto_channels_temp 186pwm[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
205static 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}
534static 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}
522static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 542static 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}
662static 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) \
644static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 686static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
@@ -656,7 +698,10 @@ show_fan_offset(3);
656static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ 698static 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); \
658static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ 700static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
659 show_pwm, set_pwm, offset - 1); 701 show_pwm, set_pwm, offset - 1); \
702static 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
661show_pwm_offset(1); 706show_pwm_offset(1);
662show_pwm_offset(2); 707show_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 */