/*
 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Andreas Heppel <aheppel@sysgo.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
 */

/*
 * Date & Time support for the MK48T59 RTC
 */

#undef	RTC_DEBUG

#include <common.h>
#include <command.h>
#include <config.h>
#include <rtc.h>
#include <mk48t59.h>

#if defined(CONFIG_BAB7xx)

static uchar rtc_read (short reg)
{
	out8(RTC_PORT_ADDR0, reg & 0xFF);
	out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
	return in8(RTC_PORT_DATA);
}

static void rtc_write (short reg, uchar val)
{
	out8(RTC_PORT_ADDR0, reg & 0xFF);
	out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
	out8(RTC_PORT_DATA, val);
}

#elif defined(CONFIG_EVAL5200)

static uchar rtc_read (short reg)
{
	return in8(RTC(reg));
}

static void rtc_write (short reg, uchar val)
{
	out8(RTC(reg),val);
}

#else
# error Board specific rtc access functions should be supplied
#endif

/* ------------------------------------------------------------------------- */

void *nvram_read(void *dest, const short src, size_t count)
{
	uchar *d = (uchar *) dest;
	short s = src;

	while (count--)
		*d++ = rtc_read(s++);

	return dest;
}

void nvram_write(short dest, const void *src, size_t count)
{
	short d = dest;
	uchar *s = (uchar *) src;

	while (count--)
		rtc_write(d++, *s++);
}

#if defined(CONFIG_CMD_DATE)

/* ------------------------------------------------------------------------- */

int rtc_get (struct rtc_time *tmp)
{
	uchar save_ctrl_a;
	uchar sec, min, hour, mday, wday, mon, year;

	/* Simple: freeze the clock, read it and allow updates again */
	save_ctrl_a = rtc_read(RTC_CONTROLA);

	/* Set the register to read the value. */
	save_ctrl_a |= RTC_CA_READ;
	rtc_write(RTC_CONTROLA, save_ctrl_a);

	sec		= rtc_read (RTC_SECONDS);
	min		= rtc_read (RTC_MINUTES);
	hour	= rtc_read (RTC_HOURS);
	mday	= rtc_read (RTC_DAY_OF_MONTH);
	wday	= rtc_read (RTC_DAY_OF_WEEK);
	mon		= rtc_read (RTC_MONTH);
	year	= rtc_read (RTC_YEAR);

	/* re-enable update */
	save_ctrl_a &= ~RTC_CA_READ;
	rtc_write(RTC_CONTROLA, save_ctrl_a);

#ifdef RTC_DEBUG
	printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
		"hr: %02x min: %02x sec: %02x\n",
		year, mon, mday, wday,
		hour, min, sec );
#endif
	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
	tmp->tm_min  = bcd2bin (min  & 0x7F);
	tmp->tm_hour = bcd2bin (hour & 0x3F);
	tmp->tm_mday = bcd2bin (mday & 0x3F);
	tmp->tm_mon  = bcd2bin (mon & 0x1F);
	tmp->tm_year = bcd2bin (year);
	tmp->tm_wday = bcd2bin (wday & 0x07);
	if(tmp->tm_year<70)
		tmp->tm_year+=2000;
	else
		tmp->tm_year+=1900;
	tmp->tm_yday = 0;
	tmp->tm_isdst= 0;
#ifdef RTC_DEBUG
	printf ( "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);
#endif

	return 0;
}

int rtc_set (struct rtc_time *tmp)
{
	uchar save_ctrl_a;

#ifdef RTC_DEBUG
	printf ( "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);
#endif
	save_ctrl_a = rtc_read(RTC_CONTROLA);

	save_ctrl_a |= RTC_CA_WRITE;
	rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */

	rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
	rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));

	rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
	rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
	rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
	rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
	rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));

	save_ctrl_a &= ~RTC_CA_WRITE;
	rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */

	return 0;
}

void rtc_reset (void)
{
	uchar control_b;

	/*
	 * Start oscillator here.
	 */
	control_b = rtc_read(RTC_CONTROLB);

	control_b &= ~RTC_CB_STOP;
	rtc_write(RTC_CONTROLB, control_b);
}

void rtc_set_watchdog(short multi, short res)
{
	uchar wd_value;

	wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
	rtc_write(RTC_WATCHDOG, wd_value);
}

#endif
