All of lore.kernel.org
 help / color / mirror / Atom feed
* [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2]
@ 2008-10-20  9:28 Hans de Goede
  0 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2008-10-20  9:28 UTC (permalink / raw)
  To: lm-sensors

[-- Attachment #1: Type: text/plain, Size: 437 bytes --]

From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Hi Jean (and all),

Convert f71882fg driver from SENSOR_ATTR to SENSOR_ATTR2 use, this is a
preparation patch for adding pwm support, which is broken out to make what
changes really in the pwm support patch clear.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Regards,

Hans


[-- Attachment #2: f71882fg-sensor_attr2.patch --]
[-- Type: text/plain, Size: 13775 bytes --]

From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Convert f71882fg driver from SENSOR_ATTR to SENSOR_ATTR2 use, this is a
preparation patch for adding pwm support, which is broken out to make what
changes really in the pwm support patch clear.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
--- f71882fg.c.orig	2008-10-19 13:10:10.000000000 +0200
+++ f71882fg.c	2008-10-19 15:26:32.000000000 +0200
@@ -188,79 +188,84 @@
 	__ATTR( name, S_IRUGO, show_name, NULL ),
 };
 
-static struct sensor_device_attribute f71882fg_in_temp_attr[] =
+static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] =
 {
-	SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
-	SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
-	SENSOR_ATTR(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 1),
-	SENSOR_ATTR(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 1),
-	SENSOR_ATTR(in1_alarm, S_IRUGO, show_in_alarm, NULL, 1),
-	SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
-	SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
-	SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
-	SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
-	SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
-	SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
-	SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
-	SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0),
-	SENSOR_ATTR(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
-		store_temp_max, 0),
-	SENSOR_ATTR(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
-		store_temp_max_hyst, 0),
-	SENSOR_ATTR(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
-		store_temp_crit, 0),
-	SENSOR_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 0),
-	SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
-	SENSOR_ATTR(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep,
-		store_temp_beep, 0),
-	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0),
-	SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0),
-	SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1),
-	SENSOR_ATTR(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
-		store_temp_max, 1),
-	SENSOR_ATTR(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
-		store_temp_max_hyst, 1),
-	SENSOR_ATTR(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
-		store_temp_crit, 1),
-	SENSOR_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 1),
-	SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
-	SENSOR_ATTR(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep,
-		store_temp_beep, 1),
-	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 1),
-	SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1),
-	SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2),
-	SENSOR_ATTR(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
-		store_temp_max, 2),
-	SENSOR_ATTR(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
-		store_temp_max_hyst, 2),
-	SENSOR_ATTR(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
-		store_temp_crit, 2),
-	SENSOR_ATTR(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 2),
-	SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
-	SENSOR_ATTR(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep,
-		store_temp_beep, 2),
-	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 2),
-	SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2)
+	SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
+	SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
+	SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
+		0, 1),
+	SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
+		0, 1),
+	SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
+	SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
+	SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
+	SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
+	SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
+	SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
+	SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
+	SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
+	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
+	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
+		store_temp_max, 0, 0),
+	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
+		store_temp_max_hyst, 0, 0),
+	SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
+		store_temp_crit, 0, 0),
+	SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
+		0, 0),
+	SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 0),
+	SENSOR_ATTR_2(temp1_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+		store_temp_beep, 0, 0),
+	SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
+	SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
+	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
+	SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
+		store_temp_max, 0, 1),
+	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
+		store_temp_max_hyst, 0, 1),
+	SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
+		store_temp_crit, 0, 1),
+	SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
+		0, 1),
+	SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
+	SENSOR_ATTR_2(temp2_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+		store_temp_beep, 0, 1),
+	SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
+	SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
+	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
+	SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
+		store_temp_max, 0, 2),
+	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
+		store_temp_max_hyst, 0, 2),
+	SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
+		store_temp_crit, 0, 2),
+	SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
+		0, 2),
+	SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 2),
+	SENSOR_ATTR_2(temp3_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+		store_temp_beep, 0, 2),
+	SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
+	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2)
 };
 
-static struct sensor_device_attribute f71882fg_fan_attr[] =
+static struct sensor_device_attribute_2 f71882fg_fan_attr[] =
 {
-	SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
-	SENSOR_ATTR(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 0),
-	SENSOR_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0),
-	SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
-	SENSOR_ATTR(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 1),
-	SENSOR_ATTR(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 1),
-	SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
-	SENSOR_ATTR(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 2),
-	SENSOR_ATTR(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 2),
-	SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
-	SENSOR_ATTR(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
-		store_fan_beep, 3),
-	SENSOR_ATTR(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 3)
+	SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
+	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
+		store_fan_beep, 0, 0),
+	SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
+	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
+	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
+		store_fan_beep, 0, 1),
+	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
+	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
+	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
+		store_fan_beep, 0, 2),
+	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
+	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
+	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
+		store_fan_beep, 0, 3),
+	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3)
 };
 
 
