/*
 * 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) && (CONFIG_COMMANDS & CFG_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
