/*
 * 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 (CFG_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");
	}
}

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

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

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
