/*
 * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
 *
 * Rex G. Feany <rfeany@zumanetworks.com>
 *
 */

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

#if defined(CONFIG_RTC_DS1302) && defined(CONFIG_CMD_DATE)

/* GPP Pins */
#define DATA		0x200
#define SCLK		0x400
#define RST		0x800

/* Happy Fun Defines(tm) */
#define RESET		rtc_go_low(RST), rtc_go_low(SCLK)
#define N_RESET		rtc_go_high(RST), rtc_go_low(SCLK)

#define CLOCK_HIGH	rtc_go_high(SCLK)
#define CLOCK_LOW	rtc_go_low(SCLK)

#define DATA_HIGH	rtc_go_high(DATA)
#define DATA_LOW	rtc_go_low(DATA)
#define DATA_READ	(GTREGREAD(GPP_VALUE) & DATA)

#undef RTC_DEBUG

#ifdef RTC_DEBUG
#  define DPRINTF(x,args...)	printf("ds1302: " x , ##args)
static inline void DUMP(const char *ptr, int num)
{
	while (num--) printf("%x ", *ptr++);
	printf("]\n");
}
#else
#  define DPRINTF(x,args...)
#  define DUMP(ptr, num)
#endif

/* time data format for DS1302 */
struct ds1302_st
{
	unsigned char CH:1;		/* clock halt 1=stop 0=start */
	unsigned char sec10:3;
	unsigned char sec:4;

	unsigned char zero0:1;
	unsigned char min10:3;
	unsigned char min:4;

	unsigned char fmt:1;		/* 1=12 hour 0=24 hour */
	unsigned char zero1:1;
	unsigned char hr10:2;	/* 10 (0-2) or am/pm (am/pm, 0-1) */
	unsigned char hr:4;

	unsigned char zero2:2;
	unsigned char date10:2;
	unsigned char date:4;

	unsigned char zero3:3;
	unsigned char month10:1;
	unsigned char month:4;

	unsigned char zero4:5;
	unsigned char day:3; 		/* day of week */

	unsigned char year10:4;
	unsigned char year:4;

	unsigned char WP:1;		/* write protect 1=protect 0=unprot */
	unsigned char zero5:7;
};

static int ds1302_initted=0;

/* Pin control */
static inline void
rtc_go_high(unsigned int mask)
{
	unsigned int f = GTREGREAD(GPP_VALUE) | mask;

	GT_REG_WRITE(GPP_VALUE, f);
}

static inline void
rtc_go_low(unsigned int mask)
{
	unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;

	GT_REG_WRITE(GPP_VALUE, f);
}

static inline void
rtc_go_input(unsigned int mask)
{
	unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;

	GT_REG_WRITE(GPP_IO_CONTROL, f);
}

static inline void
rtc_go_output(unsigned int mask)
{
	unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;

	GT_REG_WRITE(GPP_IO_CONTROL, f);
}

/* Access data in RTC */

static void
write_byte(unsigned char b)
{
	int i;
	unsigned char mask=1;

	for(i=0;i<8;i++) {
		CLOCK_LOW;			/* Lower clock */
		(b&mask)?DATA_HIGH:DATA_LOW;	/* set data */
		udelay(1);
		CLOCK_HIGH;		/* latch data with rising clock */
		udelay(1);
		mask=mask<<1;
	}
}

static unsigned char
read_byte(void)
{
	int i;
	unsigned char mask=1;
	unsigned char b=0;

	for(i=0;i<8;i++) {
		CLOCK_LOW;
		udelay(1);
		if (DATA_READ) b|=mask;	/* if this bit is high, set in b */
		CLOCK_HIGH;		/* clock out next bit */
		udelay(1);
		mask=mask<<1;
	}
	return b;
}

static void
read_ser_drv(unsigned char addr, unsigned char *buf, int count)
{
	int i;
#ifdef RTC_DEBUG
	char *foo = buf;
#endif

	DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);

	addr|=1;	/* READ */
	N_RESET;
	udelay(4);
	write_byte(addr);
	rtc_go_input(DATA); /* Put gpp pin into input mode */
	udelay(1);
	for(i=0;i<count;i++) *(buf++)=read_byte();
	RESET;
	rtc_go_output(DATA);/* Reset gpp for output */
	udelay(4);

	DUMP(foo, count);
}

