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