aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/it87.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r--drivers/hwmon/it87.c56
1 files changed, 54 insertions, 2 deletions
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 */