/*
 * 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;
}

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

#endif
