drivers/hwmon : move hardware monitor drviers to drivers/hwmon

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
diff --git a/drivers/Makefile b/drivers/Makefile
index 745a5cc..d4882f5 100755
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -28,7 +28,6 @@
 LIB	= $(obj)libdrivers.a
 
 COBJS-y += ali512x.o
-COBJS-y += ds1722.o
 COBJS-y += ns87308.o
 COBJS-y += status_led.o
 
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
new file mode 100644
index 0000000..cebb2ba
--- /dev/null
+++ b/drivers/hwmon/Makefile
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2001
+# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+#CFLAGS += -DDEBUG
+
+LIB	= $(obj)libhwmon.a
+
+COBJS-y += adm1021.o
+COBJS-y += ds1621.o
+COBJS-y += ds1722.o
+COBJS-y += ds1775.o
+COBJS-y += lm75.o
+COBJS-y += lm81.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
new file mode 100644
index 0000000..9f65cfb27
--- /dev/null
+++ b/drivers/hwmon/adm1021.c
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2003
+ * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Analog Devices's ADM1021
+ * "Low Cost Microprocessor System Temperature Monitor"
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_ADM1021
+
+#include <i2c.h>
+#include <dtt.h>
+
+typedef
+	struct {
+		uint i2c_addr:7;	/* 7bit i2c chip address */
+		uint conv_rate:3;	/* conversion rate */
+		uint enable_alert:1;	/* enable alert output pin */
+		uint enable_local:1;	/* enable internal temp sensor */
+		uint max_local:8;	/* internal temp maximum */
+		uint min_local:8;	/* internal temp minimum */
+		uint enable_remote:1;	/* enable remote temp sensor */
+		uint max_remote:8;	/* remote temp maximum */
+		uint min_remote:8;	/* remote temp minimum */
+	}
+dtt_cfg_t;
+
+dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021;
+
+int
+dtt_read (int sensor, int reg)
+{
+	dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+	uchar data;
+
+	if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
+		return -1;
+
+	return (int)data;
+} /* dtt_read() */
+
+int
+dtt_write (int sensor, int reg, int val)
+{
+	dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+	uchar data;
+
+	data = (uchar)(val & 0xff);
+
+	if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
+		return 1;
+
+	return 0;
+} /* dtt_write() */
+
+static int
+_dtt_init (int sensor)
+{
+	dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+	int reg, val;
+
+	if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
+		return 1;	/* sensor is disabled (or rather ignored) */
+
+	/*
+	 * Setup High Limit register
+	 */
+	if ((sensor & 1) == 0) {
+		reg = DTT_WRITE_LOC_HIGHLIM;
+		val = dcp->max_local;
+	}
+	else {
+		reg = DTT_WRITE_REM_HIGHLIM;
+		val = dcp->max_remote;
+	}
+	if (dtt_write (sensor, reg, val) != 0)
+		return 1;
+
+	/*
+	 * Setup Low Limit register
+	 */
+	if ((sensor & 1) == 0) {
+		reg = DTT_WRITE_LOC_LOWLIM;
+		val = dcp->min_local;
+	}
+	else {
+		reg = DTT_WRITE_REM_LOWLIM;
+		val = dcp->min_remote;
+	}
+	if (dtt_write (sensor, reg, val) != 0)
+		return 1;
+
+	/* shouldn't hurt if the rest gets done twice */
+
+	/*
+	 * Setup Conversion Rate register
+	 */
+	if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
+		return 1;
+
+	/*
+	 * Setup configuraton register
+	 */
+	val = 0;				/* running */
+	if (dcp->enable_alert == 0)
+		val |= DTT_CONFIG_ALERT_MASKED;	/* mask ALERT pin */
+	if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
+		return 1;
+
+	return 0;
+} /* _dtt_init() */
+
+int
+dtt_init (void)
+{
+	int i;
+	unsigned char sensors[] = CONFIG_DTT_SENSORS;
+	const char *const header = "DTT:   ";
+
+	/* switch to correct I2C bus */
+	I2C_SET_BUS(CFG_DTT_BUS_NUM);
+
+	for (i = 0; i < sizeof(sensors); i++) {
+		if (_dtt_init(sensors[i]) != 0)
+			printf ("%s%d FAILED INIT\n", header, i+1);
+		else
+			printf ("%s%d is %i C\n", header, i+1,
+				dtt_get_temp(sensors[i]));
+	}
+
+	return (0);
+} /* dtt_init() */
+
+int
+dtt_get_temp (int sensor)
+{
+	signed char val;
+
+	if ((sensor & 1) == 0)
+		val = dtt_read(sensor, DTT_READ_LOC_VALUE);
+	else
+		val = dtt_read(sensor, DTT_READ_REM_VALUE);
+
+	return (int) val;
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_ADM1021 */
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
new file mode 100644
index 0000000..4948181
--- /dev/null
+++ b/drivers/hwmon/ds1621.c
@@ -0,0 +1,190 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Dallas Semiconductor's DS1621 Digital Thermometer and Thermostat.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1621
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_DS1621"
+#endif
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48			/* Dallas Semi's DS1621 */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and command.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW))
+	dlen = 2;
+    else
+	dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+	return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+    /*
+     * Handle various data sizes.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW)) {
+	dlen = 2;
+	data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+	data[1] = (char)(val & 0xff);
+    }
+    else if ((reg == DTT_WRITE_START_CONV) || (reg == DTT_WRITE_STOP_CONV)) {
+	dlen = 0;
+	data[0] = (char)0;
+	data[1] = (char)0;
+    }
+    else {
+	dlen = 1;
+	data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to device.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup High Temp.
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    /*
+     * Setup Low Temp - hysteresis.
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    /*
+     * Setup configuraton register
+     *
+     * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
+     *
+     * We run in polled mode, since there isn't any way to know if this
+     * lousy device is ready to provide temperature readings on power up.
+     */
+    val = 0x9;
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("DTT%d:  FAILED\n", i+1);
+	else
+	    printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+
+int dtt_get_temp(int sensor)
+{
+    int i;
+
+    /*
+     * Start a conversion, may take up to 1 second.
+     */
+    dtt_write(sensor, DTT_WRITE_START_CONV, 0);
+    for (i = 0; i <= 10; i++) {
+	udelay(100000);
+	if (dtt_read(sensor, DTT_CONFIG) & 0x80)
+	    break;
+    }
+
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+
+#endif /* CONFIG_DTT_DS1621 */
diff --git a/drivers/ds1722.c b/drivers/hwmon/ds1722.c
similarity index 100%
rename from drivers/ds1722.c
rename to drivers/hwmon/ds1722.c
diff --git a/drivers/hwmon/ds1775.c b/drivers/hwmon/ds1775.c
new file mode 100644
index 0000000..e44cee3
--- /dev/null
+++ b/drivers/hwmon/ds1775.c
@@ -0,0 +1,156 @@
+/*
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1775
+#include <i2c.h>
+#include <dtt.h>
+
+#define DTT_I2C_DEV_CODE 0x49		/* Dallas Semi's DS1775 device code */
+
+int dtt_read(int sensor, int reg)
+{
+	int dlen;
+	uchar data[2];
+
+	/*
+	 * Calculate sensor address and command
+	 */
+	sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1775 */
+
+	/*
+	 * Prepare to handle 2 byte result
+	 */
+	if ((reg == DTT_READ_TEMP) ||
+	    (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST))
+		dlen = 2;
+	else
+		dlen = 1;
+
+	/*
+	 * Now try to read the register
+	 */
+	if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+		return 1;
+
+	/*
+	 * Handle 2 byte result
+	 */
+	if (dlen == 2)
+		return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+	return (int) data[0];
+}
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+	int dlen;
+	uchar data[2];
+
+	/*
+	 * Calculate sensor address and register
+	 */
+	sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+	/*
+	 * Handle various data sizes
+	 */
+	if ((reg == DTT_READ_TEMP) ||
+	    (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) {
+		dlen = 2;
+		data[0] = (char)((val >> 8) & 0xff); /* MSB first */
+		data[1] = (char)(val & 0xff);
+	} else {
+		dlen = 1;
+		data[0] = (char)(val & 0xff);
+	}
+
+	/*
+	 * Write value to device
+	 */
+	if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+		return 1;
+
+	return 0;
+}
+
+
+static int _dtt_init(int sensor)
+{
+	int val;
+
+	/*
+	 * Setup High Temp
+	 */
+	val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+	if (dtt_write(sensor, DTT_TEMP_OS, val) != 0)
+		return 1;
+	udelay(50000);			/* Max 50ms */
+
+	/*
+	 * Setup Low Temp - hysteresis
+	 */
+	val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+	if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+		return 1;
+	udelay(50000);			/* Max 50ms */
+
+	/*
+	 * Setup configuraton register
+	 *
+	 * Fault Tolerance limits 4, Thermometer resolution bits is 9,
+	 * Polarity = Active Low,continuous conversion mode, Thermostat
+	 * mode is interrupt mode
+	 */
+	val = 0xa;
+	if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+		return 1;
+	udelay(50000);			/* Max 50ms */
+
+	return 0;
+}
+
+
+int dtt_init (void)
+{
+	int i;
+	unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+	for (i = 0; i < sizeof(sensors); i++) {
+		if (_dtt_init(sensors[i]) != 0)
+			printf("DTT%d:  FAILED\n", i+1);
+		else
+			printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+	}
+
+	return (0);
+}
+
+
+int dtt_get_temp(int sensor)
+{
+	return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+}
+
+
+#endif /* CONFIG_DTT_DS1775 */
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
new file mode 100644
index 0000000..63f3b75
--- /dev/null
+++ b/drivers/hwmon/lm75.c
@@ -0,0 +1,185 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * On Semiconductor's LM75 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM75
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM75"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48			/* ON Semi's LM75 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if((reg < 0) || (reg > 3))
+	return -1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HYST) ||
+	(reg == DTT_TEMP_SET))
+	dlen = 2;
+    else
+	dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return -1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+	return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if ((reg < 0) || (reg > 3))
+	return 1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Handle 2 byte values.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HYST) ||
+	(reg == DTT_TEMP_SET)) {
+	dlen = 2;
+	data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+	data[1] = (char)(val & 0xff);
+    } else {
+	dlen = 1;
+	data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup TSET ( trip point ) register
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */
+    if (dtt_write(sensor, DTT_TEMP_SET, val) != 0)
+	return 1;
+
+    /*
+     * Setup THYST ( untrip point ) register - Hysteresis
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+	return 1;
+
+    /*
+     * Setup configuraton register
+     */
+#ifdef CONFIG_DTT_AD7414
+    /* config = alert active low and disabled */
+    val = 0x60;
+#else
+    /* config = 6 sample integration, int mode, active low, and enable */
+    val = 0x18;
+#endif
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+	return 1;
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("%s%d FAILED INIT\n", header, i+1);
+	else
+	    printf("%s%d is %i C\n", header, i+1,
+		   dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+int dtt_get_temp(int sensor)
+{
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM75 */
diff --git a/drivers/hwmon/lm81.c b/drivers/hwmon/lm81.c
new file mode 100644
index 0000000..03bc53d
--- /dev/null
+++ b/drivers/hwmon/lm81.c
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Enginnering <hs@denx.de>
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * On Semiconductor's LM81 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM81
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM81"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x2c			/* ON Semi's LM81 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen = 1;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return -1;
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    uchar data;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
+
+    data = (char)(val & 0xff);
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, &data, 1) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+#define DTT_MANU	0x3e
+#define DTT_REV		0x3f
+#define DTT_CONFIG	0x40
+#define DTT_ADR		0x48
+
+static int _dtt_init(int sensor)
+{
+	int	man;
+	int	adr;
+	int	rev;
+
+	if (dtt_write (sensor, DTT_CONFIG, 0x01) < 0)
+		return 1;
+	/* The LM81 needs 400ms to get the correct values ... */
+	udelay (400000);
+	man = dtt_read (sensor, DTT_MANU);
+	if (man != 0x01)
+		return 1;
+	adr = dtt_read (sensor, DTT_ADR);
+	if (adr < 0)
+		return 1;
+	rev = dtt_read (sensor, DTT_REV);
+	if (adr < 0)
+		return 1;
+
+	printf ("DTT:   Found LM81@%x Rev: %d\n", adr, rev);
+	return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("%s%d FAILED INIT\n", header, i+1);
+	else
+	    printf("%s%d is %i C\n", header, i+1,
+		   dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+#define TEMP_FROM_REG(temp) \
+   ((temp)<256?((((temp)&0x1fe) >> 1) * 10)	 + ((temp) & 1) * 5:  \
+	       ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5)  \
+
+int dtt_get_temp(int sensor)
+{
+	int val = dtt_read (sensor, DTT_READ_TEMP);
+	int tmpcnf = dtt_read (sensor, DTT_CONFIG_TEMP);
+
+	return (TEMP_FROM_REG((val << 1) + ((tmpcnf & 0x80) >> 7))) / 10;
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM81 */