static void
write_ser_drv(unsigned char addr, unsigned char *buf, int count)
{
	int i;

	DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
	DUMP(buf, count);

	addr&=~1;	/* WRITE */
	N_RESET;
	udelay(4);
	write_byte(addr);
	for(i=0;i<count;i++) write_byte(*(buf++));
	RESET;
	udelay(4);

}

void
rtc_init(void)
{
    	struct ds1302_st bbclk;
	unsigned char b;
	int mod;

	DPRINTF("init\n");

	rtc_go_output(DATA|SCLK|RST);

	/* disable write protect */
	b = 0;
	write_ser_drv(0x8e,&b,1);

	/* enable trickle */
	b = 0xa5;	/* 1010.0101 */
	write_ser_drv(0x90,&b,1);

	/* read burst */
	read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);

	/* Sanity checks */
	mod = 0;
	if (bbclk.CH) {
		printf("ds1302: Clock was halted, starting clock\n");
		bbclk.CH=0;
		mod=1;
	}

	if (bbclk.fmt) {
		printf("ds1302: Clock was in 12 hour mode, fixing\n");
		bbclk.fmt=0;
		mod=1;
	}

	if (bbclk.year>9) {
		printf("ds1302: Year was corrupted, fixing\n");
		bbclk.year10=100/10;	/* 2000 - why not? ;) */
		bbclk.year=0;
		mod=1;
	}

	/* Write out the changes if needed */
	if (mod) {
		/* enable write protect */
		bbclk.WP = 1;
		write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
	} else {
		/* Else just turn write protect on */
		b = 0x80;
		write_ser_drv(0x8e,&b,1);
	}
	DPRINTF("init done\n");

	ds1302_initted=1;
}

void
rtc_reset(void)
{
	if(!ds1302_initted) rtc_init();
	/* TODO */
}

void
rtc_get(struct rtc_time *tmp)
{
	struct ds1302_st bbclk;

	if(!ds1302_initted) rtc_init();

	read_ser_drv(0xbe,(unsigned char *)&bbclk, 8);      /* read burst */

	if (bbclk.CH) {
		printf("ds1302: rtc_get: Clock was halted, clock probably "
			"corrupt\n");
	}

	tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
	tmp->tm_min=10*bbclk.min10+bbclk.min;
	tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
	tmp->tm_wday=bbclk.day;
	tmp->tm_mday=10*bbclk.date10+bbclk.date;
	tmp->tm_mon=10*bbclk.month10+bbclk.month;
	tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;

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

	DPRINTF("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)
{
	struct ds1302_st bbclk;
	unsigned char b=0;

	if(!ds1302_initted) rtc_init();

	DPRINTF("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);

	memset(&bbclk,0,sizeof(bbclk));
	bbclk.CH=0; /* dont halt */
	bbclk.WP=1; /* write protect when we're done */

	bbclk.sec10=tmp->tm_sec/10;
	bbclk.sec=tmp->tm_sec%10;

	bbclk.min10=tmp->tm_min/10;
	bbclk.min=tmp->tm_min%10;

	bbclk.hr10=tmp->tm_hour/10;
	bbclk.hr=tmp->tm_hour%10;

	bbclk.day=tmp->tm_wday;

	bbclk.date10=tmp->tm_mday/10;
	bbclk.date=tmp->tm_mday%10;

	bbclk.month10=tmp->tm_mon/10;
	bbclk.month=tmp->tm_mon%10;

	tmp->tm_year -= 1900;
	bbclk.year10=tmp->tm_year/10;
	bbclk.year=tmp->tm_year%10;

	write_ser_drv(0x8e,&b,1);           /* disable write protect */
	write_ser_drv(0xbe,(unsigned char *)&bbclk, 8);     /* write burst */
}

#endif
