/*
 * (C) Copyright 2007
 * Larry Johnson, lrj@acm.org
 *
 * based on rtc/m41t11.c which is ...
 *
 * (C) Copyright 2002
 * Andrew May, Viasat Inc, amay@viasat.com
 *
 * 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
 */

/*
 * STMicroelectronics M41T60 serial access real-time clock
 */

/* #define DEBUG 1 */

#include <common.h>
#include <command.h>
#include <rtc.h>
#include <i2c.h>

#if defined(CONFIG_RTC_M41T60) && defined(CFG_I2C_RTC_ADDR) && \
	defined(CONFIG_CMD_DATE)

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

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

/*
 * Convert between century and "century bits" (CB1 and CB0).  These routines
 * assume years are in the range 1900 - 2299.
 */

static unsigned char year2cb(unsigned const year)
{
	if (year < 1900 || year >= 2300)
		printf("M41T60 RTC: year %d out of range\n", year);

	return (year / 100) & 0x3;
}

static unsigned cb2year(unsigned const cb)
{
	return 1900 + 100 * ((cb + 1) & 0x3);
}

/*
 * These are simple defines for the chip local to here so they aren't too
 * verbose.  DAY/DATE aren't nice but that is how they are on the data sheet.
 */
#define RTC_SEC		0x0
#define RTC_MIN		0x1
#define RTC_HOUR	0x2
#define RTC_DAY		0x3
#define RTC_DATE	0x4
#define RTC_MONTH	0x5
#define RTC_YEAR	0x6

#define RTC_REG_CNT	7

#define RTC_CTRL	0x7

#if defined(DEBUG)
static void rtc_dump(char const *const label)
{
	uchar data[8];

	if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, data, sizeof(data))) {
		printf("I2C read failed in rtc_dump()\n");
		return;
	}
	printf("RTC dump %s: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
	       label, data[0], data[1], data[2], data[3],
	       data[4], data[5], data[6], data[7]);
}
#else
#define rtc_dump(label)
#endif

static uchar *rtc_validate(void)
{
	/*
	 * This routine uses the OUT bit and the validity of the time values to
	 * determine whether there has been an initial power-up since the last
	 * time the routine was run.  It assumes that the OUT bit is not being
	 * used for any other purpose.
	 */
	static const uchar daysInMonth[0x13] = {
		0x00, 0x31, 0x29, 0x31, 0x30, 0x31, 0x30, 0x31,
		0x31, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x31, 0x30, 0x31
	};
	static uchar data[8];
	uchar min, date, month, years;

	rtc_dump("begin validate");
	if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, data, sizeof(data))) {
		printf("I2C read failed in rtc_validate()\n");
		return 0;
	}
	/*
	 * If the OUT bit is "1", there has been a loss of power, so stop the
	 * oscillator so it can be "kick-started" as per data sheet.
	 */
	if (0x00 != (data[RTC_CTRL] & 0x80)) {
		printf("M41T60 RTC clock lost power.\n");
		data[RTC_SEC] = 0x80;
		if (i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC, 1, data, 1)) {
			printf("I2C write failed in rtc_validate()\n");
			return 0;
		}
	}
	/*
	 * If the oscillator is stopped or the date is invalid, then reset the
	 * OUT bit to "0", reset the date registers, and start the oscillator.
	 */
	min = data[RTC_MIN] & 0x7F;
	date = data[RTC_DATE];
	month = data[RTC_MONTH] & 0x3F;
	years = data[RTC_YEAR];
	if (0x59 < data[RTC_SEC] || 0x09 < (data[RTC_SEC] & 0x0F) ||
	    0x59 < min || 0x09 < (min & 0x0F) ||
	    0x23 < data[RTC_HOUR] || 0x09 < (data[RTC_HOUR] & 0x0F) ||
	    0x07 < data[RTC_DAY] || 0x00 == data[RTC_DAY] ||
	    0x12 < month ||
	    0x99 < years || 0x09 < (years & 0x0F) ||
	    daysInMonth[month] < date || 0x09 < (date & 0x0F) || 0x00 == date ||
	    (0x29 == date && 0x02 == month &&
	     ((0x00 != (years & 0x03)) ||
	      (0x00 == years && 0x00 != (data[RTC_MONTH] & 0xC0))))) {
		printf("Resetting M41T60 RTC clock.\n");
		/*
		 * Set to 00:00:00 1900-01-01 (Monday)
		 */
		data[RTC_SEC] = 0x00;
		data[RTC_MIN] &= 0x80;	/* preserve OFIE bit */
		data[RTC_HOUR] = 0x00;
		data[RTC_DAY] = 0x02;
		data[RTC_DATE] = 0x01;
		data[RTC_MONTH] = 0xC1;
		data[RTC_YEAR] = 0x00;
		data[RTC_CTRL] &= 0x7F;	/* reset OUT bit */

		if (i2c_write(CFG_I2C_RTC_ADDR, 0, 1, data, sizeof(data))) {
			printf("I2C write failed in rtc_validate()\n");
			return 0;
		}
	}
	return data;
}

