All of lore.kernel.org
 help / color / mirror / Atom feed
* [lm-sensors] [PATCH v3 15/25] hwmon: (it87) Support up to 6 temperature sensors on IT8620E
@ 2016-01-27  2:03 Guenter Roeck
  0 siblings, 0 replies; only message in thread
From: Guenter Roeck @ 2016-01-27  2:03 UTC (permalink / raw)
  To: lm-sensors

From: Guenter Roeck <linux@roeck-us.net>

Add support for the additional temperature sensors on IT8620E.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/hwmon/it87.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index e02c972ef81e..722d6de62d1c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -219,7 +219,7 @@ static bool fix_pwm_polarity;
 #define IT87_REG_FAN_DIV       0x0b
 #define IT87_REG_FAN_16BIT     0x0c
 
-/* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */
+/* Monitors: 9 voltage (0 to 7, battery), 6 temp (1 to 6), 3 fan (1 to 3) */
 
 static const u8 IT87_REG_FAN[]         = { 0x0d, 0x0e, 0x0f, 0x80, 0x82, 0x4c };
 static const u8 IT87_REG_FAN_MIN[]     = { 0x10, 0x11, 0x12, 0x84, 0x86, 0x4e };
@@ -252,10 +252,12 @@ static const u8 IT87_REG_PWM_DUTY[]    = { 0x63, 0x6b, 0x73, 0x7b, 0xa3, 0xab };
 #define IT87_REG_AUTO_TEMP(nr, i) (0x60 + (nr) * 8 + (i))
 #define IT87_REG_AUTO_PWM(nr, i)  (0x65 + (nr) * 8 + (i))
 
+#define IT87_REG_TEMP456_ENABLE	0x77
+
 struct it87_devices {
 	const char *name;
 	const char * const suffix;
-	u16 features;
+	u32 features;
 	u8 peci_mask;
 	u8 old_peci_mask;
 };
@@ -276,6 +278,7 @@ struct it87_devices {
 #define FEAT_AVCC3		(1 << 13)	/* Chip supports in9/AVCC3 */
 #define FEAT_SIX_PWM		(1 << 14)	/* Chip supports 6 pwm chn */
 #define FEAT_PWM_FREQ2		(1 << 15)	/* Separate pwm freq 2 */
+#define FEAT_SIX_TEMP		(1 << 16)	/* Up to 6 temp sensors */
 
 static const struct it87_devices it87_devices[] = {
 	[it87] = {
@@ -412,7 +415,8 @@ static const struct it87_devices it87_devices[] = {
 		.suffix = "E",
 		.features = FEAT_NEWER_AUTOPWM | FEAT_12MV_ADC | FEAT_16BIT_FANS
 		  | FEAT_TEMP_OFFSET | FEAT_TEMP_PECI | FEAT_SIX_FANS
-		  | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2,
+		  | FEAT_IN7_INTERNAL | FEAT_SIX_PWM | FEAT_PWM_FREQ2
+		  | FEAT_SIX_TEMP,
 		.peci_mask = 0x07,
 	},
 };
@@ -437,6 +441,7 @@ static const struct it87_devices it87_devices[] = {
 #define has_avcc3(data)		((data)->features & FEAT_AVCC3)
 #define has_six_pwm(data)	((data)->features & FEAT_SIX_PWM)
 #define has_pwm_freq2(data)	((data)->features & FEAT_PWM_FREQ2)
+#define has_six_temp(data)	((data)->features & FEAT_SIX_TEMP)
 
 struct it87_sio_data {
 	enum chips type;
@@ -477,7 +482,7 @@ struct it87_data {
 	u8 has_fan;		/* Bitfield, fans enabled */
 	u16 fan[6][2];		/* Register values, [nr][0]ún, [1]=min */
 	u8 has_temp;		/* Bitfield, temp sensors enabled */
-	s8 temp[3][4];		/* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
+	s8 temp[6][4];		/* [nr][0]=temp, [1]=min, [2]=max, [3]=offset */
 	u8 sensor;		/* Register value (IT87_REG_TEMP_ENABLE) */
 	u8 extra;		/* Register value (IT87_REG_TEMP_EXTRA) */
 	u8 fan_div[3];		/* Register encoding, shifted right */
@@ -704,11 +709,16 @@ static struct it87_data *it87_update_device(struct device *dev)
 						IT87_REG_FANX_MIN[i]) << 8;
 			}
 		}
-		for (i = 0; i < 3; i++) {
+		for (i = 0; i < 6; i++) {
 			if (!(data->has_temp & (1 << i)))
 				continue;
 			data->temp[i][0]  				it87_read_value(data, IT87_REG_TEMP(i));
+
+			/* No limits/offset for additional sensors */
+			if (i >= 3)
+				continue;
+
 			data->temp[i][1]  				it87_read_value(data, IT87_REG_TEMP_LOW(i));
 			data->temp[i][2] @@ -848,7 +858,7 @@ static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
 static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
 static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0);
 
-/* 3 temperatures */
+/* Up to 6 temperatures */
 static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
 			 char *buf)
 {
@@ -921,6 +931,9 @@ static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
 			    2, 2);
 static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
 			    set_temp, 2, 3);
+static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0);
+static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0);
+static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0);
 
 static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
 			      char *buf)
