/*
 * (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 & sensor);

    /*
     * 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 */