void rtc_get(struct rtc_time *tmp)
{
	uchar const *const data = rtc_validate();

	if (!data)
		return;

	tmp->tm_sec = bcd2bin(data[RTC_SEC] & 0x7F);
	tmp->tm_min = bcd2bin(data[RTC_MIN] & 0x7F);
	tmp->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3F);
	tmp->tm_mday = bcd2bin(data[RTC_DATE] & 0x3F);
	tmp->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1F);
	tmp->tm_year = cb2year(data[RTC_MONTH] >> 6) + bcd2bin(data[RTC_YEAR]);
	tmp->tm_wday = bcd2bin(data[RTC_DAY] & 0x07) - 1;
	tmp->tm_yday = 0;
	tmp->tm_isdst = 0;

	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
	      tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
	      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
}

void rtc_set(struct rtc_time *tmp)
{
	uchar *const data = rtc_validate();

	if (!data)
		return;

	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
	      tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
	      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);

	data[RTC_SEC] = (data[RTC_SEC] & 0x80) | (bin2bcd(tmp->tm_sec) & 0x7F);
	data[RTC_MIN] = (data[RTC_MIN] & 0X80) | (bin2bcd(tmp->tm_min) & 0X7F);
	data[RTC_HOUR] = bin2bcd(tmp->tm_hour) & 0x3F;
	data[RTC_DATE] = bin2bcd(tmp->tm_mday) & 0x3F;
	data[RTC_MONTH] = bin2bcd(tmp->tm_mon) & 0x1F;
	data[RTC_YEAR] = bin2bcd(tmp->tm_year % 100);
	data[RTC_MONTH] |= year2cb(tmp->tm_year) << 6;
	data[RTC_DAY] = bin2bcd(tmp->tm_wday + 1) & 0x07;
	if (i2c_write(CFG_I2C_RTC_ADDR, 0, 1, data, RTC_REG_CNT)) {
		printf("I2C write failed in rtc_set()\n");
		return;
	}
}

void rtc_reset(void)
{
	uchar *const data = rtc_validate();
	char const *const s = getenv("rtccal");

	if (!data)
		return;

	rtc_dump("begin reset");
	/*
	 * If environmental variable "rtccal" is present, it must be a hex value
	 * between 0x00 and 0x3F, inclusive.  The five least-significan bits
	 * represent the calibration magnitude, and the sixth bit the sign bit.
	 * If these do not match the contents of the hardware register, that
	 * register is updated.  The value 0x00 imples no correction.  Consult
	 * the M41T60 documentation for further details.
	 */
	if (s) {
		unsigned long const l = simple_strtoul(s, 0, 16);

		if (l <= 0x3F) {
			if ((data[RTC_CTRL] & 0x3F) != l) {
				printf("Setting RTC calibration to 0x%02X\n",
				       l);
				data[RTC_CTRL] &= 0xC0;
				data[RTC_CTRL] |= (uchar) l;
			}
		} else
			printf("environment parameter \"rtccal\" not valid: "
			       "ignoring\n");
	}
	/*
	 * Turn off frequency test.
	 */
	data[RTC_CTRL] &= 0xBF;
	if (i2c_write(CFG_I2C_RTC_ADDR, RTC_CTRL, 1, data + RTC_CTRL, 1)) {
		printf("I2C write failed in rtc_reset()\n");
		return;
	}
	rtc_dump("end reset");
}
#endif /* CONFIG_RTC_M41T60 && CFG_I2C_RTC_ADDR && CONFIG_CMD_DATE */
