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#include <common.h>
34#include <command.h>
35#include <rtc.h>
36#include <i2c.h>
37
38#if defined(CONFIG_CMD_DATE)
39
40
41#undef DEBUG_RTC
42#define DEBUG_RTC
43
44#ifdef DEBUG_RTC
45#define DEBUGR(fmt,args...) printf(fmt ,##args)
46#else
47#define DEBUGR(fmt,args...)
48#endif
49
50
51#ifndef CONFIG_SYS_I2C_RTC_ADDR
52# define CONFIG_SYS_I2C_RTC_ADDR 0x68
53#endif
54
55#if defined(CONFIG_RTC_DS1374) && (CONFIG_SYS_I2C_SPEED > 400000)
56# error The DS1374 is specified up to 400kHz in fast mode!
57#endif
58
59
60
61
62#define RTC_TOD_CNT_BYTE0_ADDR 0x00
63#define RTC_TOD_CNT_BYTE1_ADDR 0x01
64#define RTC_TOD_CNT_BYTE2_ADDR 0x02
65#define RTC_TOD_CNT_BYTE3_ADDR 0x03
66
67#define RTC_WD_ALM_CNT_BYTE0_ADDR 0x04
68#define RTC_WD_ALM_CNT_BYTE1_ADDR 0x05
69#define RTC_WD_ALM_CNT_BYTE2_ADDR 0x06
70
71#define RTC_CTL_ADDR 0x07
72#define RTC_SR_ADDR 0x08
73#define RTC_TCS_DS_ADDR 0x09
74
75#define RTC_CTL_BIT_AIE (1<<0)
76#define RTC_CTL_BIT_RS1 (1<<1)
77#define RTC_CTL_BIT_RS2 (1<<2)
78#define RTC_CTL_BIT_WDSTR (1<<3)
79#define RTC_CTL_BIT_BBSQW (1<<4)
80#define RTC_CTL_BIT_WD_ALM (1<<5)
81#define RTC_CTL_BIT_WACE (1<<6)
82#define RTC_CTL_BIT_EN_OSC (1<<7)
83
84#define RTC_SR_BIT_AF 0x01
85#define RTC_SR_BIT_OSF 0x80
86
87typedef unsigned char boolean_t;
88
89#ifndef TRUE
90#define TRUE ((boolean_t)(0==0))
91#endif
92#ifndef FALSE
93#define FALSE (!TRUE)
94#endif
95
96const char RtcTodAddr[] = {
97 RTC_TOD_CNT_BYTE0_ADDR,
98 RTC_TOD_CNT_BYTE1_ADDR,
99 RTC_TOD_CNT_BYTE2_ADDR,
100 RTC_TOD_CNT_BYTE3_ADDR
101};
102
103static uchar rtc_read (uchar reg);
104static void rtc_write (uchar reg, uchar val, boolean_t set);
105static void rtc_write_raw (uchar reg, uchar val);
106
107
108
109
110int rtc_get (struct rtc_time *tm){
111 int rel = 0;
112 unsigned long time1, time2;
113 unsigned int limit;
114 unsigned char tmp;
115 unsigned int i;
116
117
118
119
120
121
122 limit = 10;
123 do {
124 i = 4;
125 time1 = 0;
126 while (i--) {
127 tmp = rtc_read(RtcTodAddr[i]);
128 time1 = (time1 << 8) | (tmp & 0xff);
129 }
130
131 i = 4;
132 time2 = 0;
133 while (i--) {
134 tmp = rtc_read(RtcTodAddr[i]);
135 time2 = (time2 << 8) | (tmp & 0xff);
136 }
137 } while ((time1 != time2) && limit--);
138
139 if (time1 != time2) {
140 printf("can't get consistent time from rtc chip\n");
141 rel = -1;
142 }
143
144 DEBUGR ("Get RTC s since 1.1.1970: %ld\n", time1);
145
146 to_tm(time1, tm);
147
148 if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF) {
149 printf ("### Warning: RTC oscillator has stopped\n");
150 rel = -1;
151 }
152
153 DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
154 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
155 tm->tm_hour, tm->tm_min, tm->tm_sec);
156
157 return rel;
158}
159
160
161
162
163int rtc_set (struct rtc_time *tmp){
164
165 unsigned long time;
166 unsigned i;
167
168 DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
169 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
170 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
171
172 if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
173 printf("WARNING: year should be between 1970 and 2069!\n");
174
175 time = mktime(tmp->tm_year, tmp->tm_mon,
176 tmp->tm_mday, tmp->tm_hour,
177 tmp->tm_min, tmp->tm_sec);
178
179 DEBUGR ("Set RTC s since 1.1.1970: %ld (0x%02lx)\n", time, time);
180
181
182 for (i = 0; i <= 3; i++) {
183 rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff));
184 time = time >> 8;
185 }
186
187
188 rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, FALSE);
189
190 return 0;
191}
192
193
194
195
196
197
198
199
200void rtc_reset (void){
201
202 struct rtc_time tmp;
203
204
205 rtc_write (RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), FALSE);
206
207
208 rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC
209 |RTC_CTL_BIT_WACE
210 |RTC_CTL_BIT_AIE), FALSE);
211
212 rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM
213 |RTC_CTL_BIT_WDSTR
214 |RTC_CTL_BIT_RS1
215 |RTC_CTL_BIT_RS2
216 |RTC_CTL_BIT_BBSQW), TRUE);
217
218
219 tmp.tm_year = 1970;
220 tmp.tm_mon = 1;
221 tmp.tm_mday= 1;
222 tmp.tm_hour = 0;
223 tmp.tm_min = 0;
224 tmp.tm_sec = 0;
225
226 rtc_set(&tmp);
227
228 printf("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n",
229 tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
230 tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
231
232 rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAC, TRUE);
233 rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR,0xDE, TRUE);
234 rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAD, TRUE);
235}
236
237
238
239
240static uchar rtc_read (uchar reg)
241{
242 return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
243}
244
245static void rtc_write (uchar reg, uchar val, boolean_t set)
246{
247 if (set == TRUE) {
248 val |= i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg);
249 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
250 } else {
251 val = i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg) & ~val;
252 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
253 }
254}
255
256static void rtc_write_raw (uchar reg, uchar val)
257{
258 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
259}
260#endif
261