浏览代码

hwmon: (dme1737) Add support for in7 for SCH5127

Add support for the 1.5V voltage monitoring input (in7) of the
SMSC SCH5127 chip.

Signed-off-by: Juerg Haefliger <juergh@gmail.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Juerg Haefliger 14 年之前
父节点
当前提交
d4b94e1fa6
共有 2 个文件被更改,包括 60 次插入20 次删除
  1. 7 5
      Documentation/hwmon/dme1737
  2. 53 15
      drivers/hwmon/dme1737.c

+ 7 - 5
Documentation/hwmon/dme1737

@@ -42,7 +42,7 @@ Description
 This driver implements support for the hardware monitoring capabilities of the
 This driver implements support for the hardware monitoring capabilities of the
 SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, SCH311x,
 SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, SCH311x,
 and SCH5127 Super-I/O chips. These chips feature monitoring of 3 temp sensors
 and SCH5127 Super-I/O chips. These chips feature monitoring of 3 temp sensors
-temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and
+temp[1-3] (2 remote diodes and 1 internal), 8 voltages in[0-7] (7 external and
 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement
 1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement
 up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and
 up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and
 automatically.
 automatically.
@@ -105,6 +105,7 @@ SCH5127:
 	in4: V1_IN				0V - 1.5V
 	in4: V1_IN				0V - 1.5V
 	in5: VTR	(+3.3V standby)		0V - 4.38V
 	in5: VTR	(+3.3V standby)		0V - 4.38V
 	in6: Vbat	(+3.0V)			0V - 4.38V
 	in6: Vbat	(+3.0V)			0V - 4.38V
+	in7: Vtrip	(+1.5V)			0V - 1.99V
 
 
 Each voltage input has associated min and max limits which trigger an alarm
 Each voltage input has associated min and max limits which trigger an alarm
 when crossed.
 when crossed.
@@ -217,10 +218,10 @@ cpu0_vid			RO	CPU core reference voltage in
 vrm				RW	Voltage regulator module version
 vrm				RW	Voltage regulator module version
 					number.
 					number.
 
 
-in[0-6]_input			RO	Measured voltage in millivolts.
-in[0-6]_min			RW	Low limit for voltage input.
-in[0-6]_max			RW	High limit for voltage input.
-in[0-6]_alarm			RO	Voltage input alarm. Returns 1 if
+in[0-7]_input			RO	Measured voltage in millivolts.
+in[0-7]_min			RW	Low limit for voltage input.
+in[0-7]_max			RW	High limit for voltage input.
+in[0-7]_alarm			RO	Voltage input alarm. Returns 1 if
 					voltage input is or went outside the
 					voltage input is or went outside the
 					associated min-max range, 0 otherwise.
 					associated min-max range, 0 otherwise.
 
 
@@ -324,3 +325,4 @@ fan5			opt		opt
 pwm5			opt		opt
 pwm5			opt		opt
 fan6			opt		opt
 fan6			opt		opt
 pwm6			opt		opt
 pwm6			opt		opt
+in7						yes

+ 53 - 15
drivers/hwmon/dme1737.c

@@ -77,12 +77,14 @@ enum chips { dme1737, sch5027, sch311x, sch5127 };
  * in4   +12V
  * in4   +12V
  * in5   VTR   (+3.3V stby)
  * in5   VTR   (+3.3V stby)
  * in6   Vbat
  * in6   Vbat
+ * in7   Vtrip (sch5127 only)
  *
  *
  * --------------------------------------------------------------------- */
  * --------------------------------------------------------------------- */
 
 
-/* Voltages (in) numbered 0-6 (ix) */
-#define	DME1737_REG_IN(ix)		((ix) < 5 ? 0x20 + (ix) \
-						  : 0x94 + (ix))
+/* Voltages (in) numbered 0-7 (ix) */
+#define	DME1737_REG_IN(ix)		((ix) < 5 ? 0x20 + (ix) : \
+					 (ix) < 7 ? 0x94 + (ix) : \
+						    0x1f)
 #define	DME1737_REG_IN_MIN(ix)		((ix) < 5 ? 0x44 + (ix) * 2 \
 #define	DME1737_REG_IN_MIN(ix)		((ix) < 5 ? 0x44 + (ix) * 2 \
 						  : 0x91 + (ix) * 2)
 						  : 0x91 + (ix) * 2)
 #define	DME1737_REG_IN_MAX(ix)		((ix) < 5 ? 0x45 + (ix) * 2 \
 #define	DME1737_REG_IN_MAX(ix)		((ix) < 5 ? 0x45 + (ix) * 2 \
@@ -101,10 +103,11 @@ enum chips { dme1737, sch5027, sch311x, sch5127 };
  *    IN_TEMP_LSB(1) = [temp3, temp1]
  *    IN_TEMP_LSB(1) = [temp3, temp1]
  *    IN_TEMP_LSB(2) = [in4, temp2]
  *    IN_TEMP_LSB(2) = [in4, temp2]
  *    IN_TEMP_LSB(3) = [in3, in0]
  *    IN_TEMP_LSB(3) = [in3, in0]
