summaryrefslogtreecommitdiff
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Makefile56
-rw-r--r--drivers/hwmon/adm1021.c174
-rw-r--r--drivers/hwmon/ds1621.c190
-rw-r--r--drivers/hwmon/ds1722.c142
-rw-r--r--drivers/hwmon/ds1775.c156
-rw-r--r--drivers/hwmon/lm75.c185
-rw-r--r--drivers/hwmon/lm81.c148
7 files changed, 1051 insertions, 0 deletions
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
new file mode 100644
index 0000000000..cebb2ba635
--- /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 0000000000..9f65cfb274
--- /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 0000000000..494818131f
--- /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/hwmon/ds1722.c b/drivers/hwmon/ds1722.c
new file mode 100644
index 0000000000..c19ee01393
--- /dev/null
+++ b/drivers/hwmon/ds1722.c
@@ -0,0 +1,142 @@
+
+#include <common.h>
+
+#ifdef CONFIG_DS1722
+
+#include <ssi.h>
+
+static void ds1722_select(int dev)
+{
+ ssi_set_interface(4096, 0, 0, 0);
+ ssi_chip_select(0);
+ udelay(1);
+ ssi_chip_select(dev);
+ udelay(1);
+}
+
+
+u8 ds1722_read(int dev, int addr)
+{
+ u8 res;
+
+ ds1722_select(dev);
+
+ ssi_tx_byte(addr);
+ res = ssi_rx_byte();
+
+ ssi_chip_select(0);
+
+ return res;
+}
+
+void ds1722_write(int dev, int addr, u8 data)
+{
+ ds1722_select(dev);
+
+ ssi_tx_byte(0x80|addr);
+ ssi_tx_byte(data);
+
+ ssi_chip_select(0);
+}
+
+
+u16 ds1722_temp(int dev, int resolution)
+{
+ static int useconds[] = {
+ 75000, 150000, 300000, 600000, 1200000
+ };
+ char temp;
+ u16 res;
+
+
+ /* set up the desired resulotion ... */
+ ds1722_write(dev, 0, 0xe0 | (resolution << 1));
+
+ /* wait while the chip measures the tremperature */
+ udelay(useconds[resolution]);
+
+ res = (temp = ds1722_read(dev, 2)) << 8;
+
+ if (temp < 0) {
+ temp = (16 - (ds1722_read(dev, 1) >> 4)) & 0x0f;
+ } else {
+ temp = (ds1722_read(dev, 1) >> 4);
+ }
+
+ switch (temp) {
+ case 0:
+ /* .0000 */
+ break;
+ case 1:
+ /* .0625 */
+ res |=1;
+ break;
+ case 2:
+ /* .1250 */
+ res |=1;
+ break;
+ case 3:
+ /* .1875 */
+ res |=2;
+ break;
+ case 4:
+ /* .2500 */
+ res |=3;
+ break;
+ case 5:
+ /* .3125 */
+ res |=3;
+ break;
+ case 6:
+ /* .3750 */
+ res |=4;
+ break;
+ case 7:
+ /* .4375 */
+ res |=4;
+ break;
+ case 8:
+ /* .5000 */
+ res |=5;
+ break;
+ case 9:
+ /* .5625 */
+ res |=6;
+ break;
+ case 10:
+ /* .6250 */
+ res |=6;
+ break;
+ case 11:
+ /* .6875 */
+ res |=7;
+ break;
+ case 12:
+ /* .7500 */
+ res |=8;
+ break;
+ case 13:
+ /* .8125 */
+ res |=8;
+ break;
+ case 14:
+ /* .8750 */
+ res |=9;
+ break;
+ case 15:
+ /* .9375 */
+ res |=9;
+ break;
+ }
+ return res;
+
+}
+
+int ds1722_probe(int dev)
+{
+ u16 temp = ds1722_temp(dev, DS1722_RESOLUTION_12BIT);
+ printf("%d.%d deg C\n\n", (char)(temp >> 8), temp & 0xff);
+ return 0;
+}
+
+#endif
diff --git a/drivers/hwmon/ds1775.c b/drivers/hwmon/ds1775.c
new file mode 100644
index 0000000000..e44cee3279
--- /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 0000000000..63f3b7551e
--- /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 0000000000..03bc53d58c
--- /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 */