/*
 * board/eva/phantom.c
 *
 * Phantom RTC device driver for EVA
 *
 * Author: Sangmoon Kim
 *         dogoil@etinsys.com
 *
 * Copyright 2002 Etinsys Inc.
 *
 * 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.
 */

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

#if defined(CONFIG_CMD_DATE)

#define RTC_BASE (CONFIG_SYS_NVRAM_BASE_ADDR + 0x7fff8)

#define RTC_YEAR                ( RTC_BASE + 7 )
#define RTC_MONTH               ( RTC_BASE + 6 )
#define RTC_DAY_OF_MONTH        ( RTC_BASE + 5 )
#define RTC_DAY_OF_WEEK         ( RTC_BASE + 4 )
#define RTC_HOURS               ( RTC_BASE + 3 )
#define RTC_MINUTES             ( RTC_BASE + 2 )
#define RTC_SECONDS             ( RTC_BASE + 1 )
#define RTC_CENTURY             ( RTC_BASE + 0 )

#define RTC_CONTROLA            RTC_CENTURY
#define RTC_CONTROLB            RTC_SECONDS
#define RTC_CONTROLC            RTC_DAY_OF_WEEK

#define RTC_CA_WRITE            0x80
#define RTC_CA_READ             0x40

#define RTC_CB_OSC_DISABLE      0x80

#define RTC_CC_BATTERY_FLAG     0x80
#define RTC_CC_FREQ_TEST        0x40


static int phantom_flag = -1;
static int century_flag = -1;

static uchar rtc_read(unsigned int addr)
{
	return *(volatile unsigned char *)(addr);
}

static void rtc_write(unsigned int addr, uchar val)
{
	*(volatile unsigned char *)(addr) = val;
}

static unsigned char phantom_rtc_sequence[] = {
	0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
};

static unsigned char* phantom_rtc_read(int addr, unsigned char rtc[8])
{
	int i, j;
	unsigned char v;
	unsigned char save = rtc_read(addr);

	for (j = 0; j < 8; j++) {
		v = phantom_rtc_sequence[j];
		for (i = 0; i < 8; i++) {
			rtc_write(addr, v & 1);
			v >>= 1;
		}
	}
	for (j = 0; j < 8; j++) {
		v = 0;
		for (i = 0; i < 8; i++) {
			if(rtc_read(addr) & 1)
				v |= 1 << i;
		}
		rtc[j] = v;
	}
	rtc_write(addr, save);
	return rtc;
}

static void phantom_rtc_write(int addr, unsigned char rtc[8])
{
	int i, j;
	unsigned char v;
	unsigned char save = rtc_read(addr);
	for (j = 0; j < 8; j++) {
		v = phantom_rtc_sequence[j];
		for (i = 0; i < 8; i++) {
			rtc_write(addr, v & 1);
			v >>= 1;
		}
	}
	for (j = 0; j < 8; j++) {
		v = rtc[j];
		for (i = 0; i < 8; i++) {
			rtc_write(addr, v & 1);
			v >>= 1;
		}
	}
	rtc_write(addr, save);
}

static int get_phantom_flag(void)
{
	int i;
	unsigned char rtc[8];

	phantom_rtc_read(RTC_BASE, rtc);

	for(i = 1; i < 8; i++) {
		if (rtc[i] != rtc[0])
			return 1;
	}
	return 0;
}

void rtc_reset(void)
{
	if (phantom_flag < 0)
		phantom_flag = get_phantom_flag();

	if (phantom_flag) {
		unsigned char rtc[8];
		phantom_rtc_read(RTC_BASE, rtc);
		if(rtc[4] & 0x30) {
			printf( "real-time-clock was stopped. Now starting...\n" );
			rtc[4] &= 0x07;
			phantom_rtc_write(RTC_BASE, rtc);
		}
	} else {
		uchar reg_a, reg_b, reg_c;
		reg_a = rtc_read( RTC_CONTROLA );
		reg_b = rtc_read( RTC_CONTROLB );

		if ( reg_b & RTC_CB_OSC_DISABLE )
		{
			printf( "real-time-clock was stopped. Now starting...\n" );
			reg_a |= RTC_CA_WRITE;
			reg_b &= ~RTC_CB_OSC_DISABLE;
			rtc_write( RTC_CONTROLA, reg_a );
			rtc_write( RTC_CONTROLB, reg_b );
		}

		/* make sure read/write clock register bits are cleared */
		reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
		rtc_write( RTC_CONTROLA, reg_a );

		reg_c = rtc_read( RTC_CONTROLC );
		if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
			printf( "RTC battery low. Clock setting may not be reliable.\n");
	}
}

