hwmon: (it87) Add support for fan4 and fan5

Add support for the IT8716F and IT8718F fan4 and fan5. The late
revisions of the IT8712F have these too but support is harder to add
and nobody asked for it yet, so I didn't include it.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 81ecc7e..5b704a4 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -90,7 +90,8 @@
 can't have both on a given board.
 
 The IT8716F, IT8718F and later IT8712F revisions have support for
-2 additional fans. They are not yet supported by the driver.
+2 additional fans. They are supported by the driver for the IT8716F and
+IT8718F but not for the IT8712F
 
 The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional
 16-bit tachometer counters for fans 1 to 3. This is better (no more fan
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 41a90e56..cd741b7 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -141,10 +141,10 @@
 
 /* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */
 
-#define IT87_REG_FAN(nr)       (0x0d + (nr))
-#define IT87_REG_FAN_MIN(nr)   (0x10 + (nr))
-#define IT87_REG_FANX(nr)      (0x18 + (nr))
-#define IT87_REG_FANX_MIN(nr)  (0x1b + (nr))
+static const u8 IT87_REG_FAN[]		= { 0x0d, 0x0e, 0x0f, 0x80, 0x82 };
+static const u8 IT87_REG_FAN_MIN[]	= { 0x10, 0x11, 0x12, 0x84, 0x86 };
+static const u8 IT87_REG_FANX[]		= { 0x18, 0x19, 0x1a, 0x81, 0x83 };
+static const u8 IT87_REG_FANX_MIN[]	= { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
 #define IT87_REG_FAN_MAIN_CTRL 0x13
 #define IT87_REG_FAN_CTL       0x14
 #define IT87_REG_PWM(nr)       (0x15 + (nr))
@@ -235,8 +235,8 @@
 	u8 in_max[8];		/* Register value */
 	u8 in_min[8];		/* Register value */
 	u8 has_fan;		/* Bitfield, fans enabled */
-	u16 fan[3];		/* Register values, possibly combined */
-	u16 fan_min[3];		/* Register values, possibly combined */
+	u16 fan[5];		/* Register values, possibly combined */
+	u16 fan_min[5];		/* Register values, possibly combined */
 	u8 temp[3];		/* Register value */
 	u8 temp_high[3];	/* Register value */
 	u8 temp_low[3];		/* Register value */
@@ -555,7 +555,7 @@
 	}
 
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-	it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
+	it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -596,7 +596,7 @@
 
 	/* Restore fan min limit */
 	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	it87_write_value(data, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
+	it87_write_value(data, IT87_REG_FAN_MIN[nr], data->fan_min[nr]);
 
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -729,9 +729,9 @@
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN16_TO_REG(val);
-	it87_write_value(data, IT87_REG_FAN_MIN(nr),
+	it87_write_value(data, IT87_REG_FAN_MIN[nr],
 			 data->fan_min[nr] & 0xff);
-	it87_write_value(data, IT87_REG_FANX_MIN(nr),
+	it87_write_value(data, IT87_REG_FANX_MIN[nr],
 			 data->fan_min[nr] >> 8);
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -751,6 +751,8 @@
 show_fan16_offset(1);
 show_fan16_offset(2);
 show_fan16_offset(3);
+show_fan16_offset(4);
+show_fan16_offset(5);
 
 /* Alarms */
 static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
@@ -851,6 +853,10 @@
 	&sensor_dev_attr_fan2_min16.dev_attr.attr,
 	&sensor_dev_attr_fan3_input16.dev_attr.attr,
 	&sensor_dev_attr_fan3_min16.dev_attr.attr,
+	&sensor_dev_attr_fan4_input16.dev_attr.attr,
+	&sensor_dev_attr_fan4_min16.dev_attr.attr,
+	&sensor_dev_attr_fan5_input16.dev_attr.attr,
+	&sensor_dev_attr_fan5_min16.dev_attr.attr,
 
 	&sensor_dev_attr_fan1_input.dev_attr.attr,
 	&sensor_dev_attr_fan1_min.dev_attr.attr,
@@ -1024,6 +1030,20 @@
 			     &sensor_dev_attr_fan3_min16.dev_attr)))
 				goto ERROR4;
 		}
+		if (data->has_fan & (1 << 3)) {
+			if ((err = device_create_file(dev,
+			     &sensor_dev_attr_fan4_input16.dev_attr))
+			 || (err = device_create_file(dev,
+			     &sensor_dev_attr_fan4_min16.dev_attr)))
+				goto ERROR4;
+		}
+		if (data->has_fan & (1 << 4)) {
+			if ((err = device_create_file(dev,
+			     &sensor_dev_attr_fan5_input16.dev_attr))
+			 || (err = device_create_file(dev,
+			     &sensor_dev_attr_fan5_min16.dev_attr)))
+				goto ERROR4;
+		}
 	} else {
 		/* 8-bit tachometers with clock divider */
 		if (data->has_fan & (1 << 0)) {
@@ -1260,6 +1280,10 @@
 			it87_write_value(data, IT87_REG_FAN_16BIT,
 					 tmp | 0x07);
 		}
+		if (tmp & (1 << 4))
+			data->has_fan |= (1 << 3);	/* fan4 enabled */
+		if (tmp & (1 << 5))
+			data->has_fan |= (1 << 4);	/* fan5 enabled */
 	}
 
 	/* Set current fan mode registers and the default settings for the
@@ -1314,21 +1338,21 @@
 		data->in[8] =
 		    it87_read_value(data, IT87_REG_VIN(8));
 
-		for (i = 0; i < 3; i++) {
+		for (i = 0; i < 5; i++) {
 			/* Skip disabled fans */
 			if (!(data->has_fan & (1 << i)))
 				continue;
 
 			data->fan_min[i] =
-			    it87_read_value(data, IT87_REG_FAN_MIN(i));
+			    it87_read_value(data, IT87_REG_FAN_MIN[i]);
 			data->fan[i] = it87_read_value(data,
-				       IT87_REG_FAN(i));
+				       IT87_REG_FAN[i]);
 			/* Add high byte if in 16-bit mode */
 			if (data->type == it8716 || data->type == it8718) {
 				data->fan[i] |= it87_read_value(data,
-						IT87_REG_FANX(i)) << 8;
+						IT87_REG_FANX[i]) << 8;
 				data->fan_min[i] |= it87_read_value(data,
-						IT87_REG_FANX_MIN(i)) << 8;
+						IT87_REG_FANX_MIN[i]) << 8;
 			}
 		}
 		for (i = 0; i < 3; i++) {