aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/f71805f.c
diff options
context:
space:
mode:
authorPhil Endecott <kernel@chezphil.org>2007-06-29 03:19:14 -0400
committerMark M. Hoffman <mhoffman@lightlink.com>2007-07-19 14:22:15 -0400
commitaba5073d3f4c928c89c483d85f8cff7cc9aa3312 (patch)
treec966ca4de6e14d4edbb7232b3dcef3fb7e114b7f /drivers/hwmon/f71805f.c
parent158ce07564b68d4215b9560213a089d6f7c5a4ea (diff)
hwmon/f71805f: Add temperature-tracking fan control mode
Add support for the "temperature mode" fan speed control. In this mode, the user can define 3 temperature/speed trip points, and the chip will set the speed automatically according to the temperature changes. Signed-off-by: Phil Endecott <kernel@chezphil.org> Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
Diffstat (limited to 'drivers/hwmon/f71805f.c')
-rw-r--r--drivers/hwmon/f71805f.c167
1 files changed, 166 insertions, 1 deletions
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 8fe4d70d8f51..6f60715f34f8 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -127,6 +127,13 @@ superio_exit(int base)
127#define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) 127#define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr))
128#define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) 128#define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr))
129#define F71805F_REG_TEMP_MODE 0x01 129#define F71805F_REG_TEMP_MODE 0x01
130/* pwm/fan pwmnr from 0 to 2, auto point apnr from 0 to 2 */
131/* map Fintek numbers to our numbers as follows: 9->0, 5->1, 1->2 */
132#define F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr) \
133 (0xA0 + 0x10 * (pwmnr) + (2 - (apnr)))
134#define F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr) \
135 (0xA4 + 0x10 * (pwmnr) + \
136 2 * (2 - (apnr)))
130 137
131#define F71805F_REG_START 0x00 138#define F71805F_REG_START 0x00
132/* status nr from 0 to 2 */ 139/* status nr from 0 to 2 */
@@ -144,6 +151,11 @@ superio_exit(int base)
144 * Data structures and manipulation thereof 151 * Data structures and manipulation thereof
145 */ 152 */
146 153
154struct f71805f_auto_point {
155 u8 temp[3];
156 u16 fan[3];
157};
158
147struct f71805f_data { 159struct f71805f_data {
148 unsigned short addr; 160 unsigned short addr;
149 const char *name; 161 const char *name;
@@ -170,6 +182,7 @@ struct f71805f_data {
170 u8 temp_hyst[3]; 182 u8 temp_hyst[3];
171 u8 temp_mode; 183 u8 temp_mode;
172 unsigned long alarms; 184 unsigned long alarms;
185 struct f71805f_auto_point auto_points[3];
173}; 186};
174 187
175struct f71805f_sio_data { 188struct f71805f_sio_data {
@@ -312,7 +325,7 @@ static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
312static struct f71805f_data *f71805f_update_device(struct device *dev) 325static struct f71805f_data *f71805f_update_device(struct device *dev)
313{ 326{
314 struct f71805f_data *data = dev_get_drvdata(dev); 327 struct f71805f_data *data = dev_get_drvdata(dev);
315 int nr; 328 int nr, apnr;
316 329
317 mutex_lock(&data->update_lock); 330 mutex_lock(&data->update_lock);
318 331
@@ -342,6 +355,18 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
342 F71805F_REG_TEMP_HYST(nr)); 355 F71805F_REG_TEMP_HYST(nr));
343 } 356 }
344 data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); 357 data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE);
358 for (nr = 0; nr < 3; nr++) {
359 for (apnr = 0; apnr < 3; apnr++) {
360 data->auto_points[nr].temp[apnr] =
361 f71805f_read8(data,
362 F71805F_REG_PWM_AUTO_POINT_TEMP(nr,
363 apnr));
364 data->auto_points[nr].fan[apnr] =
365 f71805f_read16(data,
366 F71805F_REG_PWM_AUTO_POINT_FAN(nr,
367 apnr));
368 }
369 }
345 370
346 data->last_limits = jiffies; 371 data->last_limits = jiffies;
347 } 372 }
@@ -705,6 +730,70 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
705 return count; 730 return count;
706} 731}
707 732
733static ssize_t show_pwm_auto_point_temp(struct device *dev,
734 struct device_attribute *devattr,
735 char* buf)
736{
737 struct f71805f_data *data = dev_get_drvdata(dev);
738 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
739 int pwmnr = attr->nr;
740 int apnr = attr->index;
741
742 return sprintf(buf, "%ld\n",
743 temp_from_reg(data->auto_points[pwmnr].temp[apnr]));
744}
745
746static ssize_t set_pwm_auto_point_temp(struct device *dev,
747 struct device_attribute *devattr,
748 const char* buf, size_t count)
749{
750 struct f71805f_data *data = dev_get_drvdata(dev);
751 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
752 int pwmnr = attr->nr;
753 int apnr = attr->index;
754 unsigned long val = simple_strtol(buf, NULL, 10);
755
756 mutex_lock(&data->update_lock);
757 data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val);
758 f71805f_write8(data, F71805F_REG_PWM_AUTO_POINT_TEMP(pwmnr, apnr),
759 data->auto_points[pwmnr].temp[apnr]);
760 mutex_unlock(&data->update_lock);
761
762 return count;
763}
764
765static ssize_t show_pwm_auto_point_fan(struct device *dev,
766 struct device_attribute *devattr,
767 char* buf)
768{
769 struct f71805f_data *data = dev_get_drvdata(dev);
770 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
771 int pwmnr = attr->nr;
772 int apnr = attr->index;
773
774 return sprintf(buf, "%ld\n",
775 fan_from_reg(data->auto_points[pwmnr].fan[apnr]));
776}
777
778static ssize_t set_pwm_auto_point_fan(struct device *dev,
779 struct device_attribute *devattr,
780 const char* buf, size_t count)
781{
782 struct f71805f_data *data = dev_get_drvdata(dev);
783 struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
784 int pwmnr = attr->nr;
785 int apnr = attr->index;
786 unsigned long val = simple_strtoul(buf, NULL, 10);
787
788 mutex_lock(&data->update_lock);
789 data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val);
790 f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr),
791 data->auto_points[pwmnr].fan[apnr]);
792 mutex_unlock(&data->update_lock);
793
794 return count;
795}
796
708static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, 797static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
709 char *buf) 798 char *buf)
710{ 799{
@@ -932,6 +1021,63 @@ static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO | S_IWUSR,
932 show_pwm_freq, set_pwm_freq, 2); 1021 show_pwm_freq, set_pwm_freq, 2);
933static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2); 1022static SENSOR_DEVICE_ATTR(pwm3_mode, S_IRUGO, show_pwm_mode, NULL, 2);
934 1023
1024static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
1025 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1026 0, 0);
1027static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_fan, S_IRUGO | S_IWUSR,
1028 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1029 0, 0);
1030static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
1031 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1032 0, 1);
1033static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_fan, S_IRUGO | S_IWUSR,
1034 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1035 0, 1);
1036static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
1037 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1038 0, 2);
1039static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_fan, S_IRUGO | S_IWUSR,
1040 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1041 0, 2);
1042
1043static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
1044 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1045 1, 0);
1046static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_fan, S_IRUGO | S_IWUSR,
1047 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1048 1, 0);
1049static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
1050 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1051 1, 1);
1052static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_fan, S_IRUGO | S_IWUSR,
1053 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1054 1, 1);
1055static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
1056 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1057 1, 2);
1058static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_fan, S_IRUGO | S_IWUSR,
1059 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1060 1, 2);
1061
1062static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
1063 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1064 2, 0);
1065static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_fan, S_IRUGO | S_IWUSR,
1066 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1067 2, 0);
1068static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
1069 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1070 2, 1);
1071static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_fan, S_IRUGO | S_IWUSR,
1072 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1073 2, 1);
1074static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
1075 show_pwm_auto_point_temp, set_pwm_auto_point_temp,
1076 2, 2);
1077static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_fan, S_IRUGO | S_IWUSR,
1078 show_pwm_auto_point_fan, set_pwm_auto_point_fan,
1079 2, 2);
1080
935static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 1081static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
936static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 1082static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
937static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); 1083static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
@@ -1014,6 +1160,25 @@ static struct attribute *f71805f_attributes[] = {
1014 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, 1160 &sensor_dev_attr_temp3_max_hyst.dev_attr.attr,
1015 &sensor_dev_attr_temp3_type.dev_attr.attr, 1161 &sensor_dev_attr_temp3_type.dev_attr.attr,
1016 1162
1163 &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
1164 &sensor_dev_attr_pwm1_auto_point1_fan.dev_attr.attr,
1165 &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
1166 &sensor_dev_attr_pwm1_auto_point2_fan.dev_attr.attr,
1167 &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
1168 &sensor_dev_attr_pwm1_auto_point3_fan.dev_attr.attr,
1169 &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
1170 &sensor_dev_attr_pwm2_auto_point1_fan.dev_attr.attr,
1171 &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
1172 &sensor_dev_attr_pwm2_auto_point2_fan.dev_attr.attr,
1173 &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
1174 &sensor_dev_attr_pwm2_auto_point3_fan.dev_attr.attr,
1175 &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
1176 &sensor_dev_attr_pwm3_auto_point1_fan.dev_attr.attr,
1177 &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
1178 &sensor_dev_attr_pwm3_auto_point2_fan.dev_attr.attr,
1179 &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
1180 &sensor_dev_attr_pwm3_auto_point3_fan.dev_attr.attr,
1181
1017 &sensor_dev_attr_in0_alarm.dev_attr.attr, 1182 &sensor_dev_attr_in0_alarm.dev_attr.attr,
1018 &sensor_dev_attr_in1_alarm.dev_attr.attr, 1183 &sensor_dev_attr_in1_alarm.dev_attr.attr,
1019 &sensor_dev_attr_in2_alarm.dev_attr.attr, 1184 &sensor_dev_attr_in2_alarm.dev_attr.attr,