@@ -1828,6 +1841,11 @@ static umode_t it87_temp_is_visible(struct kobject *kobj,
 	int i = index / 7;	/* temperature index */
 	int a = index % 7;	/* attribute index */
 
+	if (index >= 21) {
+		i = index - 21 + 3;
+		a = 0;
+	}
+
 	if (!(data->has_temp & (1 << i)))
 		return 0;
 
@@ -1849,7 +1867,7 @@ static struct attribute *it87_attributes_temp[] = {
 	&sensor_dev_attr_temp1_offset.dev_attr.attr,	/* 5 */
 	&sensor_dev_attr_temp1_beep.dev_attr.attr,	/* 6 */
 
-	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,	/* 7 */
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_min.dev_attr.attr,
 	&sensor_dev_attr_temp2_type.dev_attr.attr,
@@ -1857,7 +1875,7 @@ static struct attribute *it87_attributes_temp[] = {
 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
 	&sensor_dev_attr_temp2_beep.dev_attr.attr,
 
-	&sensor_dev_attr_temp3_input.dev_attr.attr,
+	&sensor_dev_attr_temp3_input.dev_attr.attr,	/* 14 */
 	&sensor_dev_attr_temp3_max.dev_attr.attr,
 	&sensor_dev_attr_temp3_min.dev_attr.attr,
 	&sensor_dev_attr_temp3_type.dev_attr.attr,
@@ -1865,6 +1883,9 @@ static struct attribute *it87_attributes_temp[] = {
 	&sensor_dev_attr_temp3_offset.dev_attr.attr,
 	&sensor_dev_attr_temp3_beep.dev_attr.attr,
 
+	&sensor_dev_attr_temp4_input.dev_attr.attr,	/* 21 */
+	&sensor_dev_attr_temp5_input.dev_attr.attr,
+	&sensor_dev_attr_temp6_input.dev_attr.attr,
 	NULL
 };
 
@@ -2710,6 +2731,17 @@ static int it87_probe(struct platform_device *pdev)
 	data->in_internal = sio_data->internal;
 	data->has_in = 0x3ff & ~sio_data->skip_in;
 
+	if (has_six_temp(data)) {
+		u8 reg = it87_read_value(data, IT87_REG_TEMP456_ENABLE);
+
+		if ((reg & 0x03) >= 0x02)
+			data->has_temp |= (1 << 3);
+		if (((reg >> 2) & 0x03) >= 0x02)
+			data->has_temp |= (1 << 4);
+		if (((reg >> 4) & 0x03) >= 0x02)
+			data->has_temp |= (1 << 5);
+	}
+
 	data->has_beep = !!sio_data->beep_pin;
 
 	/* Initialize the IT87 chip */
-- 
2.1.4


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

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2016-01-27  2:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-27  2:03 [lm-sensors] [PATCH v3 15/25] hwmon: (it87) Support up to 6 temperature sensors on IT8620E Guenter Roeck

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.