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

int
rtc_get(struct rtc_time *tmp)
{
	int rel = 0;
	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");
		rel = -1;
	}

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

	return rel;
}

int 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 */

	return 0;
}

#endif