@@ -417,7 +422,7 @@
 	char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int speed = fan_from_reg(data->fan[nr]);
 
 	if (speed == FAN_MIN_DETECT)
@@ -430,7 +435,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->fan_beep & (1 << nr))
 		return sprintf(buf, "1\n");
@@ -442,7 +447,7 @@
 	*devattr, const char *buf, size_t count)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int val = simple_strtoul(buf, NULL, 10);
 
 	mutex_lock(&data->update_lock);
@@ -461,7 +466,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->fan_status & (1 << nr))
 		return sprintf(buf, "1\n");
@@ -473,7 +478,7 @@
 	char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n", data->in[nr] * 8);
 }
@@ -507,7 +512,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->in_beep & (1 << nr))
 		return sprintf(buf, "1\n");
@@ -519,7 +524,7 @@
 	*devattr, const char *buf, size_t count)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int val = simple_strtoul(buf, NULL, 10);
 
 	mutex_lock(&data->update_lock);
@@ -538,7 +543,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->in_status & (1 << nr))
 		return sprintf(buf, "1\n");
@@ -550,7 +555,7 @@
 	char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n", data->temp[nr] * 1000);
 }
@@ -559,7 +564,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
 }
@@ -568,7 +573,7 @@
 	*devattr, const char *buf, size_t count)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int val = simple_strtoul(buf, NULL, 10) / 1000;
 
 	if (val > 255)
@@ -586,7 +591,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n",
 		(data->temp_high[nr] - data->temp_hyst[nr]) * 1000);
@@ -596,7 +601,7 @@
 	*devattr, const char *buf, size_t count)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int val = simple_strtoul(buf, NULL, 10) / 1000;
 	ssize_t ret = count;
 
@@ -636,7 +641,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
 }
@@ -645,7 +650,7 @@
 	*devattr, const char *buf, size_t count)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int val = simple_strtoul(buf, NULL, 10) / 1000;
 
 	if (val > 255)
@@ -663,7 +668,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n",
 		(data->temp_ovt[nr] - data->temp_hyst[nr]) * 1000);
@@ -673,7 +678,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	return sprintf(buf, "%d\n", data->temp_type[nr]);
 }
@@ -682,7 +687,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->temp_beep & (1 << (nr + 1)))
 		return sprintf(buf, "1\n");
@@ -694,7 +699,7 @@
 	*devattr, const char *buf, size_t count)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 	int val = simple_strtoul(buf, NULL, 10);
 
 	mutex_lock(&data->update_lock);
@@ -713,7 +718,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->temp_status & (1 << (nr + 1)))
 		return sprintf(buf, "1\n");
