diff options
| author | Wolfgang Denk <wd@denx.de> | 2007-11-26 19:15:04 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2007-11-26 19:15:04 +0100 | 
| commit | fe08fb658008cd4be54758faa5d382a2b3b1f86a (patch) | |
| tree | a932a892ff4702d91d51ea13cf81be4e4f6c9d27 /drivers/hwmon/ds1621.c | |
| parent | cfa4c9d8996d5949f615553c220a06c9fe6395cc (diff) | |
| parent | 87ddedd6ad804427ce125ceaa076d7a4f74e9d5d (diff) | |
| download | olio-uboot-2014.01-fe08fb658008cd4be54758faa5d382a2b3b1f86a.tar.xz olio-uboot-2014.01-fe08fb658008cd4be54758faa5d382a2b3b1f86a.zip | |
Merge commit '87ddedd'
Diffstat (limited to 'drivers/hwmon/ds1621.c')
| -rw-r--r-- | drivers/hwmon/ds1621.c | 190 | 
1 files changed, 190 insertions, 0 deletions
| diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c new file mode 100644 index 000000000..494818131 --- /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 */ |