static int get_century_flag(void)
{
	int flag = 0;
	int bcd, century;
	bcd = rtc_read( RTC_CENTURY );
	century = bcd2bin( bcd & 0x3F );
	rtc_write( RTC_CENTURY, bin2bcd(century+1));
	if (bcd == rtc_read( RTC_CENTURY ))
		flag = 1;
	rtc_write( RTC_CENTURY, bcd);
	return flag;
}

int rtc_get( struct rtc_time *tmp)
{
	if (phantom_flag < 0)
		phantom_flag = get_phantom_flag();

	if (phantom_flag)
	{
		unsigned char rtc[8];

		phantom_rtc_read(RTC_BASE, rtc);

		tmp->tm_sec	= bcd2bin(rtc[1] & 0x7f);
		tmp->tm_min	= bcd2bin(rtc[2] & 0x7f);
		tmp->tm_hour	= bcd2bin(rtc[3] & 0x1f);
		tmp->tm_wday	= bcd2bin(rtc[4] & 0x7);
		tmp->tm_mday	= bcd2bin(rtc[5] & 0x3f);
		tmp->tm_mon	= bcd2bin(rtc[6] & 0x1f);
		tmp->tm_year	= bcd2bin(rtc[7]) + 1900;
		tmp->tm_yday = 0;
		tmp->tm_isdst = 0;

		if( (rtc[3] & 0x80)  && (rtc[3] & 0x40) ) tmp->tm_hour += 12;
		if (tmp->tm_year < 1970) tmp->tm_year += 100;
	} else {
		uchar sec, min, hour;
		uchar mday, wday, mon, year;

		int century;

		uchar reg_a;

		if (century_flag < 0)
			century_flag = get_century_flag();

		reg_a = rtc_read( RTC_CONTROLA );
		/* lock clock registers for read */
		rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));

		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 );
		century = rtc_read( RTC_CENTURY );

		/* unlock clock registers after read */
		rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));

		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_wday = bcd2bin( wday & 0x07 );

		if (century_flag) {
			tmp->tm_year = bcd2bin( year ) +
				( bcd2bin( century & 0x3F ) * 100 );
		} else {
			tmp->tm_year = bcd2bin( year ) + 1900;
			if (tmp->tm_year < 1970) tmp->tm_year += 100;
		}

		tmp->tm_yday = 0;
		tmp->tm_isdst= 0;
	}

	return 0;
}

int rtc_set( struct rtc_time *tmp )
{
	if (phantom_flag < 0)
		phantom_flag = get_phantom_flag();

	if (phantom_flag) {
		uint year;
		unsigned char rtc[8];

		year = tmp->tm_year;
		year -= (year < 2000) ? 1900 : 2000;

		rtc[0] = bin2bcd(0);
		rtc[1] = bin2bcd(tmp->tm_sec);
		rtc[2] = bin2bcd(tmp->tm_min);
		rtc[3] = bin2bcd(tmp->tm_hour);
		rtc[4] = bin2bcd(tmp->tm_wday);
		rtc[5] = bin2bcd(tmp->tm_mday);
		rtc[6] = bin2bcd(tmp->tm_mon);
		rtc[7] = bin2bcd(year);

		phantom_rtc_write(RTC_BASE, rtc);
	} else {
		uchar reg_a;
		if (century_flag < 0)
			century_flag = get_century_flag();

		/* lock clock registers for write */
		reg_a = rtc_read( RTC_CONTROLA );
		rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));

		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 ));

		/* break year up into century and year in century */
		if (century_flag) {
			rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
			rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
			reg_a &= 0xc0;
			reg_a |= bin2bcd( tmp->tm_year / 100 );
		} else {
			rtc_write(RTC_YEAR, bin2bcd(tmp->tm_year -
				((tmp->tm_year < 2000) ? 1900 : 2000)));
		}

		/* unlock clock registers after read */
		rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
	}

	return 0;
}

#endif
