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/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++) {