ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/drivers/hwmon/Makefile b/marvell/uboot/drivers/hwmon/Makefile
new file mode 100644
index 0000000..a78a724
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/Makefile
@@ -0,0 +1,21 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2001
+# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+#CFLAGS += -DDEBUG
+
+obj-$(CONFIG_DTT_ADM1021) += adm1021.o
+obj-$(CONFIG_DTT_ADT7460) += adt7460.o
+obj-$(CONFIG_DTT_DS1621) += ds1621.o
+obj-$(CONFIG_DTT_DS1722) += ds1722.o
+obj-$(CONFIG_DTT_DS1775) += ds1775.o
+obj-$(CONFIG_DTT_LM63) += lm63.o
+obj-$(CONFIG_DTT_LM73) += lm73.o
+obj-$(CONFIG_DTT_LM75) += lm75.o
+obj-$(CONFIG_DTT_LM81) += lm81.o
diff --git a/marvell/uboot/drivers/hwmon/adm1021.c b/marvell/uboot/drivers/hwmon/adm1021.c
new file mode 100644
index 0000000..99e942b
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/adm1021.c
@@ -0,0 +1,164 @@
+/*
+ * (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
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Analog Devices's ADM1021
+ * "Low Cost Microprocessor System Temperature Monitor"
+ */
+
+#include <common.h>
+
+#include <i2c.h>
+#include <dtt.h>
+
+#define DTT_READ_LOC_VALUE	0x00
+#define DTT_READ_REM_VALUE	0x01
+#define DTT_READ_STATUS		0x02
+#define DTT_READ_CONFIG		0x03
+#define DTT_READ_CONVRATE	0x04
+#define DTT_READ_LOC_HIGHLIM	0x05
+#define DTT_READ_LOC_LOWLIM	0x06
+#define DTT_READ_REM_HIGHLIM	0x07
+#define DTT_READ_REM_LOWLIM	0x08
+#define DTT_READ_DEVID		0xfe
+
+#define DTT_WRITE_CONFIG	0x09
+#define DTT_WRITE_CONVRATE	0x0a
+#define DTT_WRITE_LOC_HIGHLIM	0x0b
+#define DTT_WRITE_LOC_LOWLIM	0x0c
+#define DTT_WRITE_REM_HIGHLIM	0x0d
+#define DTT_WRITE_REM_LOWLIM	0x0e
+#define DTT_WRITE_ONESHOT	0x0f
+
+#define DTT_STATUS_BUSY		0x80	/* 1=ADC Converting */
+#define DTT_STATUS_LHIGH	0x40	/* 1=Local High Temp Limit Tripped */
+#define DTT_STATUS_LLOW		0x20	/* 1=Local Low Temp Limit Tripped */
+#define DTT_STATUS_RHIGH	0x10	/* 1=Remote High Temp Limit Tripped */
+#define DTT_STATUS_RLOW		0x08	/* 1=Remote Low Temp Limit Tripped */
+#define DTT_STATUS_OPEN		0x04	/* 1=Remote Sensor Open-Circuit */
+
+#define DTT_CONFIG_ALERT_MASKED	0x80	/* 0=ALERT Enabled, 1=ALERT Masked */
+#define DTT_CONFIG_STANDBY	0x40	/* 0=Run, 1=Standby */
+
+#define DTT_ADM1021_DEVID	0x41
+
+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[] = CONFIG_SYS_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() */
+
+int
+dtt_init_one(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_one() */
+
+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() */
diff --git a/marvell/uboot/drivers/hwmon/adt7460.c b/marvell/uboot/drivers/hwmon/adt7460.c
new file mode 100644
index 0000000..fd05c17
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/adt7460.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2008
+ * Ricado Ribalda-Universidad Autonoma de Madrid, ricardo.ribalda@uam.es
+ * This work has been supported by: QTechnology  http://qtec.com/
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <dtt.h>
+
+#define ADT7460_ADDRESS		0x2c
+#define ADT7460_INVALID		128
+#define ADT7460_CONFIG		0x40
+#define ADT7460_REM1_TEMP	0x25
+#define ADT7460_LOCAL_TEMP	0x26
+#define ADT7460_REM2_TEMP	0x27
+
+int dtt_read(int sensor, int reg)
+{
+	u8 dir = reg;
+	u8 data;
+
+	if (i2c_read(ADT7460_ADDRESS, dir, 1, &data, 1) == -1)
+		return -1;
+	if (data == ADT7460_INVALID)
+		return -1;
+
+	return data;
+}
+
+int dtt_write(int sensor, int reg, int val)
+{
+	u8 dir = reg;
+	u8 data = val;
+
+	if (i2c_write(ADT7460_ADDRESS, dir, 1, &data, 1) == -1)
+		return -1;
+
+	return 0;
+}
+
+int dtt_init_one(int sensor)
+{
+	printf("ADT7460 at I2C address 0x%2x\n", ADT7460_ADDRESS);
+
+	if (dtt_write(0, ADT7460_CONFIG, 1) == -1) {
+		puts("Error initialiting ADT7460\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+int dtt_get_temp(int sensor)
+{
+	int aux;
+	u8 table[] =
+	    { ADT7460_REM1_TEMP, ADT7460_LOCAL_TEMP, ADT7460_REM2_TEMP };
+
+	if (sensor > 2) {
+		puts("DTT sensor does not exist\n");
+		return -1;
+	}
+
+	aux = dtt_read(0, table[sensor]);
+	if (aux == -1) {
+		puts("DTT temperature read failed\n");
+		return -1;
+	}
+
+	return aux;
+}
diff --git a/marvell/uboot/drivers/hwmon/ds1621.c b/marvell/uboot/drivers/hwmon/ds1621.c
new file mode 100644
index 0000000..66947a6
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/ds1621.c
@@ -0,0 +1,155 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.com.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Dallas Semiconductor's DS1621/1631 Digital Thermometer and Thermostat.
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 	0x48	/* Dallas Semi's DS1621 */
+#define DTT_READ_TEMP		0xAA
+#define DTT_READ_COUNTER	0xA8
+#define DTT_READ_SLOPE		0xA9
+#define DTT_WRITE_START_CONV	0xEE
+#define DTT_WRITE_STOP_CONV	0x22
+#define DTT_TEMP_HIGH		0xA1
+#define DTT_TEMP_LOW		0xA2
+#define DTT_CONFIG		0xAC
+
+/*
+ * Config register bits
+ */
+#define DTT_CONFIG_1SHOT	0x01
+#define DTT_CONFIG_POLARITY	0x02
+#define DTT_CONFIG_R0		0x04	/* ds1631 only */
+#define DTT_CONFIG_R1		0x08	/* ds1631 only */
+#define DTT_CONFIG_NVB		0x10
+#define DTT_CONFIG_TLF		0x20
+#define DTT_CONFIG_THF		0x40
+#define DTT_CONFIG_DONE		0x80
+
+
+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 */
+	switch(reg) {
+	case DTT_READ_TEMP:
+	case DTT_TEMP_HIGH:
+	case DTT_TEMP_LOW:
+		dlen = 2;
+		break;
+	default:
+		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 (short)((data[0] << 8) | data[1]);
+
+	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. */
+	switch(reg) {
+	case DTT_READ_TEMP:
+	case DTT_TEMP_HIGH:
+	case DTT_TEMP_LOW:
+		dlen = 2;
+		data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+		data[1] = (char)(val & 0xff);
+		break;
+	case DTT_WRITE_START_CONV:
+	case DTT_WRITE_STOP_CONV:
+		dlen = 0;
+		data[0] = (char)0;
+		data[1] = (char)0;
+		break;
+	default:
+		dlen = 1;
+		data[0] = (char)(val & 0xff);
+	}
+
+	/* Write value to device */
+	if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+		return 1;
+
+	/* Poll NV memory busy bit in case write was to register stored in EEPROM */
+	while(i2c_reg_read(sensor, DTT_CONFIG) & DTT_CONFIG_NVB)
+		;
+
+	return 0;
+}
+
+
+int dtt_init_one(int sensor)
+{
+	int val;
+
+	/* Setup High Temp */
+	val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+	if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
+		return 1;
+
+	/* Setup Low Temp - hysteresis */
+	val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+	if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
+		return 1;
+
+	/*
+	 * 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;
+
+	return 0;
+}
+
+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) & DTT_CONFIG_DONE)
+			break;
+	}
+
+	return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+}
diff --git a/marvell/uboot/drivers/hwmon/ds1722.c b/marvell/uboot/drivers/hwmon/ds1722.c
new file mode 100644
index 0000000..c469588
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/ds1722.c
@@ -0,0 +1,137 @@
+#include <common.h>
+#include <asm/ic/ssi.h>
+#include <ds1722.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;
+}
diff --git a/marvell/uboot/drivers/hwmon/ds1775.c b/marvell/uboot/drivers/hwmon/ds1775.c
new file mode 100644
index 0000000..b95b130
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/ds1775.c
@@ -0,0 +1,126 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat
+ */
+
+#include <common.h>
+
+#include <i2c.h>
+#include <dtt.h>
+
+#define DTT_I2C_DEV_CODE	CONFIG_SYS_I2C_DTT_ADDR /* Dallas Semi's DS1775 device code */
+#define DTT_READ_TEMP		0x0
+#define DTT_CONFIG		0x1
+#define DTT_TEMP_HYST		0x2
+#define DTT_TEMP_OS		0x3
+
+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;
+}
+
+
+int dtt_init_one(int sensor)
+{
+	int val;
+
+	/*
+	 * Setup High Temp
+	 */
+	val = ((CONFIG_SYS_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 = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_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_get_temp(int sensor)
+{
+	return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+}
diff --git a/marvell/uboot/drivers/hwmon/lm63.c b/marvell/uboot/drivers/hwmon/lm63.c
new file mode 100644
index 0000000..053c785
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/lm63.c
@@ -0,0 +1,160 @@
+/*
+ * (C) Copyright 2007-2008
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
+ * based on lm75.c by Bill Hunter
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * National LM63/LM64 Temperature Sensor
+ * Main difference: LM 64 has -16 Kelvin temperature offset
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <dtt.h>
+
+#define DTT_I2C_LM63_ADDR	0x4C	/* National LM63 device */
+
+#define DTT_READ_TEMP_RMT_MSB	0x01
+#define DTT_CONFIG		0x03
+#define DTT_READ_TEMP_RMT_LSB	0x10
+#define DTT_TACHLIM_LSB		0x48
+#define DTT_TACHLIM_MSB		0x49
+#define DTT_FAN_CONFIG		0x4A
+#define DTT_PWM_FREQ		0x4D
+#define DTT_PWM_LOOKUP_BASE	0x50
+
+struct pwm_lookup_entry {
+	u8 temp;
+	u8 pwm;
+};
+
+/*
+ * Device code
+ */
+
+int dtt_read(int sensor, int reg)
+{
+	int dlen;
+	uchar data[2];
+
+	/*
+	 * Calculate sensor address and register.
+	 */
+	if (!sensor)
+		sensor = DTT_I2C_LM63_ADDR;	/* legacy config */
+
+	dlen = 1;
+
+	/*
+	 * 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)
+{
+	int dlen;
+	uchar data[2];
+
+	/*
+	 * Calculate sensor address and register.
+	 */
+	if (!sensor)
+		sensor = DTT_I2C_LM63_ADDR;	/* legacy config */
+
+	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 is_lm64(int sensor)
+{
+	return sensor && (sensor != DTT_I2C_LM63_ADDR);
+}
+
+int dtt_init_one(int sensor)
+{
+	int i;
+	int val;
+
+	struct pwm_lookup_entry pwm_lookup[] = CONFIG_DTT_PWM_LOOKUPTABLE;
+
+	/*
+	 * Set PWM Frequency to 2.5% resolution
+	 */
+	val = 20;
+	if (dtt_write(sensor, DTT_PWM_FREQ, val) != 0)
+		return 1;
+
+	/*
+	 * Set Tachometer Limit
+	 */
+	val = CONFIG_DTT_TACH_LIMIT;
+	if (dtt_write(sensor, DTT_TACHLIM_LSB, val & 0xff) != 0)
+		return 1;
+	if (dtt_write(sensor, DTT_TACHLIM_MSB, (val >> 8) & 0xff) != 0)
+		return 1;
+
+	/*
+	 * Make sure PWM Lookup-Table is writeable
+	 */
+	if (dtt_write(sensor, DTT_FAN_CONFIG, 0x20) != 0)
+		return 1;
+
+	/*
+	 * Setup PWM Lookup-Table
+	 */
+	for (i = 0; i < ARRAY_SIZE(pwm_lookup); i++) {
+		int address = DTT_PWM_LOOKUP_BASE + 2 * i;
+		val = pwm_lookup[i].temp;
+		if (is_lm64(sensor))
+			val -= 16;
+		if (dtt_write(sensor, address, val) != 0)
+			return 1;
+		val = dtt_read(sensor, address);
+		val = pwm_lookup[i].pwm;
+		if (dtt_write(sensor, address + 1, val) != 0)
+			return 1;
+	}
+
+	/*
+	 * Enable PWM Lookup-Table, PWM Clock 360 kHz, Tachometer Mode 2
+	 */
+	val = 0x02;
+	if (dtt_write(sensor, DTT_FAN_CONFIG, val) != 0)
+		return 1;
+
+	/*
+	 * Enable Tach input
+	 */
+	val = dtt_read(sensor, DTT_CONFIG) | 0x04;
+	if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+		return 1;
+
+	return 0;
+}
+
+int dtt_get_temp(int sensor)
+{
+	s16 temp = (dtt_read(sensor, DTT_READ_TEMP_RMT_MSB) << 8)
+	    | (dtt_read(sensor, DTT_READ_TEMP_RMT_LSB));
+
+	if (is_lm64(sensor))
+		temp += 16 << 8;
+
+	/* Ignore LSB for now, U-Boot only prints natural numbers */
+	return temp >> 8;
+}
diff --git a/marvell/uboot/drivers/hwmon/lm73.c b/marvell/uboot/drivers/hwmon/lm73.c
new file mode 100644
index 0000000..c15c751
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/lm73.c
@@ -0,0 +1,146 @@
+/*
+ * (C) Copyright 2007-2008
+ * Larry Johnson, lrj@acm.org
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * National Semiconductor LM73 Temperature Sensor
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48	/* National Semi's LM73 device */
+#define DTT_READ_TEMP		0x0
+#define DTT_CONFIG		0x1
+#define DTT_TEMP_HIGH		0x2
+#define DTT_TEMP_LOW		0x3
+#define DTT_CONTROL		0x4
+#define DTT_ID			0x7
+
+int dtt_read(int const sensor, int const reg)
+{
+	int dlen;
+	uint8_t data[2];
+
+	/*
+	 * Validate 'reg' param and get register size.
+	 */
+	switch (reg) {
+	case DTT_CONFIG:
+	case DTT_CONTROL:
+		dlen = 1;
+		break;
+	case DTT_READ_TEMP:
+	case DTT_TEMP_HIGH:
+	case DTT_TEMP_LOW:
+	case DTT_ID:
+		dlen = 2;
+		break;
+	default:
+		return -1;
+	}
+	/*
+	 * Try to read the register at the calculated sensor address.
+	 */
+	if (0 !=
+	    i2c_read(DTT_I2C_DEV_CODE + (sensor & 0x07), reg, 1, data, dlen))
+		return -1;
+	/*
+	 * Handle 2 byte result.
+	 */
+	if (2 == dlen)
+		return (int)((unsigned)data[0] << 8 | (unsigned)data[1]);
+
+	return (int)data[0];
+} /* dtt_read() */
+
+int dtt_write(int const sensor, int const reg, int const val)
+{
+	int dlen;
+	uint8_t data[2];
+
+	/*
+	 * Validate 'reg' param and handle register size
+	 */
+	switch (reg) {
+	case DTT_CONFIG:
+	case DTT_CONTROL:
+		dlen = 1;
+		data[0] = (uint8_t) val;
+		break;
+	case DTT_TEMP_HIGH:
+	case DTT_TEMP_LOW:
+		dlen = 2;
+		data[0] = (uint8_t) (val >> 8);	/* MSB first */
+		data[1] = (uint8_t) val;
+		break;
+	default:
+		return -1;
+	}
+	/*
+	 * Write value to register at the calculated sensor address.
+	 */
+	return 0 != i2c_write(DTT_I2C_DEV_CODE + (sensor & 0x07), reg, 1, data,
+			      dlen);
+} /* dtt_write() */
+
+int dtt_init_one(int const sensor)
+{
+	int val;
+
+	/*
+	 * Validate the Identification register
+	 */
+	if (0x0190 != dtt_read(sensor, DTT_ID))
+		return -1;
+	/*
+	 * Setup THIGH (upper-limit) and TLOW (lower-limit) registers
+	 */
+	val = CONFIG_SYS_DTT_MAX_TEMP << 7;
+	if (dtt_write(sensor, DTT_TEMP_HIGH, val))
+		return -1;
+
+	val = CONFIG_SYS_DTT_MIN_TEMP << 7;
+	if (dtt_write(sensor, DTT_TEMP_LOW, val))
+		return -1;
+	/*
+	 * Setup configuraton register
+	 */
+	/* config = alert active low, disabled, and reset */
+	val = 0x64;
+	if (dtt_write(sensor, DTT_CONFIG, val))
+		return -1;
+	/*
+	 * Setup control/status register
+	 */
+	/* control = temp resolution 0.25C */
+	val = 0x00;
+	if (dtt_write(sensor, DTT_CONTROL, val))
+		return -1;
+
+	dtt_read(sensor, DTT_CONTROL);	/* clear temperature flags */
+	return 0;
+} /* dtt_init_one() */
+
+int dtt_get_temp(int const sensor)
+{
+	int const ret = dtt_read(sensor, DTT_READ_TEMP);
+
+	if (ret < 0) {
+		printf("DTT temperature read failed.\n");
+		return 0;
+	}
+	return (int)((int16_t) ret + 0x0040) >> 7;
+} /* dtt_get_temp() */
diff --git a/marvell/uboot/drivers/hwmon/lm75.c b/marvell/uboot/drivers/hwmon/lm75.c
new file mode 100644
index 0000000..462f902
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/lm75.c
@@ -0,0 +1,143 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * On Semiconductor's LM75 Temperature Sensor
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#if defined(CONFIG_SYS_I2C_DTT_ADDR)
+#define DTT_I2C_DEV_CODE CONFIG_SYS_I2C_DTT_ADDR
+#else
+#define DTT_I2C_DEV_CODE 0x48			/* ON Semi's LM75 device */
+#endif
+#define DTT_READ_TEMP		0x0
+#define DTT_CONFIG		0x1
+#define DTT_TEMP_HYST		0x2
+#define DTT_TEMP_SET		0x3
+
+int dtt_read(int sensor, int reg)
+{
+	int dlen;
+	uchar data[2];
+
+#ifdef CONFIG_DTT_AD7414
+	/*
+	 * On AD7414 the first value upon bootup is not read correctly.
+	 * This is most likely because of the 800ms update time of the
+	 * temp register in normal update mode. To get current values
+	 * each time we issue the "dtt" command including upon powerup
+	 * we switch into one-short mode.
+	 *
+	 * Issue one-shot mode command
+	 */
+	dtt_write(sensor, DTT_CONFIG, 0x64);
+#endif
+
+	/* Validate 'reg' param */
+	if((reg < 0) || (reg > 3))
+		return -1;
+
+	/* Calculate sensor address and register. */
+	sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+	/* 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);
+
+	/* 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() */
+
+
+int dtt_init_one(int sensor)
+{
+	int val;
+
+	/* Setup TSET ( trip point ) register */
+	val = ((CONFIG_SYS_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 = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_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_one() */
+
+int dtt_get_temp(int sensor)
+{
+	int const ret = dtt_read(sensor, DTT_READ_TEMP);
+
+	if (ret < 0) {
+		printf("DTT temperature read failed.\n");
+		return 0;
+	}
+	return (int)((int16_t) ret / 256);
+} /* dtt_get_temp() */
diff --git a/marvell/uboot/drivers/hwmon/lm81.c b/marvell/uboot/drivers/hwmon/lm81.c
new file mode 100644
index 0000000..c1fc42a
--- /dev/null
+++ b/marvell/uboot/drivers/hwmon/lm81.c
@@ -0,0 +1,111 @@
+/*
+ * (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
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/*
+ * On Semiconductor's LM81 Temperature Sensor
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x2c			/* ON Semi's LM81 device */
+#define DTT_READ_TEMP		0x27
+#define DTT_CONFIG_TEMP		0x4b
+#define DTT_TEMP_MAX		0x39
+#define DTT_TEMP_HYST		0x3a
+#define DTT_CONFIG		0x40
+
+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
+
+int dtt_init_one(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;
+
+	debug ("DTT:   Found LM81@%x Rev: %d\n", adr, rev);
+	return 0;
+} /* dtt_init_one() */
+
+
+#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() */