@@ -725,7 +730,7 @@
 	*devattr, char *buf)
 {
 	struct f71882fg_data *data = f71882fg_update_device(dev);
-	int nr = to_sensor_dev_attr(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->index;
 
 	if (data->temp_diode_open & (1 << (nr + 1)))
 		return sprintf(buf, "1\n");

[-- Attachment #3: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2]
@ 2008-10-20  9:29 Hans de Goede
  2008-10-20 13:43 ` Jean Delvare
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Hans de Goede @ 2008-10-20  9:29 UTC (permalink / raw)
  To: lm-sensors

[-- Attachment #1: Type: text/plain, Size: 761 bytes --]

From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Hi Jean (and all),

Add pwm support to the f71882fg driver. Changes made by me to the latest
revision submitted by Mark van Doesburg:
-Remove whitespace only changes from the patch (undo Lindent damage)
-Change pwm#_auto_point#_temp unit from degrees to milli degrees celcius
-Remove incomplete ability to turn of pwm (pwm#_enable = 0), as the hardware
  does not support this
-Made handling of out of range input to sysfs files more robust
-When we write a new setting to IC update our local cached copy of the register
  being written

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Regards,

Hans



[-- Attachment #2: f71882fg-pwm-support.patch --]
[-- Type: text/plain, Size: 28617 bytes --]

From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Add pwm support to the f71882fg driver. Changes made by me to the latest
revision submitted by Mark van Doesburg:
-Remove whitespace only changes from the patch (undo Lindent damage)
-Change pwm#_auto_point#_temp unit from degrees to milli degrees celcius
-Remove incomplete ability to turn of pwm (pwm#_enable = 0), as the hardware
 does not support this
-Made handling of out of range input to sysfs files more robust
-When we write a new setting to IC update our local cached copy of the register
 being written

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
--- f71882fg.c.orig	2008-10-20 09:53:36.000000000 +0200
+++ f71882fg.c	2008-10-20 10:44:11.000000000 +0200
@@ -27,11 +27,11 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define DRVNAME "f71882fg"
 
-#define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device*/
+#define SIO_F71882FG_LD_HWM	0x04	/* Hardware monitor logical device */
 #define SIO_UNLOCK_KEY		0x87	/* Key to enable Super-I/O */
 #define SIO_LOCK_KEY		0xAA	/* Key to diasble Super-I/O */
 
@@ -57,6 +57,8 @@
 #define F71882FG_REG_IN1_HIGH		0x32
 
 #define F71882FG_REG_FAN(nr)		(0xA0 + (16 * (nr)))
+#define F71882FG_REG_FAN_TARGET(nr)	(0xA2 + (16 * (nr)))
+#define F71882FG_REG_FAN_FULL_SPEED(nr)	(0xA4 + (16 * (nr)))
 #define F71882FG_REG_FAN_STATUS		0x92
 #define F71882FG_REG_FAN_BEEP		0x93
 
@@ -70,6 +72,17 @@
 #define F71882FG_REG_TEMP_TYPE		0x6B
 #define F71882FG_REG_TEMP_DIODE_OPEN	0x6F
 
+#define F71882FG_REG_PWM(nr)            (0xA3 + (16 * (nr)))
+#define F71882FG_REG_PWM_TYPE		0x94
+#define F71882FG_REG_PWM_ENABLE         0x96
+
+#define F71882FG_REG_FAN_HYST0		0x98
+#define F71882FG_REG_FAN_HYST1		0x99
+
+#define F71882FG_REG_POINT_PWM(pwm, point)	(0xAA + point + (16 * (pwm)))
+#define F71882FG_REG_POINT_TEMP(pwm, point)	(0xA6 + point + (16 * (pwm)))
+#define F71882FG_REG_POINT_MAPPING(nr)		(0xAF + 16*(nr))
+
 #define	F71882FG_REG_START		0x01
 
 #define FAN_MIN_DETECT			366 /* Lowest detectable fanspeed */
@@ -78,7 +91,13 @@
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-static struct platform_device *f71882fg_pdev = NULL;
+static int fan_mode[4] = { 0, 0, 0, 0 };
+module_param_array(fan_mode, int, NULL, 0644);
+MODULE_PARM_DESC(fan_mode, "List of fan control modes (f71882fg only)"
+		 "(0=don't change, 1=pwm, 2=rpm)\n"
+		 "Note: this needs a write to pwm#_enable to take effect");
+
+static struct platform_device *f71882fg_pdev;
 
 /* Super-I/O Function prototypes */
 static inline int superio_inb(int base, int reg);
@@ -102,6 +121,8 @@
 	u8	in_status;
 	u8	in_beep;
 	u16	fan[4];
+	u16	fan_target[4];
+	u16	fan_full_speed[4];
 	u8	fan_status;
 	u8	fan_beep;
 	u8	temp[3];
@@ -112,9 +133,15 @@
 	u8	temp_status;
 	u8	temp_beep;
 	u8	temp_diode_open;
+	u8	pwm[4];
+	u8	pwm_enable;
+	u8	pwm_auto_point_hyst[2];
+	u8	pwm_auto_point_mapping[4];
+	u8	pwm_auto_point_pwm[4][5];
+	u8	pwm_auto_point_temp[4][4];
 };
 
-/* Sysfs in*/
+/* Sysfs in */
 static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
 	char *buf);
 static ssize_t show_in_max(struct device *dev, struct device_attribute
@@ -130,6 +157,10 @@
 /* Sysfs Fan */
 static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
 	char *buf);
+static ssize_t show_fan_full_speed(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_fan_full_speed(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
 	*devattr, char *buf);
 static ssize_t store_fan_beep(struct device *dev, struct device_attribute
@@ -163,6 +194,35 @@
 	*devattr, char *buf);
 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
 	*devattr, char *buf);
+/* PWM and Auto point control */
+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
+	char *buf);
+static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
+	const char *buf, size_t count);
+static ssize_t show_pwm_enable(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_pwm_enable(struct device *dev,
+	struct device_attribute	*devattr, const char *buf, size_t count);
+static ssize_t show_pwm_interpolate(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_pwm_interpolate(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
+static ssize_t show_pwm_auto_point_channel(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_pwm_auto_point_channel(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
+static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
+static ssize_t show_pwm_auto_point_pwm(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_pwm_auto_point_pwm(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
+static ssize_t show_pwm_auto_point_temp(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_pwm_auto_point_temp(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
 /* Sysfs misc */
 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
 	char *buf);
@@ -248,26 +308,220 @@
 	SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2)
 };
 
-static struct sensor_device_attribute_2 f71882fg_fan_attr[] =
-{
+static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
 	SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
+	SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 0),
 	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 0),
 	SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
 	SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
+	SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 1),
 	SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 1),
 	SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
 	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
+	SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 2),
 	SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 2),
 	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
 	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
+	SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
+		      show_fan_full_speed,
+		      store_fan_full_speed, 0, 3),
 	SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
 		store_fan_beep, 0, 3),
-	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3)
-};
+	SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
 
+	SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
+	SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
+		      store_pwm_enable, 0, 0),
+	SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
+		      show_pwm_interpolate, store_pwm_interpolate, 0, 0),
+	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 0),
+	SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      0, 0),
+	SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      1, 0),
+	SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      2, 0),
+	SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      3, 0),
+	SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      4, 0),
+	SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      0, 0),
+	SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      1, 0),
+	SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      2, 0),
+	SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      3, 0),
+	SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp_hyst,
+		      store_pwm_auto_point_temp_hyst,
+		      0, 0),
+	SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 1, 0),
+	SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 2, 0),
+	SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 3, 0),
+
+	SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
+	SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
+		      store_pwm_enable, 0, 1),
+	SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
+		      show_pwm_interpolate, store_pwm_interpolate, 0, 1),
+	SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 1),
+	SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      0, 1),
+	SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      1, 1),
+	SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      2, 1),
+	SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      3, 1),
+	SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      4, 1),
+	SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      0, 1),
+	SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      1, 1),
+	SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      2, 1),
+	SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      3, 1),
+	SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp_hyst,
+		      store_pwm_auto_point_temp_hyst,
+		      0, 1),
+	SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 1, 1),
+	SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 2, 1),
+	SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 3, 1),
+
+	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
+	SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
+		      store_pwm_enable, 0, 2),
+	SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
+		      show_pwm_interpolate, store_pwm_interpolate, 0, 2),
+	SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 2),
+	SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      0, 2),
+	SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      1, 2),
+	SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      2, 2),
+	SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      3, 2),
+	SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      4, 2),
+	SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      0, 2),
+	SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      1, 2),
+	SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      2, 2),
+	SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      3, 2),
+	SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp_hyst,
+		      store_pwm_auto_point_temp_hyst,
+		      0, 2),
+	SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 1, 2),
+	SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 2, 2),
+	SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
+
+	SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
+	SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
+		      store_pwm_enable, 0, 3),
+	SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
+		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
+	SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_channel,
+		      store_pwm_auto_point_channel, 0, 3),
+	SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      0, 3),
+	SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      1, 3),
+	SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      2, 3),
+	SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      3, 3),
+	SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
+		      4, 3),
+	SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      0, 3),
+	SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      1, 3),
+	SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      2, 3),
+	SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp, store_pwm_auto_point_temp,
+		      3, 3),
+	SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
+		      show_pwm_auto_point_temp_hyst,
+		      store_pwm_auto_point_temp_hyst,
+		      0, 3),
+	SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 1, 3),
+	SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 2, 3),
+	SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
+		      show_pwm_auto_point_temp_hyst, NULL, 3, 3)
+};
 
 /* Super I/O functions */
 static inline int superio_inb(int base, int reg)
@@ -309,6 +563,11 @@
 	return reg ? (1500000 / reg) : 0;
 }
 
+static inline u16 fan_to_reg(u16 fan)
+{
+	return fan ? (1500000 / fan) : 0;
+}
+
 static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
 {
 	u8 val;
@@ -337,7 +596,15 @@
 	outb(val, data->addr + DATA_REG_OFFSET);
 }
 
-static struct f71882fg_data *f71882fg_update_device(struct device * dev)
+static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
+{
+	outb(reg++, data->addr + ADDR_REG_OFFSET);
+	outb(val >> 8, data->addr + DATA_REG_OFFSET);
+	outb(reg, data->addr + ADDR_REG_OFFSET);
+	outb(val & 255, data->addr + DATA_REG_OFFSET);
+}
+
+static struct f71882fg_data *f71882fg_update_device(struct device *dev)
 {
 	struct f71882fg_data *data = dev_get_drvdata(dev);
 	int nr, reg, reg2;
@@ -383,6 +650,32 @@
 
 		data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
 
+		data->pwm_enable = f71882fg_read8(data,
+						  F71882FG_REG_PWM_ENABLE);
+		data->pwm_auto_point_hyst[0] = f71882fg_read8(data,
+						      F71882FG_REG_FAN_HYST0);
+		data->pwm_auto_point_hyst[1] = f71882fg_read8(data,
+						      F71882FG_REG_FAN_HYST1);
+		for (nr = 0; nr < 4; nr++) {
+			int point;
+
+			data->pwm_auto_point_mapping[nr] =
+			    f71882fg_read8(data,
+					   F71882FG_REG_POINT_MAPPING(nr));
+
+			for (point = 0; point < 5; point++) {
+				data->pwm_auto_point_pwm[nr][point] =
+				    f71882fg_read8(data,
+						   F71882FG_REG_POINT_PWM
+						   (nr, point));
+			}
+			for (point = 0; point < 4; point++) {
+				data->pwm_auto_point_temp[nr][point] =
+				    f71882fg_read8(data,
+						   F71882FG_REG_POINT_TEMP
+						   (nr, point));
+			}
+		}
 		data->last_limits = jiffies;
 	}
 
@@ -398,9 +691,17 @@
 
 		data->fan_status = f71882fg_read8(data,
 						F71882FG_REG_FAN_STATUS);
-		for (nr = 0; nr < 4; nr++)
+		for (nr = 0; nr < 4; nr++) {
 			data->fan[nr] = f71882fg_read16(data,
 						F71882FG_REG_FAN(nr));
+			data->fan_target[nr] =
+			    f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
+			data->fan_full_speed[nr] =
+			    f71882fg_read16(data,
+					    F71882FG_REG_FAN_FULL_SPEED(nr));
+			data->pwm[nr] =
+			    f71882fg_read8(data, F71882FG_REG_PWM(nr));
+		}
 
 		data->in_status = f71882fg_read8(data,
 						F71882FG_REG_IN_STATUS);
@@ -431,6 +732,40 @@
 	return sprintf(buf, "%d\n", speed);
 }
 
+static ssize_t show_fan_full_speed(struct device *dev,
+				   struct device_attribute *devattr, char *buf)
+{
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	int speed = fan_from_reg(data->fan_full_speed[nr]);
+	return sprintf(buf, "%d\n", speed);
+}
+
+static ssize_t store_fan_full_speed(struct device *dev,
+				    struct device_attribute *devattr,
+				    const char *buf, size_t count)
+{
+	struct f71882fg_data *data = dev_get_drvdata(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	long val = simple_strtol(buf, NULL, 10);
+
+	val = SENSORS_LIMIT(val, 23, 1500000);
+	val = fan_to_reg(val);
+
+	mutex_lock(&data->update_lock);
+	if (data->pwm_enable & (1 << (2 * nr)))
+		/* PWM mode */
+		count = -EINVAL;
+	else {
+		/* RPM mode */
+		f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
+		data->fan_full_speed[nr] = val;
+	}
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
 static ssize_t show_fan_beep(struct device *dev, struct device_attribute
 	*devattr, char *buf)
 {
@@ -738,6 +1073,323 @@
 		return sprintf(buf, "0\n");
 }
 
+static ssize_t show_pwm(struct device *dev,
+			struct device_attribute *devattr, char *buf)
+{
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int val, nr = to_sensor_dev_attr_2(devattr)->index;
+	if (data->pwm_enable & (1 << (2 * nr)))
+		/* PWM mode */
+		val = data->pwm[nr];
+	else {
+		/* RPM mode */
+		mutex_lock(&data->update_lock);
+		val = 255 * fan_from_reg(data->fan_target[nr])
+			/ fan_from_reg(data->fan_full_speed[nr]);
+		mutex_unlock(&data->update_lock);
+	}
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t store_pwm(struct device *dev,
+			 struct device_attribute *devattr, const char *buf,
+			 size_t count)
+{
+	/* struct f71882fg_data *data = dev_get_drvdata(dev); */
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	long val = simple_strtol(buf, NULL, 10);
+	val = SENSORS_LIMIT(val, 0, 255);
+
+	mutex_lock(&data->update_lock);
+	if (data->pwm_enable & (1 << (2 * nr))) {
+		/* PWM mode */
+		f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
+		data->pwm[nr] = val;
+	} else {
+		/* RPM mode */
+		int target = val * fan_from_reg(data->fan_full_speed[nr]) / 255;
+		f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr),
+				 fan_to_reg(target));
+		data->fan_target[nr] = fan_to_reg(target);
+	}
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_pwm_enable(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
+{
+	int result;
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+
+	if (data->pwm_enable & (2 << (2 * nr)))
+		result = 1;
+	else
+		result = 2;
+
+	return sprintf(buf, "%d\n", result);
+}
+
+static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
+				*devattr, const char *buf, size_t count)
+{
+	struct f71882fg_data *data = dev_get_drvdata(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	long val = simple_strtol(buf, NULL, 10);
+	if (val < 1 || val > 2)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	switch (val) {
+	case 1:
+		data->pwm_enable |= 2 << (2 * nr);
+		break;		/* Manual */
+	case 2:
+		data->pwm_enable &= ~(2 << (2 * nr));
+		break;		/* Temperature ctrl */
+	}
+	switch (fan_mode[nr]) {
+	case 1:
+		data->pwm_enable |= 1 << (2 * nr);
+		break;		/* Duty cycle mode */
+	case 2:
+		data->pwm_enable &= ~(1 << (2 * nr));
+		break;		/* RPM mode */
+	}
+	f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_pwm_auto_point_pwm(struct device *dev,
+				       struct device_attribute *devattr,
+				       char *buf)
+{
+	int result;
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int pwm = to_sensor_dev_attr_2(devattr)->index;
+	int point = to_sensor_dev_attr_2(devattr)->nr;
+
+	if (data->pwm_enable & (1 << (2 * pwm))) {
+		/* PWM mode */
+		result = data->pwm_auto_point_pwm[pwm][point];
+	} else {
+		/* RPM mode */
+		result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
+	}
+
+	return sprintf(buf, "%d\n", result);
+}
+
+static ssize_t store_pwm_auto_point_pwm(struct device *dev,
+					struct device_attribute *devattr,
+					const char *buf, size_t count)
+{
+	/* struct f71882fg_data *data = dev_get_drvdata(dev); */
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int pwm = to_sensor_dev_attr_2(devattr)->index;
+	int point = to_sensor_dev_attr_2(devattr)->nr;
+	int val = simple_strtoul(buf, NULL, 10);
+	val = SENSORS_LIMIT(val, 0, 255);
+
+	mutex_lock(&data->update_lock);
+	if (data->pwm_enable & (1 << (2 * pwm))) {
+		/* PWM mode */
+	} else {
+		/* RPM mode */
+		if (val < 29)	/* Prevent negative numbers */
+			val = 255;
+		else
+			val = (255 - val) * 32 / val;
+	}
+	f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
+	data->pwm_auto_point_pwm[pwm][point] = val;
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
+					     struct device_attribute *devattr,
+					     char *buf)
+{
+	int result = 0;
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	int point = to_sensor_dev_attr_2(devattr)->nr;
+
+	mutex_lock(&data->update_lock);
+	switch (nr) {
+	case 0:
+		result = data->pwm_auto_point_hyst[0] & 15;
+		break;
+	case 1:
+		result = data->pwm_auto_point_hyst[0] >> 4;
+		break;
+	case 2:
+		result = data->pwm_auto_point_hyst[1] & 15;
+		break;
+	case 3:
+		result = data->pwm_auto_point_hyst[1] >> 4;
+		break;
+	}
+	result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%d\n", result);
+}
+
+static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
+					      struct device_attribute *devattr,
+					      const char *buf, size_t count)
+{
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	int point = to_sensor_dev_attr_2(devattr)->nr;
+	long val = simple_strtol(buf, NULL, 10) / 1000;
+
+	mutex_lock(&data->update_lock);
+	val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
+				data->pwm_auto_point_temp[nr][point]);
+	val = data->pwm_auto_point_temp[nr][point] - val;
+
+	switch (nr) {
+	case 0:
+		val = (data->pwm_auto_point_hyst[0] & 0xf0) | val;
+		break;
+	case 1:
+		val = (data->pwm_auto_point_hyst[0] & 0x0f) | (val << 4);
+		break;
+	case 2:
+		val = (data->pwm_auto_point_hyst[1] & 0xf0) | val;
+		break;
+	case 3:
+		val = (data->pwm_auto_point_hyst[1] & 0x0f) | (val << 4);
+		break;
+	}
+	if (nr == 0 || nr == 1) {
+		f71882fg_write8(data, F71882FG_REG_FAN_HYST0, val);
+		data->pwm_auto_point_hyst[0] = val;
+	} else {
+		f71882fg_write8(data, F71882FG_REG_FAN_HYST1, val);
+		data->pwm_auto_point_hyst[1] = val;
+	}
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_pwm_interpolate(struct device *dev,
+				    struct device_attribute *devattr, char *buf)
+{
+	int result;
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+
+	result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
+
+	return sprintf(buf, "%d\n", result);
+}
+
+static ssize_t store_pwm_interpolate(struct device *dev,
+				     struct device_attribute *devattr,
+				     const char *buf, size_t count)
+{
+	/* struct f71882fg_data *data = dev_get_drvdata(dev); */
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	int val = simple_strtoul(buf, NULL, 10);
+	mutex_lock(&data->update_lock);
+	if (val)
+		val = data->pwm_auto_point_mapping[nr] | (1 << 4);
+	else
+		val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
+	f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
+	data->pwm_auto_point_mapping[nr] = val;
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_pwm_auto_point_channel(struct device *dev,
+					   struct device_attribute *devattr,
+					   char *buf)
+{
+	int result;
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+
+	result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - 1);
+
+	return sprintf(buf, "%d\n", result);
+}
+
+static ssize_t store_pwm_auto_point_channel(struct device *dev,
+					    struct device_attribute *devattr,
+					    const char *buf, size_t count)
+{
+	/* struct f71882fg_data *data = dev_get_drvdata(dev); */
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int nr = to_sensor_dev_attr_2(devattr)->index;
+	long val = simple_strtol(buf, NULL, 10);
+	switch (val) {
+	case 1:
+		val = 1;
+		break;
+	case 2:
+		val = 2;
+		break;
+	case 4:
+		val = 3;
+		break;
+	default:
+		return -EINVAL;
+	}
+	mutex_lock(&data->update_lock);
+	val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
+	f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
+	data->pwm_auto_point_mapping[nr] = val;
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t show_pwm_auto_point_temp(struct device *dev,
+					struct device_attribute *devattr,
+					char *buf)
+{
+	int result;
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int pwm = to_sensor_dev_attr_2(devattr)->index;
+	int point = to_sensor_dev_attr_2(devattr)->nr;
+
+	result = data->pwm_auto_point_temp[pwm][point];
+	return sprintf(buf, "%d\n", 1000 * result);
+}
+
+static ssize_t store_pwm_auto_point_temp(struct device *dev,
+					 struct device_attribute *devattr,
+					 const char *buf, size_t count)
+{
+	/* struct f71882fg_data *data = dev_get_drvdata(dev); */
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int pwm = to_sensor_dev_attr_2(devattr)->index;
+	int point = to_sensor_dev_attr_2(devattr)->nr;
+	long val = simple_strtol(buf, NULL, 10) / 1000;
+	val = SENSORS_LIMIT(val, 0, 255);
+
+	mutex_lock(&data->update_lock);
+	f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
+	data->pwm_auto_point_temp[pwm][point] = val;
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
 	char *buf)
 {

[-- Attachment #3: Type: text/plain, Size: 153 bytes --]

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2]
  2008-10-20  9:29 [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2] Hans de Goede
@ 2008-10-20 13:43 ` Jean Delvare
  2008-10-20 16:50 ` Jean Delvare
  2008-10-20 17:26 ` Hans de Goede
  2 siblings, 0 replies; 5+ messages in thread
From: Jean Delvare @ 2008-10-20 13:43 UTC (permalink / raw)
  To: lm-sensors

On Mon, 20 Oct 2008 11:28:38 +0200, Hans de Goede wrote:
> From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
> 
> Hi Jean (and all),
> 
> Convert f71882fg driver from SENSOR_ATTR to SENSOR_ATTR2 use, this is a
> preparation patch for adding pwm support, which is broken out to make what
> changes really in the pwm support patch clear.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>

Note: Signed-off-by supersedes Reviewed-by.

> CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
> 
> Regards,

Applied, thanks.

For future patches, please come up with better subjects. For this
one I've used:

hwmon: (f71882fg) Use sensor_device_attribute_2

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2]
  2008-10-20  9:29 [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2] Hans de Goede
  2008-10-20 13:43 ` Jean Delvare
@ 2008-10-20 16:50 ` Jean Delvare
  2008-10-20 17:26 ` Hans de Goede
  2 siblings, 0 replies; 5+ messages in thread
From: Jean Delvare @ 2008-10-20 16:50 UTC (permalink / raw)
  To: lm-sensors

Hi Hans,

On Mon, 20 Oct 2008 11:29:04 +0200, Hans de Goede wrote:
> From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
> 
> Hi Jean (and all),
> 
> Add pwm support to the f71882fg driver. Changes made by me to the latest
> revision submitted by Mark van Doesburg:
> -Remove whitespace only changes from the patch (undo Lindent damage)
> -Change pwm#_auto_point#_temp unit from degrees to milli degrees celcius
> -Remove incomplete ability to turn of pwm (pwm#_enable = 0), as the hardware
>   does not support this
> -Made handling of out of range input to sysfs files more robust
> -When we write a new setting to IC update our local cached copy of the register
>   being written

This is hardly a valid patch description for git. We don't care much
about the incremental patches there, what we want to know is what the
final patch is doing, why and how. I'll try to come up with something
myself this time...

> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
> CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>

Preliminary note: I've split 5 unrelated coding style cleanups to a
separate patch, and cleaned up defines a bit (spaces -> tabs and
missing parentheses.

I am not totally happy with this patch:

> +static int fan_mode[4] = { 0, 0, 0, 0 };
> +module_param_array(fan_mode, int, NULL, 0644);
> +MODULE_PARM_DESC(fan_mode, "List of fan control modes (f71882fg only)"
> +		 "(0=don't change, 1=pwm, 2=rpm)\n"
> +		 "Note: this needs a write to pwm#_enable to take effect");

I don't really like this. But... I see that this is a result of
previous discussions on the lm-sensors list I didn't take part to, so
it's probably too late for me to object. And probably all interested
parties have better things to do than reworking and retesting such a
large patch. So, I'll take the patch as is.

-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2]
  2008-10-20  9:29 [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2] Hans de Goede
  2008-10-20 13:43 ` Jean Delvare
  2008-10-20 16:50 ` Jean Delvare
@ 2008-10-20 17:26 ` Hans de Goede
  2 siblings, 0 replies; 5+ messages in thread
From: Hans de Goede @ 2008-10-20 17:26 UTC (permalink / raw)
  To: lm-sensors



Jean Delvare wrote:
> Hi Hans,
> 
> On Mon, 20 Oct 2008 11:29:04 +0200, Hans de Goede wrote:
>> From: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
>>
>> Hi Jean (and all),
>>
>> Add pwm support to the f71882fg driver. Changes made by me to the latest
>> revision submitted by Mark van Doesburg:
>> -Remove whitespace only changes from the patch (undo Lindent damage)
>> -Change pwm#_auto_point#_temp unit from degrees to milli degrees celcius
>> -Remove incomplete ability to turn of pwm (pwm#_enable = 0), as the hardware
>>   does not support this
>> -Made handling of out of range input to sysfs files more robust
>> -When we write a new setting to IC update our local cached copy of the register
>>   being written
> 
> This is hardly a valid patch description for git. We don't care much
> about the incremental patches there, what we want to know is what the
> final patch is doing, why and how. I'll try to come up with something
> myself this time...
> 

Well the final patch: "Adds pwm support to the f71882fg driver" I know that 
isn't much of a description for such a large patch, but that is basicly it.

>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
>> CC: Mark van Doesburg <mark.vandoesburg@hetnet.nl>
> 
> Preliminary note: I've split 5 unrelated coding style cleanups to a
> separate patch, and cleaned up defines a bit (spaces -> tabs and
> missing parentheses.
> 

Thanks!

> I am not totally happy with this patch:
> 
>> +static int fan_mode[4] = { 0, 0, 0, 0 };
>> +module_param_array(fan_mode, int, NULL, 0644);
>> +MODULE_PARM_DESC(fan_mode, "List of fan control modes (f71882fg only)"
>> +		 "(0=don't change, 1=pwm, 2=rpm)\n"
>> +		 "Note: this needs a write to pwm#_enable to take effect");
> 
> I don't really like this. But... I see that this is a result of
> previous discussions on the lm-sensors list I didn't take part to, so
> it's probably too late for me to object. And probably all interested
> parties have better things to do than reworking and retesting such a
> large patch. So, I'll take the patch as is.

Thanks, note that I'm not entirely happy with this myself either, I added the
"Note: this needs a write to pwm#_enable to take effect" comment to make 
atleast that much clear. The only reason for this option really is to be able 
to test both code paths easily (without it we default to whatever the BIOS has 
programmed the chip in). I've considered putting "testing use only" in the 
parameter description but I didn't think that would do any good either, we 
could put the option code in #ifdef DEBUG or something like that, but that 
didn't feel right either (I don't want this to require a recompile). So I guess 
this is just the best we can do, this or remove the option completely (which is 
a simple patch to make).

Regards,

Hans


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-10-20 17:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-20  9:29 [lm-sensors] PATCH: f71882fg-sensor_attr2.patch [1/2] Hans de Goede
2008-10-20 13:43 ` Jean Delvare
2008-10-20 16:50 ` Jean Delvare
2008-10-20 17:26 ` Hans de Goede
  -- strict thread matches above, loose matches on Subject: below --
2008-10-20  9:28 Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.