/*
 * rs5c372.c
 *
 * Device driver for Ricoh's Real Time Controller RS5C372A.
 *
 * Copyright (C) 2004 Gary Jennejohn garyj@denx.de
 *
 * Based in part in ds1307.c -
 * (C) Copyright 2001, 2002, 2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 * Keith Outwater, keith_outwater@mvis.com`
 * Steven Scholz, steven.scholz@imc-berlin.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 version 2 as
 * published by the Free Software Foundation.
 *
 * 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 <common.h>
#include <command.h>
#include <rtc.h>
#include <i2c.h>

#if defined(CONFIG_RTC_RS5C372A) && defined(CONFIG_CMD_DATE)
/*
 * Reads are always done starting with register 15, which requires some
 * jumping-through-hoops to access the data correctly.
 *
 * Writes are always done starting with register 0.
 */

#define DEBUG 0

#if DEBUG
static unsigned int rtc_debug = DEBUG;
#else
#define rtc_debug 0	/* gcc will remove all the debug code for us */
#endif

#ifndef CFG_I2C_RTC_ADDR
#define CFG_I2C_RTC_ADDR 0x32
#endif

#define RS5C372_RAM_SIZE 0x10
#define RATE_32000HZ	0x80	/* Rate Select 32.000KHz */
#define RATE_32768HZ	0x00	/* Rate Select 32.768KHz */

#define STATUS_XPT  0x10    /* data invalid because voltage was 0 */

#define USE_24HOUR_MODE 0x20
#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
#define HOURS_AP(n)	(((n) >> 5) & 1)
#define HOURS_12(n)	bcd2bin((n) & 0x1F)
#define HOURS_24(n)	bcd2bin((n) & 0x3F)


static uchar bin2bcd (unsigned int n);
static unsigned bcd2bin (uchar c);

static int setup_done = 0;

static int
rs5c372_readram(unsigned char *buf, int len)
{
	int ret;

	ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, len);
	if (ret != 0) {
		printf("%s: failed to read\n", __FUNCTION__);
		return ret;
	}

	if (buf[0] & STATUS_XPT)
		printf("### Warning: RTC lost power\n");

	return ret;
}

static void
rs5c372_enable(void)
{
	unsigned char buf[RS5C372_RAM_SIZE + 1];
	int ret;

	/* note that this returns reg. 15 in buf[1] */
	ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
	if (ret != 0) {
		printf("%s: failed\n", __FUNCTION__);
		return;
	}

	buf[0] = 0;
	/* we want to start writing at register 0 so we have to copy the */
	/* register contents up one slot */
	for (ret = 2; ret < 9; ret++)
		buf[ret - 1] = buf[ret];
	/* registers 0 to 6 (time values) are not touched */
	buf[8] = RATE_32768HZ; /* reg. 7 */
	buf[9] = 0; /* reg. 8 */
	buf[10] = 0; /* reg. 9 */
	buf[11] = 0; /* reg. 10 */
	buf[12] = 0; /* reg. 11 */
	buf[13] = 0; /* reg. 12 */
	buf[14] = 0; /* reg. 13 */
	buf[15] = 0; /* reg. 14 */
	buf[16] = USE_24HOUR_MODE; /* reg. 15 */
	ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
	if (ret != 0) {
		printf("%s: failed\n", __FUNCTION__);
		return;
	}
	setup_done = 1;

	return;
}

static void
rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
{
	/* buf[0] is register 15 */
	dt->tm_sec = bcd2bin(buf[1]);
	dt->tm_min = bcd2bin(buf[2]);

	if (TWELVE_HOUR_MODE(buf[0])) {
		dt->tm_hour = HOURS_12(buf[3]);
		if (HOURS_AP(buf[3])) /* PM */
			dt->tm_hour += 12;
	} else /* 24-hour-mode */
		dt->tm_hour = HOURS_24(buf[3]);

	dt->tm_mday = bcd2bin(buf[5]);
	dt->tm_mon = bcd2bin(buf[6]);
	dt->tm_year = bcd2bin(buf[7]);
	if (dt->tm_year >= 70)
		dt->tm_year += 1900;
	else
		dt->tm_year += 2000;
	/* 0 is Sunday */
	dt->tm_wday = bcd2bin(buf[4] & 0x07);
	dt->tm_yday = 0;
	dt->tm_isdst= 0;

	if(rtc_debug > 2) {
		printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
		printf("rs5c372_convert_to_time: mon  = %d\n", dt->tm_mon);
		printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
		printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
		printf("rs5c372_convert_to_time: min  = %d\n", dt->tm_min);
		printf("rs5c372_convert_to_time: sec  = %d\n", dt->tm_sec);
	}
}

/*
 * Get the current time from the RTC
 */
void
rtc_get (struct rtc_time *tmp)
{
	unsigned char buf[RS5C372_RAM_SIZE];
	int ret;

	if (!setup_done)
		rs5c372_enable();

	if (!setup_done)
		return;

	memset(buf, 0, sizeof(buf));

	/* note that this returns reg. 15 in buf[0] */
	ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
	if (ret != 0) {
		printf("%s: failed\n", __FUNCTION__);
		return;
	}

	rs5c372_convert_to_time(tmp, buf);

	return;
}

/*
 * Set the RTC
 */
void
rtc_set (struct rtc_time *tmp)
{
	unsigned char buf[8], reg15;
	int ret;

	if (!setup_done)
		rs5c372_enable();

	if (!setup_done)
		return;

	if(rtc_debug > 2) {
		printf("rtc_set: tm_year = %d\n", tmp->tm_year);
		printf("rtc_set: tm_mon	 = %d\n", tmp->tm_mon);
		printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
		printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
		printf("rtc_set: tm_min	 = %d\n", tmp->tm_min);
		printf("rtc_set: tm_sec	 = %d\n", tmp->tm_sec);
	}

	memset(buf, 0, sizeof(buf));

	/* only read register 15 */
	ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, 1);

	if (ret == 0) {
		/* need to save register 15 */
		reg15 = buf[0];
		buf[0] = 0;	/* register address on RS5C372 */
		buf[1] = bin2bcd(tmp->tm_sec);
		buf[2] = bin2bcd(tmp->tm_min);
		/* need to handle 12 hour mode */
		if (TWELVE_HOUR_MODE(reg15)) {
			if (tmp->tm_hour >= 12) { /* PM */
				/* 12 PM is a special case */
				if (tmp->tm_hour == 12)
					buf[3] = bin2bcd(tmp->tm_hour);
				else
					buf[3] = bin2bcd(tmp->tm_hour - 12);
				buf[3] |= 0x20;
			}
		} else {
			buf[3] = bin2bcd(tmp->tm_hour);
		}

		buf[4] = bin2bcd(tmp->tm_wday);
		buf[5] = bin2bcd(tmp->tm_mday);
		buf[6] = bin2bcd(tmp->tm_mon);
		if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
			printf("WARNING: year should be between 1970 and 2069!\n");
		buf[7] = bin2bcd(tmp->tm_year % 100);

		ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, 8);
		if (ret != 0)
			printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
	}

	return;
}

/*
 * Reset the RTC. We set the date back to 1970-01-01.
 */
void
rtc_reset (void)
{
	struct rtc_time tmp;

	if (!setup_done)
		rs5c372_enable();

	if (!setup_done)
		return;

	tmp.tm_year = 1970;
	tmp.tm_mon = 1;
	/* Jan. 1, 1970 was a Thursday */
	tmp.tm_wday= 4;
	tmp.tm_mday= 1;
	tmp.tm_hour = 0;
	tmp.tm_min = 0;
	tmp.tm_sec = 0;

	rtc_set(&tmp);

	printf ("RTC:	%4d-%02d-%02d %2d:%02d:%02d UTC\n",
		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);

	return;
}

static unsigned int
bcd2bin (unsigned char n)
{
	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
}

static unsigned char
bin2bcd (unsigned int n)
{
	return (((n / 10) << 4) | (n % 10));
}
#endif
