/*
 * (C) Copyright 2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * 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 <post.h>
#include <common.h>

#ifdef CONFIG_POST

/*
 * SYSMON test
 *
 * This test performs the system hardware monitoring.
 * The test passes when all the following voltages and temperatures
 * are within allowed ranges:
 *
 * Board temperature
 * Front temperature
 * +3.3V CPU logic
 * +5V logic
 * +12V PCMCIA
 * +12V CCFL
 * +5V standby
 *
 * CCFL is not enabled if temperature values are not within allowed ranges
 *
 * See the list off all parameters in the sysmon_table below
 */

#include <post.h>
#include <watchdog.h>
#include <i2c.h>

#if CONFIG_POST & CFG_POST_SYSMON

static int sysmon_temp_invalid = 0;

/* #define DEBUG */

#define	RELOC(x) if (x != NULL) x = (void *) ((ulong) (x) + gd->reloc_off)

typedef struct sysmon_s sysmon_t;
typedef struct sysmon_table_s sysmon_table_t;

static void sysmon_lm87_init (sysmon_t * this);
static void sysmon_pic_init (sysmon_t * this);
static uint sysmon_i2c_read (sysmon_t * this, uint addr);
static uint sysmon_i2c_read_sgn (sysmon_t * this, uint addr);
static void sysmon_ccfl_disable (sysmon_table_t * this);
static void sysmon_ccfl_enable (sysmon_table_t * this);

struct sysmon_s
{
	uchar	chip;
	void	(*init)(sysmon_t *);
	uint	(*read)(sysmon_t *, uint);
};

static sysmon_t sysmon_lm87 =
	{CFG_I2C_SYSMON_ADDR, sysmon_lm87_init, sysmon_i2c_read};
static sysmon_t sysmon_lm87_sgn =
	{CFG_I2C_SYSMON_ADDR, sysmon_lm87_init, sysmon_i2c_read_sgn};
static sysmon_t sysmon_pic =
	{CFG_I2C_PICIO_ADDR, sysmon_pic_init, sysmon_i2c_read};

static sysmon_t * sysmon_list[] =
{
	&sysmon_lm87,
	&sysmon_lm87_sgn,
	&sysmon_pic,
	NULL
};

struct sysmon_table_s
{
	char *		name;
	char *		unit_name;
	sysmon_t *	sysmon;
	void		(*exec_before)(sysmon_table_t *);
	void		(*exec_after)(sysmon_table_t *);

	int		unit_div;
	int		unit_min;
	int		unit_max;
	uint		val_mask;
	uint		val_min;
	uint		val_max;
	int		val_valid;
	uint		addr;
};

static sysmon_table_t sysmon_table[] =
{
    {"Board temperature", " C", &sysmon_lm87_sgn, NULL, sysmon_ccfl_disable,
     1, -128, 127, 0xFF, 0x58, 0xD5, 0, 0x27},

    {"Front temperature", " C", &sysmon_lm87, NULL, sysmon_ccfl_disable,
     100, -27316, 8984, 0xFF, 0xA4, 0xFC, 0, 0x29},

    {"+3.3V CPU logic", "V", &sysmon_lm87, NULL, NULL,
     1000, 0, 4386, 0xFF, 0xB6, 0xC9, 0, 0x22},

    {"+5V logic", "V", &sysmon_lm87, NULL, NULL,
     1000, 0, 6630, 0xFF, 0xB6, 0xCA, 0, 0x23},

    {"+12V PCMCIA", "V", &sysmon_lm87, NULL, NULL,
     1000, 0, 15460, 0xFF, 0xBC, 0xD0, 0, 0x21},

    {"+12V CCFL", "V", &sysmon_lm87, NULL, sysmon_ccfl_enable,
     1000, 0, 15900, 0xFF, 0xB6, 0xCA, 0, 0x24},

    {"+5V standby", "V", &sysmon_pic, NULL, NULL,
     1000, 0, 6040, 0xFF, 0xC8, 0xDE, 0, 0x7C},
};
static int sysmon_table_size = sizeof(sysmon_table) / sizeof(sysmon_table[0]);

static int conversion_done = 0;


int sysmon_init_f (void)
{
	sysmon_t ** l;
	ulong reg;

	/* Power on CCFL, PCMCIA */
	reg = pic_read  (0x60);
	reg |= 0x09;
	pic_write (0x60, reg);

	for (l = sysmon_list; *l; l++)
	{
		(*l)->init(*l);
	}

	return 0;
}

