[patch] incomplete mtp008.c port to 2.6.18.2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi...

i've recently been resurrecting some tyan s2510 and would like to get 
their mtp008 working.  i found Andrew Pam's patch which brought mtp008 
forward to 2.6.12, but i'd like to run 2.6.18.2 or later.

so i went through the patch and compared it with other 2.6.18 hwmon 
drivers and without really any deep understanding made a bunch of changes 
which seem to have made it mostly work.

i have two problems:

- the lm-sensors userland code seems to expect temp?_over/temp?_hyst files 
for mtp008 but the driver has min/max... i patched lm-sensors for this, 
but maybe i should have fixed the driver instead.

- the mtp008 seems to hang and start reporting all zeroes/constant 
garbage.  i'm skeptical this is just my hacked code though because the 
BIOS "System Health Monitor" has the exact same problem after a few 
minutes.

so... does anyone happen to have a datasheet for this part?

or can anyone spot some obvious boneheadedness in my patch?

note i didn't do the up/down -> mutex conversion yet.

thanks
-dean
-------------- next part --------------
Index: linux/drivers/hwmon/Kconfig
===================================================================
--- linux.orig/drivers/hwmon/Kconfig	2006-11-17 02:10:30.000000000 -0800
+++ linux/drivers/hwmon/Kconfig	2006-11-17 15:42:10.000000000 -0800
@@ -517,4 +517,14 @@
 	  a problem with I2C support and want to see more of what is going
 	  on.
 
+config SENSORS_MTP008
+	tristate "Myson MTP008 sensor chip"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select HWMON_VID
+	help
+	  If you say yes here you get support for MTP008 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called mtp008.
+
 endmenu
Index: linux/drivers/hwmon/Makefile
===================================================================
--- linux.orig/drivers/hwmon/Makefile	2006-11-17 02:10:30.000000000 -0800
+++ linux/drivers/hwmon/Makefile	2006-11-17 02:12:14.000000000 -0800
@@ -39,6 +39,7 @@
 obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
 obj-$(CONFIG_SENSORS_LM92)	+= lm92.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