- *    IN_TEMP_LSB(4) = [in2, in1] */
+ *    IN_TEMP_LSB(4) = [in2, in1]
+ *    IN_TEMP_LSB(5) = [res, in7] */
 #define DME1737_REG_IN_TEMP_LSB(ix)	(0x84 + (ix))
 #define DME1737_REG_IN_TEMP_LSB(ix)	(0x84 + (ix))
-static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0};
-static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4};
+static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5};
+static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4};
 static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1};
 static const u8 DME1737_REG_TEMP_LSB[] = {1, 2, 1};
 static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};
 static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};
 
 
@@ -145,7 +148,7 @@ static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};
 #define DME1737_REG_ALARM1		0x41
 #define DME1737_REG_ALARM1		0x41
 #define DME1737_REG_ALARM2		0x42
 #define DME1737_REG_ALARM2		0x42
 #define DME1737_REG_ALARM3		0x83
 #define DME1737_REG_ALARM3		0x83
-static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17};
+static const u8 DME1737_BIT_ALARM_IN[] = {0, 1, 2, 3, 8, 16, 17, 18};
 static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6};
 static const u8 DME1737_BIT_ALARM_TEMP[] = {4, 5, 6};
 static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
 static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
 
 
@@ -190,6 +193,7 @@ static const u8 DME1737_BIT_ALARM_FAN[] = {10, 11, 12, 13, 22, 23};
 #define HAS_PWM_MIN		(1 << 4)		/* bit 4 */
 #define HAS_PWM_MIN		(1 << 4)		/* bit 4 */
 #define HAS_FAN(ix)		(1 << ((ix) + 5))	/* bits 5-10 */
 #define HAS_FAN(ix)		(1 << ((ix) + 5))	/* bits 5-10 */
 #define HAS_PWM(ix)		(1 << ((ix) + 11))	/* bits 11-16 */
 #define HAS_PWM(ix)		(1 << ((ix) + 11))	/* bits 11-16 */
+#define HAS_IN7			(1 << 17)		/* bit 17 */
 
 
 /* ---------------------------------------------------------------------
 /* ---------------------------------------------------------------------
  * Data structures and manipulation thereof
  * Data structures and manipulation thereof
@@ -213,9 +217,9 @@ struct dme1737_data {
 	u32 has_features;
 	u32 has_features;
 
 
 	/* Register values */
 	/* Register values */
-	u16 in[7];
-	u8  in_min[7];
-	u8  in_max[7];
+	u16 in[8];
+	u8  in_min[8];
+	u8  in_max[8];
 	s16 temp[3];
 	s16 temp[3];
 	s8  temp_min[3];
 	s8  temp_min[3];
 	s8  temp_max[3];
 	s8  temp_max[3];
@@ -247,7 +251,7 @@ static const int IN_NOMINAL_SCH311x[] = {2500, 1500, 3300, 5000, 12000, 3300,
 static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300,
 static const int IN_NOMINAL_SCH5027[] = {5000, 2250, 3300, 1125, 1125, 3300,
 					 3300};
 					 3300};
 static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300,
 static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300,
-					 3300};
+					 3300, 1500};
 #define IN_NOMINAL(type)	((type) == sch311x ? IN_NOMINAL_SCH311x : \
 #define IN_NOMINAL(type)	((type) == sch311x ? IN_NOMINAL_SCH311x : \
 				 (type) == sch5027 ? IN_NOMINAL_SCH5027 : \
 				 (type) == sch5027 ? IN_NOMINAL_SCH5027 : \
 				 (type) == sch5127 ? IN_NOMINAL_SCH5127 : \
 				 (type) == sch5127 ? IN_NOMINAL_SCH5127 : \
@@ -580,7 +584,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 {
 {
 	struct dme1737_data *data = dev_get_drvdata(dev);
 	struct dme1737_data *data = dev_get_drvdata(dev);
 	int ix;
 	int ix;
-	u8 lsb[5];
+	u8 lsb[6];
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 
 
@@ -603,6 +607,9 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 			/* Voltage inputs are stored as 16 bit values even
 			/* Voltage inputs are stored as 16 bit values even
 			 * though they have only 12 bits resolution. This is
 			 * though they have only 12 bits resolution. This is
 			 * to make it consistent with the temp inputs. */
 			 * to make it consistent with the temp inputs. */
+			if (ix == 7 && !(data->has_features & HAS_IN7)) {
+				continue;
+			}
 			data->in[ix] = dme1737_read(data,
 			data->in[ix] = dme1737_read(data,
 					DME1737_REG_IN(ix)) << 8;
 					DME1737_REG_IN(ix)) << 8;
 			data->in_min[ix] = dme1737_read(data,
 			data->in_min[ix] = dme1737_read(data,
@@ -635,10 +642,16 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 		 * which the registers are read (MSB first, then LSB) is
 		 * which the registers are read (MSB first, then LSB) is
 		 * important! */
 		 * important! */
 		for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
 		for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
+			if (ix == 5 && !(data->has_features & HAS_IN7)) {
+				continue;
+			}
 			lsb[ix] = dme1737_read(data,
 			lsb[ix] = dme1737_read(data,
 					DME1737_REG_IN_TEMP_LSB(ix));
 					DME1737_REG_IN_TEMP_LSB(ix));
 		}
 		}
 		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
 		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
+			if (ix == 7 && !(data->has_features & HAS_IN7)) {
+				continue;
+			}
 			data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] <<
 			data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] <<
 					DME1737_REG_IN_LSB_SHL[ix]) & 0xf0;
 					DME1737_REG_IN_LSB_SHL[ix]) & 0xf0;
 		}
 		}
@@ -762,7 +775,7 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 
 
 /* ---------------------------------------------------------------------
 /* ---------------------------------------------------------------------
  * Voltage sysfs attributes
  * Voltage sysfs attributes
- * ix = [0-5]
+ * ix = [0-7]
  * --------------------------------------------------------------------- */
  * --------------------------------------------------------------------- */
 
 
 #define SYS_IN_INPUT	0
 #define SYS_IN_INPUT	0
@@ -1439,7 +1452,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute *attr,
  * Sysfs device attribute defines and structs
  * Sysfs device attribute defines and structs
  * --------------------------------------------------------------------- */
  * --------------------------------------------------------------------- */
 
 
-/* Voltages 0-6 */
+/* Voltages 0-7 */
 
 
 #define SENSOR_DEVICE_ATTR_IN(ix) \
 #define SENSOR_DEVICE_ATTR_IN(ix) \
 static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \
 static SENSOR_DEVICE_ATTR_2(in##ix##_input, S_IRUGO, \
@@ -1458,6 +1471,7 @@ SENSOR_DEVICE_ATTR_IN(3);
 SENSOR_DEVICE_ATTR_IN(4);
 SENSOR_DEVICE_ATTR_IN(4);
 SENSOR_DEVICE_ATTR_IN(5);
 SENSOR_DEVICE_ATTR_IN(5);
 SENSOR_DEVICE_ATTR_IN(6);
 SENSOR_DEVICE_ATTR_IN(6);
+SENSOR_DEVICE_ATTR_IN(7);
 
 
 /* Temperatures 1-3 */
 /* Temperatures 1-3 */
 
 
@@ -1695,6 +1709,21 @@ static const struct attribute_group dme1737_zone_hyst_group = {
 	.attrs = dme1737_zone_hyst_attr,
 	.attrs = dme1737_zone_hyst_attr,
 };
 };
 
 
+/* The following struct holds voltage in7 related attributes, which
+ * are not available in all chips. The following chips support them:
+ * SCH5127 */
+static struct attribute *dme1737_in7_attr[] = {
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in7_min.dev_attr.attr,
+	&sensor_dev_attr_in7_max.dev_attr.attr,
+	&sensor_dev_attr_in7_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group dme1737_in7_group = {
+	.attrs = dme1737_in7_attr,
+};
+
 /* The following structs hold the PWM attributes, some of which are optional.
 /* The following structs hold the PWM attributes, some of which are optional.
  * Their creation depends on the chip configuration which is determined during
  * Their creation depends on the chip configuration which is determined during
  * module load. */
  * module load. */
@@ -1986,6 +2015,9 @@ static void dme1737_remove_files(struct device *dev)
 	if (data->has_features & HAS_ZONE_HYST) {
 	if (data->has_features & HAS_ZONE_HYST) {
 		sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group);
 		sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group);
 	}
 	}
+	if (data->has_features & HAS_IN7) {
+		sysfs_remove_group(&dev->kobj, &dme1737_in7_group);
+	}
 	sysfs_remove_group(&dev->kobj, &dme1737_group);
 	sysfs_remove_group(&dev->kobj, &dme1737_group);
 
 
 	if (!data->client) {
 	if (!data->client) {
@@ -2030,6 +2062,12 @@ static int dme1737_create_files(struct device *dev)
 				      &dme1737_zone_hyst_group))) {
 				      &dme1737_zone_hyst_group))) {
 		goto exit_remove;
 		goto exit_remove;
 	}
 	}
+	if (data->has_features & HAS_IN7) {
+		err = sysfs_create_group(&dev->kobj, &dme1737_in7_group);
+		if (err) {
+			goto exit_remove;
+		}
+	}
 
 
 	/* Create fan sysfs attributes */
 	/* Create fan sysfs attributes */
 	for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
 	for (ix = 0; ix < ARRAY_SIZE(dme1737_fan_group); ix++) {
@@ -2188,7 +2226,7 @@ static int dme1737_init_device(struct device *dev)
 		data->has_features |= HAS_ZONE3;
 		data->has_features |= HAS_ZONE3;
 		break;
 		break;
 	case sch5127:
 	case sch5127:
-		data->has_features |= HAS_FAN(2) | HAS_PWM(2);
+		data->has_features |= HAS_FAN(2) | HAS_PWM(2) | HAS_IN7;
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;