void sysmon_reloc (void)
{
	DECLARE_GLOBAL_DATA_PTR;

	sysmon_t ** l;
	sysmon_table_t * t;

	for (l = sysmon_list; *l; l++)
	{
		RELOC(*l);
		RELOC((*l)->init);
		RELOC((*l)->read);
	}

	for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++)
	{
		RELOC(t->exec_before);
		RELOC(t->exec_after);
		RELOC(t->sysmon);
	}
}

static char * sysmon_unit_value (sysmon_table_t * s, uint val)
{
	static char buf[32];
	int unit_val =
	    s->unit_min + (s->unit_max - s->unit_min) * val / s->val_mask;
	char * p;
	int dec, frac;

	sprintf(buf, "%+d", unit_val / s->unit_div);

	frac = (unit_val > 0 ? unit_val : -unit_val) % s->unit_div;
	p = buf + strlen(buf);

	dec = s->unit_div;

	if (dec != 1)
	{
		*p++ = '.';
	}

	for (dec /= 10; dec != 0; dec /= 10)
	{
		*p++ = '0' + frac / dec % 10;
	}

	strcpy(p, s->unit_name);

	return buf;
}

static void sysmon_lm87_init (sysmon_t * this)
{
	uchar val;

	/* Detect LM87 chip */
	if (i2c_read(this->chip, 0x40, 1, &val, 1) || (val & 0x80) != 0 ||
	    i2c_read(this->chip, 0x3E, 1, &val, 1) || val != 0x02)
	{
		printf("Error: LM87 not found at 0x%02X\n", this->chip);
		return;
	}

	/* Configure pins 5,6 as AIN */
	val = 0x03;
	if (i2c_write(this->chip, 0x16, 1, &val, 1))
	{
		printf("Error: can't write LM87 config register\n");
		return;
	}

	/* Start monitoring */
	val = 0x01;
	if (i2c_write(this->chip, 0x40, 1, &val, 1))
	{
		printf("Error: can't write LM87 config register\n");
		return;
	}
}

static void sysmon_pic_init (sysmon_t * this)
{
}

static uint sysmon_i2c_read (sysmon_t * this, uint addr)
{
	uchar val;
	uint res = i2c_read(this->chip, addr, 1, &val, 1);

	return res == 0 ? val : -1;
}

static uint sysmon_i2c_read_sgn (sysmon_t * this, uint addr)
{
	uchar val;
	return i2c_read(this->chip, addr, 1, &val, 1) == 0 ?
		128 + (signed char)val : -1;
}

static void sysmon_ccfl_disable (sysmon_table_t * this)
{
	if (!this->val_valid)
	{
		sysmon_temp_invalid = 1;
	}
}

static void sysmon_ccfl_enable (sysmon_table_t * this)
{
	ulong reg;

	if (!sysmon_temp_invalid)
	{
		reg = pic_read  (0x60);
		reg |= 0x02;
		pic_write (0x60, reg);
	}
}

int sysmon_post_test (int flags)
{
	DECLARE_GLOBAL_DATA_PTR;

	int res = 0;
	sysmon_table_t * t;
	uint val;

	/*
	 * The A/D conversion on the LM87 sensor takes 300 ms.
	 */
	if (! conversion_done)
	{
		while (post_time_ms(gd->post_init_f_time) < 300) WATCHDOG_RESET ();
		conversion_done = 1;
	}

	for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++)
	{
		if (t->exec_before)
		{
			t->exec_before(t);
		}

		val = t->sysmon->read(t->sysmon, t->addr);
		t->val_valid = val >= t->val_min && val <= t->val_max;

		if (t->exec_after)
		{
			t->exec_after(t);
		}

#ifndef DEBUG
		if (!t->val_valid)
#endif
		{
			printf("%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
			printf("allowed range");
			printf(" %-8s ..", sysmon_unit_value(t, t->val_min));
			printf(" %-8s", sysmon_unit_value(t, t->val_max));
			printf("     %s\n", t->val_valid ? "OK" : "FAIL");
		}

		if (!t->val_valid)
		{
			res = -1;
		}
	}

	return res;
}

#endif /* CONFIG_POST & CFG_POST_SYSMON */
#endif /* CONFIG_POST */