+obj-$(CONFIG_SENSORS_MTP008)	+= mtp008.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595.o
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
Index: linux/drivers/hwmon/mtp008.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux/drivers/hwmon/mtp008.c	2006-11-17 02:12:31.000000000 -0800
@@ -0,0 +1,972 @@
+/*
+   mtp008.c - Part of lm_sensors, Linux kernel modules for hardware
+   monitoring
+   Copyright (C) 2001, 2004  Kris Van Hees <aedil at alchar.org>
+   Port to Linux 2.6 Copyright (C) 2005  Andrew Pam <andrew at sericyb.com.au>
+   Port to Linux 2.6.18 Copyright (C) 2006  dean gaudet <dean at arctic.org>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>     /* for hardware monitoring drivers */
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h> /* if you need VRM support */
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = {0x2c, 0x2d, 0x2e, I2C_CLIENT_END};
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(mtp008);
+
+/* The MTP008 registers */
+/*      in0 .. in6 */
+#define MTP008_REG_IN(nr)		(0x20 + (nr))
+#define MTP008_REG_IN_MAX(nr)		(0x2b + (nr) * 2)
+#define MTP008_REG_IN_MIN(nr)		(0x2c + (nr) * 2)
+
+/*      temp1 */
+#define MTP008_REG_TEMP			0x27
+#define MTP008_REG_TEMP_MAX		0x39
+#define MTP008_REG_TEMP_MIN		0x3a
+
+/*      fan1 .. fan3 (nr is 0..2) */
+#define MTP008_REG_FAN(nr)		(0x28 + (nr))
+#define MTP008_REG_FAN_MIN(nr)		(0x3b + (nr))
+
+#define MTP008_REG_CONFIG		0x40
+#define MTP008_REG_INT_STAT1		0x41
+#define MTP008_REG_INT_STAT2		0x42
+
+#define MTP008_REG_VID_FANDIV		0x47
+
+#define MTP008_REG_I2C_ADDR		0x48
+
+#define MTP008_REG_RESET_VID4		0x49
+
+#define MTP008_REG_OVT_PROP		0x50
+
+#define MTP008_REG_BEEP_CTRL1		0x51
+#define MTP008_REG_BEEP_CTRL2		0x52
+
+/*      pwm1 .. pwm3 (nr is 0..2) */
+#define MTP008_REG_PWM_CTRL(nr)		(0x53 + (nr))
+
+#define MTP008_REG_PIN_CTRL1		0x56
+#define MTP008_REG_PIN_CTRL2		0x57
+
+#define MTP008_REG_CHIPID		0x58
+
+/*
+ * Pin control register configuration constants.
+ */
+#define MTP008_CFG_VT1_MASK		0x08
+#define MTP008_CFG_VT2_MASK		0x06
+#define MTP008_CFG_VT3_MASK		0x01
+
+/*
+ * Conversion routines and macros.  Limit checking is only done on
+ * the TO_REG variants.
+ */
+
+/* IN: mV, (0V to 4.08V)
+   REG: 16mV/bit */
+#define IN_TO_REG(val)		(SENSORS_LIMIT((((val) + 8) / 16), 0, 255))
+#define IN_FROM_REG(val)	((val) * 16)
+
+/*
+ * The fan rotation count (as stored in the register) is calculated using the
+ * following formula:
+ *      count = (22.5K * 60) / (rpm * div) = 1350000 / (rpm * div)
+ * and the rpm is therefore:
+ *      rpm = 1350000 / (count * div)
+ */
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm <= 0)
+		return 255;
+
+	return SENSORS_LIMIT( (1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+#define FAN_FROM_REG(val, div)	( (val) == 0 ? -1		\
+				: (val) == 255 ? 0		\
+			        : 1350000 / ((val) * (div))	\
+				)
+
+/* TEMP: mC (-128C to +127C)
+   REG: 1C/bit, two's complement */
+#define TEMP_TO_REG(val)	(					\
+				 ( (val) < 0 ? ((val) - 500)		\
+				 	     : ((val) + 500)		\
+			         ) / 1000				\
+				)
+#define TEMP_FROM_REG(val)	( (val) * 1000 )
+
+/* VID: mV
+ * REG: 0x00 to 0x0f    = 2.05 to 1.30 (0.05 per unit)
+ *      0x10 to 0x1e    = 3.50 to 2.10 (0.10 per unit)
+ *      0x1f            = No CPU
+ */
+#define VID_FROM_REG(val)	((val) == 0x1f				      \
+					 ? 0				      \
+					 : (val) < 0x10 ? 2050 - (val) * 50   \
+							: 5100 - (val) * 100)
+
+/*
+ * Fan divider.
+ */
+#define DIV_FROM_REG(val)	(1 << (val))
+
+/*
+ * PWM control.  (nr is 0..2)
+ */
+#define PWM_FROM_REG(val)	(val)
+#define PWM_TO_REG(val)		(SENSORS_LIMIT((val), 0, 255))
+#define PWMENABLE_FROM_REG(nr, val)	(((val) >> ((nr) + 4)) & 1)
+
+/* sysfs temperature sensor types	mtp008 sensor types
+ * 0: Not defined			0: Analog input (voltage)
+ * 1: PII/Celeron Diode			2: PII Diode
+ * 2: 3904 transistor
+ * 3: thermal diode			1: Thermistor
+ */
+#define SENS_FROM_REG(val)	((val) == 0 ? 0	: (val) == 1 ? 3 : 1)
+#define SENS_TO_REG(val)	((val) == 0 ? 0 : (val) == 1 ? 2 : 1)
+
+/*
+ * For each registered MTP008, we need to keep some data in memory.  The
+ * structure itself is dynamically allocated, at the same time when a new
+ * mtp008 client is allocated.
+ */
+struct mtp008_data {
+	struct i2c_client client;
+	struct class_device *class_dev;
+	struct semaphore update_lock;
+	char valid;				/* !=0 if fields are valid */
+	unsigned long last_updated;		/* In jiffies */
+
+	u8 in[7];				/* Register value */
+	u8 in_max[7];				/* Register value */
+	u8 in_min[7];				/* Register value */
+	s8 temp[3];				/* Register value */
+	s8 temp_max[3];				/* Register value */
+	s8 temp_min[3];				/* Register value */
+	u8 fan[3];				/* Register value */
+	u8 fan_min[3];				/* Register value */
+	u8 vid;					/* Register encoding */
+	u8 fan_div[3];				/* Register encoding */
+	u16 alarms;				/* Register encoding */
+	u16 beeps;				/* Register encoding */
+	u8 pwm[3];				/* Register value */
+	u8 sens[3];				/* 0 = Analog input,
+						   1 = Thermistor,
+						   2 = PII/Celeron diode */
+	u8 pwmenable;				/* Register 0x57 value */
+};
+
+static int mtp008_attach_adapter(struct i2c_adapter *adapter);
+static int mtp008_detect(struct i2c_adapter *adapter, int address, int kind);
+static int mtp008_detach_client(struct i2c_client *client);
+
+static struct mtp008_data *mtp008_update_device(struct device *dev);
+static void mtp008_init_client(struct i2c_client *client, struct mtp008_data *data);
+
+static struct i2c_driver mtp008_driver =
+{
+	.driver = {
+		.name	= "mtp008",
+	},
+	.id		= I2C_DRIVERID_MTP008,
+	.attach_adapter	= mtp008_attach_adapter,
+	.detach_client	= mtp008_detach_client,
+};
+
+/* 7 Voltages */
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	if ((nr != 4 && nr != 5) || data->sens[nr - 3] == 0) {
+		down(&data->update_lock);
+		data->in_min[nr] = IN_TO_REG(val);
+		i2c_smbus_write_byte_data(client, MTP008_REG_IN_MIN(nr),
+				data->in_min[nr]);
+		up(&data->update_lock);
+	}
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	if ((nr != 4 && nr != 5) || data->sens[nr - 3] == 0) {
+		down(&data->update_lock);
+		data->in_max[nr] = IN_TO_REG(val);
+		i2c_smbus_write_byte_data(client, MTP008_REG_IN_MAX(nr),
+				data->in_max[nr]);
+		up(&data->update_lock);
+	}
+	return count;
+}
+
+#define GENERATE_IN_FUNCTIONS(offset)				\
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, 		\
+		show_in, NULL, offset);				\
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_in_min, set_in_min, offset);		\
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_in_max, set_in_max, offset);
+
+GENERATE_IN_FUNCTIONS(0);
+GENERATE_IN_FUNCTIONS(1);
+GENERATE_IN_FUNCTIONS(2);
+GENERATE_IN_FUNCTIONS(3);
+GENERATE_IN_FUNCTIONS(4);
+GENERATE_IN_FUNCTIONS(5);
+GENERATE_IN_FUNCTIONS(6);
+
+/* 3 Temperatures */
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
+}
+
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
+}
+
+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
+}
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[nr] = TEMP_TO_REG(val);
+	if (nr == 0) {
+		i2c_smbus_write_byte_data(client, MTP008_REG_TEMP_MAX,
+				data->temp_max[nr]);
+	}
+	else if (data->sens[nr] != 0) {
+		i2c_smbus_write_byte_data(client, MTP008_REG_IN_MAX(nr + 3),
+				data->temp_max[nr]);
+	}
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_min[nr] = TEMP_TO_REG(val);
+	if (nr == 0) {
+		i2c_smbus_write_byte_data(client, MTP008_REG_TEMP_MIN,
+				data->temp_min[nr]);
+	}
+	else if (data->sens[nr] != 0) {
+		i2c_smbus_write_byte_data(client, MTP008_REG_IN_MIN(nr + 3),
+				data->temp_min[nr]);
+	}
+	up(&data->update_lock);
+	return count;
+}
+
+#define GENERATE_TEMP_FUNCTIONS(offset)					\
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, 		\
+		show_temp, NULL, offset - 1);				\
+static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_temp_min, set_temp_min, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_temp_max, set_temp_max, offset - 1);
+
+GENERATE_TEMP_FUNCTIONS(1);
+GENERATE_TEMP_FUNCTIONS(2);
+GENERATE_TEMP_FUNCTIONS(3);
+
+/* 3 Fans */
+static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+}
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	i2c_smbus_write_byte_data(client, MTP008_REG_FAN_MIN(nr),
+			data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long min;
+	u8 reg;
+
+	down(&data->update_lock);
+	min = FAN_FROM_REG(data->fan_min[nr],
+			   DIV_FROM_REG(data->fan_div[nr]));
+
+	switch (val) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not "
+			"supported. Choose one of 1, 2, 4 or 8!\n", val);
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	switch (nr) {
+	case 0:
+		reg = i2c_smbus_read_byte_data(client, MTP008_REG_VID_FANDIV);
+		reg = (reg & 0xcf) | ((data->fan_div[nr] & 0x03) << 4);
+		i2c_smbus_write_byte_data(client, MTP008_REG_VID_FANDIV, reg);
+		break;
+	case 1:
+		reg = i2c_smbus_read_byte_data(client, MTP008_REG_VID_FANDIV);
+		reg = (reg & 0x3f) | ((data->fan_div[nr] & 0x03) << 6);
+		i2c_smbus_write_byte_data(client, MTP008_REG_VID_FANDIV, reg);
+		break;
+	case 2:
+		reg = i2c_smbus_read_byte_data(client, MTP008_REG_PIN_CTRL1);
+		reg = (reg & 0x3f) | ((data->fan_div[nr] & 0x03) << 6);
+		i2c_smbus_write_byte_data(client, MTP008_REG_PIN_CTRL1, reg);
+		break;
+	}
+
+	data->fan_min[nr] =
+		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	i2c_smbus_write_byte_data(client, MTP008_REG_FAN_MIN(nr),
+			data->fan_min[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define GENERATE_FAN_FUNCTIONS(offset)					\
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,			\
+		show_fan, NULL, offset - 1); 				\
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
+		show_fan_min, set_fan_min, offset - 1);			\
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
+		show_fan_div, set_fan_div, offset - 1);
+
+GENERATE_FAN_FUNCTIONS(1);
+GENERATE_FAN_FUNCTIONS(2);
+GENERATE_FAN_FUNCTIONS(3);
+
+/* VID */
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", VID_FROM_REG(data->vid));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/* Beeps */
+static ssize_t show_beeps(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%u\n", data->beeps);
+}
+
+static ssize_t set_beeps(struct device *dev, struct device_attribute *attr, const char *buf,
+			size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->beeps = val & 0xdf8f;
+	i2c_smbus_write_byte_data(client, MTP008_REG_BEEP_CTRL1,
+			data->beeps & 0xff);
+	i2c_smbus_write_byte_data(client, MTP008_REG_BEEP_CTRL2,
+			data->beeps >> 8);
+	up(&data->update_lock);
+	return count;
+}
+static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, show_beeps, set_beeps);
+
+/* 3 PWM fan speed controls */
+static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
+}
+static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->pwm[nr] = PWM_TO_REG(val);
+	i2c_smbus_write_byte_data(client, MTP008_REG_PWM_CTRL(nr),
+			data->pwm[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", PWMENABLE_FROM_REG(nr, data->pwmenable));
+}
+static ssize_t set_pwm_enable(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	if (val)
+		data->pwmenable |= (0x10 << nr);
+	else
+		data->pwmenable &= ~(0x10 << nr);
+	i2c_smbus_write_byte_data(client, MTP008_REG_PIN_CTRL2,
+			data->pwmenable);
+	up(&data->update_lock);
+	return count;
+}
+
+#define GENERATE_PWM_FUNCTIONS(offset)					\
+static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,		\
+		show_pwm, set_pwm, offset - 1);				\
+static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,	\
+		show_pwm_enable, set_pwm_enable, offset - 1);
+
+GENERATE_PWM_FUNCTIONS(1);
+GENERATE_PWM_FUNCTIONS(2);
+GENERATE_PWM_FUNCTIONS(3);
+
+/* 3 Sensor type selections */
+static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct mtp008_data *data = mtp008_update_device(dev);
+	return sprintf(buf, "%d\n", SENS_FROM_REG(data->sens[nr]));
+}
+static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	u8 reg, mask, bits;
+
+	mask = (nr == 0) ? MTP008_CFG_VT1_MASK
+			 : (nr == 1) ? MTP008_CFG_VT2_MASK
+			 	     : MTP008_CFG_VT3_MASK;
+	bits = SENS_TO_REG(val) << ((2 - nr) + 1);
+
+	if ( (val == 0)				/* Undefined */
+	     || (data->sens[nr] == 0)		/* Voltage sensor */
+	     || ((bits & ~mask) != 0)		/* Invalid setting */
+	   )
+		dev_err(&client->dev,
+			"Invalid sensor type %ld for sensor %d.\n",
+			val, nr + 1);
+	else {
+		down(&data->update_lock);
+		data->sens[nr] = SENS_TO_REG(val);
+		reg = (i2c_smbus_read_byte_data(client, MTP008_REG_PIN_CTRL2)
+			& ~mask) | bits;
+		i2c_smbus_write_byte_data(client, MTP008_REG_PIN_CTRL2, reg);
+		up(&data->update_lock);
+	}
+	return count;
+}
+
+#define GENERATE_SENS_FUNCTIONS(offset)					\
+static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR,	\
+		show_sensor, set_sensor, offset - 1);
+
+GENERATE_SENS_FUNCTIONS(1);
+GENERATE_SENS_FUNCTIONS(2);
+GENERATE_SENS_FUNCTIONS(3);
+
+
+/* This function is called when:
+ * mtp008_driver is inserted (when this module is loaded), for each available
+ * adapter when a new adapter is inserted (and mtp008_driver is still present)
+ */
+static int mtp008_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_probe(adapter, &addr_data, mtp008_detect);
+}
+
+static int mtp008_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int err, i;
+	struct i2c_client *new_client;
+	struct mtp008_data *data;
+
+	err = 0;
+
+	/*
+	 * We presume we have a valid client.  We now create the client
+	 * structure, even though we cannot fill it completely yet.  But it
+	 * allows us to use mtp008_(read|write)_value().
+	 */
+	if (!(data = kzalloc(sizeof(struct mtp008_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &mtp008_driver;
+	new_client->flags = 0;
+
+	/* Remaining detection. */
+	if ((kind < 0)
+	    && (i2c_smbus_read_byte_data(new_client, MTP008_REG_CHIPID) != 0xac
+		|| i2c_smbus_read_byte_data(new_client, MTP008_REG_I2C_ADDR)
+			!= address)
+	   ) {
+		err = -ENODEV;
+		goto exit_free;
+	}
+
+	/*
+	 * Fill in the remaining client fields and put it into the global list.
+	 */
+	strlcpy(new_client->name, "mtp008", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer that a new client has arrived. */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the MTP008 chip. */
+	mtp008_init_client(new_client, data);
+
+	/* A few vars need to be filled upon startup */
+	for (i = 0; i < 3; i++) {
+		data->fan_min[i] = i2c_smbus_read_byte_data(new_client,
+					MTP008_REG_FAN_MIN(i));
+	}
+
+	/* Register sysfs hooks */
+        data->class_dev = hwmon_device_register(&new_client->dev);
+        if (IS_ERR(data->class_dev)) {
+                err = PTR_ERR(data->class_dev);
+                goto exit_detach;
+        }
+
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_pwm2_enable.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_pwm3_enable.dev_attr);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_beep_mask);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+
+	return 0;
+
+exit_detach:
+	i2c_detach_client(new_client);
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int mtp008_detach_client(struct i2c_client *client)
+{
+	struct mtp008_data *data = i2c_get_clientdata(client);
+	int err;
+
+        hwmon_device_unregister(data->class_dev);
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		    "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static void mtp008_getsensortype(struct mtp008_data *data, u8 inp)
+{
+	inp &= 0x0f;
+	data->sens[0] = (inp >> 3) + 1;		/* 1 or 2 */
+	data->sens[1] = (inp >> 1) & 0x03;	/* 0, 1 or 2 */
+	data->sens[2] = inp & 0x01;		/* 0 or 1 */
+}
+
+/* Called when we have found a new MTP008. */
+static void mtp008_init_client(struct i2c_client *client, struct mtp008_data *data)
+{
+	mtp008_getsensortype(data, i2c_smbus_read_byte_data(client,
+				MTP008_REG_PIN_CTRL2) );
+
+	/* Start monitoring. */
+	i2c_smbus_write_byte_data(
+		client, MTP008_REG_CONFIG,
+		(i2c_smbus_read_byte_data(client, MTP008_REG_CONFIG) & 0xf7)
+		| 0x01
+	);
+}
+
+static struct mtp008_data *mtp008_update_device(struct device *dev)
+{
+	int i;
+	u8 inp;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mtp008_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting mtp008 update\n");
+
+		/*
+		 * Read in the analog inputs.  We're reading AIN4 and AIN5 as
+		 * regular analog inputs, even though they may have been
+		 * configured as temperature readings instead.  Interpretation
+		 * of these values is done below.
+		 */
+		for (i = 0; i < 7; i++) {
+			data->in[i] =
+				i2c_smbus_read_byte_data(client,
+						MTP008_REG_IN(i));
+			data->in_max[i] =
+				i2c_smbus_read_byte_data(client,
+						MTP008_REG_IN_MAX(i));
+			data->in_min[i] =
+				i2c_smbus_read_byte_data(client,
+						MTP008_REG_IN_MIN(i));
+		}
+
+		/* Read the temperature sensor. */
+		data->temp[0] = i2c_smbus_read_byte_data(client,
+				MTP008_REG_TEMP);
+		data->temp_max[0] = i2c_smbus_read_byte_data(client,
+				MTP008_REG_TEMP_MAX);
+		data->temp_min[0] = i2c_smbus_read_byte_data(client,
+				MTP008_REG_TEMP_MIN);
+
+		/*
+		 * Read the first 2 fan dividers and the VID setting.  Read the
+		 * third fan divider from a different register.
+		 */
+		inp = i2c_smbus_read_byte_data(client, MTP008_REG_VID_FANDIV);
+		data->vid = inp & 0x0f;
+		data->vid |= (i2c_smbus_read_byte_data(client,
+				MTP008_REG_RESET_VID4) & 0x01) << 4;
+
+		data->fan_div[0] = (inp >> 4) & 0x03;
+		data->fan_div[1] = inp >> 6;
+		data->fan_div[2] = i2c_smbus_read_byte_data(client,
+				MTP008_REG_PIN_CTRL1) >> 6;
+
+		/* Read the interrupt status registers. */
+		data->alarms =
+			(i2c_smbus_read_byte_data(client,
+					   MTP008_REG_INT_STAT1) & 0xdf) |
+			(i2c_smbus_read_byte_data(client,
+					   MTP008_REG_INT_STAT2) & 0x0f) << 8;
+
+		/* Read the beep control registers. */
+		data->beeps =
+			(i2c_smbus_read_byte_data(client,
+					   MTP008_REG_BEEP_CTRL1) & 0xdf) |
+			(i2c_smbus_read_byte_data(client,
+					   MTP008_REG_BEEP_CTRL2) & 0x8f) << 8;
+
+		/* Read the sensor configuration. */
+		inp = i2c_smbus_read_byte_data(client, MTP008_REG_PIN_CTRL2);
+		mtp008_getsensortype(data, inp);
+		data->pwmenable = inp;
+
+		/* Deal with the configuration of sensors 2 and 3. */
+		for (i = 1; i < 3; i++)
+			if (data->sens[i] == 0) {	/* Voltage */
+				data->temp[i] = 0;
+				data->temp_max[i] = 0;
+				data->temp_min[i] = 0;
+			}
+			else {
+				data->temp[i] = data->in[i + 3];
+				data->in[i + 3] = 0;
+				data->temp_max[i] = data->in_max[i + 3];
+				data->in_max[i + 3] = 0;
+				data->temp_min[i] = data->in_min[i + 3];
+				data->in_min[i + 3] = 0;
+			}
+
+		/* Read the PWM registers if enabled. */
+		for (i = 0; i < 3; i++) {
+			if(PWMENABLE_FROM_REG(i, inp))
+				data->pwm[i] = i2c_smbus_read_byte_data(client,
+						  MTP008_REG_PWM_CTRL(i));
+			else
+				data->pwm[i] = 255;
+		}
+
+		/* Read the fan sensors. Skip 3 if PWM1 enabled. */
+		for (i = 0; i < 3; i++) {
+			if (i == 2 && PWMENABLE_FROM_REG(0, inp)) {
+				data->fan[2] = 0;
+				data->fan_min[2] = 0;
+			} else {
+				data->fan[i] = i2c_smbus_read_byte_data(client,
+					  MTP008_REG_FAN(i));
+				data->fan_min[i] =
+					i2c_smbus_read_byte_data(client,
+					  MTP008_REG_FAN_MIN(i));
+			}
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sm_mtp008_init(void)
+{
+	return i2c_add_driver(&mtp008_driver);
+}
+
+static void __exit sm_mtp008_exit(void)
+{
+	i2c_del_driver(&mtp008_driver);
+}
+
+
+
+MODULE_AUTHOR("Kris Van Hees <aedil at alchar.org> "
+	      "and Andrew Pam <andrew at sericyb.com.au>");
+MODULE_DESCRIPTION("MTP008 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sm_mtp008_init);
+module_exit(sm_mtp008_exit);
-------------- next part --------------
Index: lm-sensors-2.10.1/lib/chips.c
===================================================================
--- lm-sensors-2.10.1.orig/lib/chips.c	2006-11-17 01:52:27.000000000 -0800
+++ lm-sensors-2.10.1/lib/chips.c	2006-11-17 01:53:44.000000000 -0800
@@ -4197,22 +4197,22 @@
                         R, MTP008_SYSCTL_TEMP2, VALUE(3), 1 },
     { SENSORS_MTP008_TEMP3, "temp3", NOMAP, NOMAP,
                         R, MTP008_SYSCTL_TEMP3, VALUE(3), 1 },
-    { SENSORS_MTP008_TEMP1_OVER, "temp1_over", SENSORS_MTP008_TEMP1,
+    { SENSORS_MTP008_TEMP1_MAX, "temp1_max", SENSORS_MTP008_TEMP1,
 			SENSORS_MTP008_TEMP1, RW,
 			MTP008_SYSCTL_TEMP1, VALUE(1), 1 },
-    { SENSORS_MTP008_TEMP2_OVER, "temp2_over", SENSORS_MTP008_TEMP2,
+    { SENSORS_MTP008_TEMP2_MAX, "temp2_max", SENSORS_MTP008_TEMP2,
 			SENSORS_MTP008_TEMP2, RW,
 			MTP008_SYSCTL_TEMP2, VALUE(1), 1 },
-    { SENSORS_MTP008_TEMP3_OVER, "temp3_over", SENSORS_MTP008_TEMP3,
+    { SENSORS_MTP008_TEMP3_MAX, "temp3_max", SENSORS_MTP008_TEMP3,
 			SENSORS_MTP008_TEMP3, RW,
 			MTP008_SYSCTL_TEMP3, VALUE(1), 1 },
-    { SENSORS_MTP008_TEMP1_HYST, "temp1_hyst", SENSORS_MTP008_TEMP1,
+    { SENSORS_MTP008_TEMP1_MIN, "temp1_min", SENSORS_MTP008_TEMP1,
 			SENSORS_MTP008_TEMP1, RW,
 			MTP008_SYSCTL_TEMP1, VALUE(2), 1 },
-    { SENSORS_MTP008_TEMP2_HYST, "temp2_hyst", SENSORS_MTP008_TEMP2,
+    { SENSORS_MTP008_TEMP2_MIN, "temp2_min", SENSORS_MTP008_TEMP2,
 			SENSORS_MTP008_TEMP2, RW,
 			MTP008_SYSCTL_TEMP2, VALUE(2), 1 },
-    { SENSORS_MTP008_TEMP3_HYST, "temp3_hyst", SENSORS_MTP008_TEMP3,
+    { SENSORS_MTP008_TEMP3_MIN, "temp3_min", SENSORS_MTP008_TEMP3,
 			SENSORS_MTP008_TEMP3, RW,
 			MTP008_SYSCTL_TEMP3, VALUE(2), 1 },
     { SENSORS_MTP008_VID, "vid", NOMAP, NOMAP,
Index: lm-sensors-2.10.1/lib/chips.h
===================================================================
--- lm-sensors-2.10.1.orig/lib/chips.h	2006-11-17 01:52:28.000000000 -0800
+++ lm-sensors-2.10.1/lib/chips.h	2006-11-17 01:54:04.000000000 -0800
@@ -1494,12 +1494,12 @@
 #define SENSORS_MTP008_TEMP1           51 /* R */
 #define SENSORS_MTP008_TEMP2           52 /* R */
 #define SENSORS_MTP008_TEMP3           53 /* R */
-#define SENSORS_MTP008_TEMP1_OVER      54 /* RW */
-#define SENSORS_MTP008_TEMP1_HYST      55 /* RW */
-#define SENSORS_MTP008_TEMP2_OVER      56 /* RW */
-#define SENSORS_MTP008_TEMP2_HYST      57 /* RW */
-#define SENSORS_MTP008_TEMP3_OVER      58 /* RW */
-#define SENSORS_MTP008_TEMP3_HYST      59 /* RW */
+#define SENSORS_MTP008_TEMP1_MAX       54 /* RW */
+#define SENSORS_MTP008_TEMP1_MIN       55 /* RW */
+#define SENSORS_MTP008_TEMP2_MAX       56 /* RW */
+#define SENSORS_MTP008_TEMP2_MIN       57 /* RW */
+#define SENSORS_MTP008_TEMP3_MAX       58 /* RW */
+#define SENSORS_MTP008_TEMP3_MIN       59 /* RW */
 #define SENSORS_MTP008_VID             61 /* R */
 #define SENSORS_MTP008_FAN1_DIV        71 /* RW */
 #define SENSORS_MTP008_FAN2_DIV        72 /* RW */
Index: lm-sensors-2.10.1/prog/sensors/chips.c
===================================================================
--- lm-sensors-2.10.1.orig/prog/sensors/chips.c	2006-11-17 01:52:27.000000000 -0800
+++ lm-sensors-2.10.1/prog/sensors/chips.c	2006-11-17 02:03:29.000000000 -0800
@@ -2136,11 +2136,11 @@
 
   if (!sensors_get_label_and_valid(*name,SENSORS_MTP008_TEMP1,&label,&valid) &&
       !sensors_get_feature(*name,SENSORS_MTP008_TEMP1,&cur) &&
-      !sensors_get_feature(*name,SENSORS_MTP008_TEMP1_HYST,&min) &&
-      !sensors_get_feature(*name,SENSORS_MTP008_TEMP1_OVER,&max)) {
+      !sensors_get_feature(*name,SENSORS_MTP008_TEMP1_MIN,&min) &&
+      !sensors_get_feature(*name,SENSORS_MTP008_TEMP1_MAX,&max)) {
     if (valid) {
       print_label(label,10);
-      print_temp_info( cur, max, min, HYST, 0, 0);
+      print_temp_info( cur, max, min, MINMAX, 0, 0);
       printf(" %s\n", alarms&MTP008_ALARM_TEMP1?"ALARM":"");
     }
   } else
@@ -2149,11 +2149,11 @@
 
   if (!sensors_get_label_and_valid(*name,SENSORS_MTP008_TEMP2,&label,&valid) &&
       !sensors_get_feature(*name,SENSORS_MTP008_TEMP2,&cur) &&
-      !sensors_get_feature(*name,SENSORS_MTP008_TEMP2_HYST,&min) &&
-      !sensors_get_feature(*name,SENSORS_MTP008_TEMP2_OVER,&max)) {
+      !sensors_get_feature(*name,SENSORS_MTP008_TEMP2_MIN,&min) &&
+      !sensors_get_feature(*name,SENSORS_MTP008_TEMP2_MAX,&max)) {
     if (valid) {
       print_label(label,10);
-      print_temp_info( cur, max, min, HYST, 0, 0);
+      print_temp_info( cur, max, min, MINMAX, 0, 0);
       printf(" %s\n", alarms&MTP008_ALARM_TEMP2?"ALARM":"");
     }
   } else
@@ -2162,11 +2162,11 @@
 
   if (!sensors_get_label_and_valid(*name,SENSORS_MTP008_TEMP3,&label,&valid) &&
       !sensors_get_feature(*name,SENSORS_MTP008_TEMP3,&cur) &&
-      !sensors_get_feature(*name,SENSORS_MTP008_TEMP3_HYST,&min) &&
-      !sensors_get_feature(*name,SENSORS_MTP008_TEMP3_OVER,&max)) {
+      !sensors_get_feature(*name,SENSORS_MTP008_TEMP3_MIN,&min) &&
+      !sensors_get_feature(*name,SENSORS_MTP008_TEMP3_MAX,&max)) {
     if (valid) {
       print_label(label,10);
-      print_temp_info( cur, max, min, HYST, 0, 0);
+      print_temp_info( cur, max, min, MINMAX, 0, 0);
       printf(" %s\n", alarms&MTP008_ALARM_TEMP3?"ALARM":"");
     }
   } else


[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux