summaryrefslogtreecommitdiffstats
path: root/arch/mips/sni/ds1216.c
blob: 1d92732c14f16ae9c6cf6257c1693a49cd23b0ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

#include <linux/bcd.h>
#include <linux/time.h>

#include <asm/ds1216.h>

volatile unsigned char *ds1216_base;

/*
 * Read the 64 bit we'd like to have - It a series
 * of 64 bits showing up in the LSB of the base register.
 *
 */
static unsigned char *ds1216_read(void)
{
	static unsigned char	rdbuf[8];
	unsigned char		c;
	int			i, j;

	for (i = 0; i < 8; i++) {
		c = 0x0;
		for (j = 0; j < 8; j++) {
			c |= (*ds1216_base & 0x1) << j;
		}
		rdbuf[i] = c;
	}

	return rdbuf;
}

static void ds1216_switch_ds_to_clock(void)
{
	unsigned char magic[] = {
		0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
	};
	int i,j,c;

	/* Reset magic pointer */
	c = *ds1216_base;

	/* Write 64 bit magic to DS1216 */
	for (i = 0; i < 8; i++) {
		c = magic[i];
		for (j = 0; j < 8; j++) {
			*ds1216_base = c;
			c = c >> 1;
		}
	}
}

unsigned long ds1216_get_cmos_time(void)
{
	unsigned char	*rdbuf;
	unsigned int	year, month, date, hour, min, sec;

	ds1216_switch_ds_to_clock();
	rdbuf = ds1216_read();

	sec = BCD2BIN(DS1216_SEC(rdbuf));
	min = BCD2BIN(DS1216_MIN(rdbuf));
	hour = BCD2BIN(DS1216_HOUR(rdbuf));
	date = BCD2BIN(DS1216_DATE(rdbuf));
	month = BCD2BIN(DS1216_MONTH(rdbuf));
	year = BCD2BIN(DS1216_YEAR(rdbuf));

	if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
		hour+=12;

	if (year < 70)
		year += 2000;
	else
		year += 1900;

	return mktime(year, month, date, hour, min, sec);
}

int ds1216_set_rtc_mmss(unsigned long nowtime)
{
	printk("ds1216_set_rtc_mmss called but not implemented\n");
	return -1;
}