]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/rtc/rs5c372.c
4 * Device driver for Ricoh's Real Time Controller RS5C372A.
6 * Copyright (C) 2004 Gary Jennejohn garyj@denx.de
8 * Based in part in ds1307.c -
9 * (C) Copyright 2001, 2002, 2003
10 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
11 * Keith Outwater, keith_outwater@mvis.com`
12 * Steven Scholz, steven.scholz@imc-berlin.de
14 * See file CREDITS for list of people who contributed to this
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
27 #if defined(CONFIG_CMD_DATE)
29 * Reads are always done starting with register 15, which requires some
30 * jumping-through-hoops to access the data correctly.
32 * Writes are always done starting with register 0.
38 static unsigned int rtc_debug
= DEBUG
;
40 #define rtc_debug 0 /* gcc will remove all the debug code for us */
43 #ifndef CONFIG_SYS_I2C_RTC_ADDR
44 #define CONFIG_SYS_I2C_RTC_ADDR 0x32
47 #define RS5C372_RAM_SIZE 0x10
48 #define RATE_32000HZ 0x80 /* Rate Select 32.000KHz */
49 #define RATE_32768HZ 0x00 /* Rate Select 32.768KHz */
51 #define STATUS_XPT 0x10 /* data invalid because voltage was 0 */
53 #define USE_24HOUR_MODE 0x20
54 #define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
55 #define HOURS_AP(n) (((n) >> 5) & 1)
56 #define HOURS_12(n) bcd2bin((n) & 0x1F)
57 #define HOURS_24(n) bcd2bin((n) & 0x3F)
60 static int setup_done
= 0;
63 rs5c372_readram(unsigned char *buf
, int len
)
67 ret
= i2c_read(CONFIG_SYS_I2C_RTC_ADDR
, 0, 0, buf
, len
);
69 printf("%s: failed to read\n", __FUNCTION__
);
73 if (buf
[0] & STATUS_XPT
)
74 printf("### Warning: RTC lost power\n");
82 unsigned char buf
[RS5C372_RAM_SIZE
+ 1];
85 /* note that this returns reg. 15 in buf[1] */
86 ret
= rs5c372_readram(&buf
[1], RS5C372_RAM_SIZE
);
88 printf("%s: failed\n", __FUNCTION__
);
93 /* we want to start writing at register 0 so we have to copy the */
94 /* register contents up one slot */
95 for (ret
= 2; ret
< 9; ret
++)
96 buf
[ret
- 1] = buf
[ret
];
97 /* registers 0 to 6 (time values) are not touched */
98 buf
[8] = RATE_32768HZ
; /* reg. 7 */
99 buf
[9] = 0; /* reg. 8 */
100 buf
[10] = 0; /* reg. 9 */
101 buf
[11] = 0; /* reg. 10 */
102 buf
[12] = 0; /* reg. 11 */
103 buf
[13] = 0; /* reg. 12 */
104 buf
[14] = 0; /* reg. 13 */
105 buf
[15] = 0; /* reg. 14 */
106 buf
[16] = USE_24HOUR_MODE
; /* reg. 15 */
107 ret
= i2c_write(CONFIG_SYS_I2C_RTC_ADDR
, 0, 0, buf
, RS5C372_RAM_SIZE
+1);
109 printf("%s: failed\n", __FUNCTION__
);
118 rs5c372_convert_to_time(struct rtc_time
*dt
, unsigned char *buf
)
120 /* buf[0] is register 15 */
121 dt
->tm_sec
= bcd2bin(buf
[1]);
122 dt
->tm_min
= bcd2bin(buf
[2]);
124 if (TWELVE_HOUR_MODE(buf
[0])) {
125 dt
->tm_hour
= HOURS_12(buf
[3]);
126 if (HOURS_AP(buf
[3])) /* PM */
128 } else /* 24-hour-mode */
129 dt
->tm_hour
= HOURS_24(buf
[3]);
131 dt
->tm_mday
= bcd2bin(buf
[5]);
132 dt
->tm_mon
= bcd2bin(buf
[6]);
133 dt
->tm_year
= bcd2bin(buf
[7]);
134 if (dt
->tm_year
>= 70)
139 dt
->tm_wday
= bcd2bin(buf
[4] & 0x07);
144 printf("rs5c372_convert_to_time: year = %d\n", dt
->tm_year
);
145 printf("rs5c372_convert_to_time: mon = %d\n", dt
->tm_mon
);
146 printf("rs5c372_convert_to_time: mday = %d\n", dt
->tm_mday
);
147 printf("rs5c372_convert_to_time: hour = %d\n", dt
->tm_hour
);
148 printf("rs5c372_convert_to_time: min = %d\n", dt
->tm_min
);
149 printf("rs5c372_convert_to_time: sec = %d\n", dt
->tm_sec
);
154 * Get the current time from the RTC
157 rtc_get (struct rtc_time
*tmp
)
159 unsigned char buf
[RS5C372_RAM_SIZE
];
168 memset(buf
, 0, sizeof(buf
));
170 /* note that this returns reg. 15 in buf[0] */
171 ret
= rs5c372_readram(buf
, RS5C372_RAM_SIZE
);
173 printf("%s: failed\n", __FUNCTION__
);
177 rs5c372_convert_to_time(tmp
, buf
);
185 int rtc_set (struct rtc_time
*tmp
)
187 unsigned char buf
[8], reg15
;
197 printf("rtc_set: tm_year = %d\n", tmp
->tm_year
);
198 printf("rtc_set: tm_mon = %d\n", tmp
->tm_mon
);
199 printf("rtc_set: tm_mday = %d\n", tmp
->tm_mday
);
200 printf("rtc_set: tm_hour = %d\n", tmp
->tm_hour
);
201 printf("rtc_set: tm_min = %d\n", tmp
->tm_min
);
202 printf("rtc_set: tm_sec = %d\n", tmp
->tm_sec
);
205 memset(buf
, 0, sizeof(buf
));
207 /* only read register 15 */
208 ret
= i2c_read(CONFIG_SYS_I2C_RTC_ADDR
, 0, 0, buf
, 1);
211 /* need to save register 15 */
213 buf
[0] = 0; /* register address on RS5C372 */
214 buf
[1] = bin2bcd(tmp
->tm_sec
);
215 buf
[2] = bin2bcd(tmp
->tm_min
);
216 /* need to handle 12 hour mode */
217 if (TWELVE_HOUR_MODE(reg15
)) {
218 if (tmp
->tm_hour
>= 12) { /* PM */
219 /* 12 PM is a special case */
220 if (tmp
->tm_hour
== 12)
221 buf
[3] = bin2bcd(tmp
->tm_hour
);
223 buf
[3] = bin2bcd(tmp
->tm_hour
- 12);
227 buf
[3] = bin2bcd(tmp
->tm_hour
);
230 buf
[4] = bin2bcd(tmp
->tm_wday
);
231 buf
[5] = bin2bcd(tmp
->tm_mday
);
232 buf
[6] = bin2bcd(tmp
->tm_mon
);
233 if (tmp
->tm_year
< 1970 || tmp
->tm_year
> 2069)
234 printf("WARNING: year should be between 1970 and 2069!\n");
235 buf
[7] = bin2bcd(tmp
->tm_year
% 100);
237 ret
= i2c_write(CONFIG_SYS_I2C_RTC_ADDR
, 0, 0, buf
, 8);
239 printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret
);
250 * Reset the RTC. We set the date back to 1970-01-01.
265 /* Jan. 1, 1970 was a Thursday */
274 printf ("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n",
275 tmp
.tm_year
, tmp
.tm_mon
, tmp
.tm_mday
,
276 tmp
.tm_hour
, tmp
.tm_min
, tmp
.tm_sec
);