]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/etin/debris/phantom.c
4 * Phantom RTC device driver for EVA
9 * Copyright 2002 Etinsys Inc.
11 * SPDX-License-Identifier: GPL-2.0+
18 #if defined(CONFIG_CMD_DATE)
20 #define RTC_BASE (CONFIG_SYS_NVRAM_BASE_ADDR + 0x7fff8)
22 #define RTC_YEAR ( RTC_BASE + 7 )
23 #define RTC_MONTH ( RTC_BASE + 6 )
24 #define RTC_DAY_OF_MONTH ( RTC_BASE + 5 )
25 #define RTC_DAY_OF_WEEK ( RTC_BASE + 4 )
26 #define RTC_HOURS ( RTC_BASE + 3 )
27 #define RTC_MINUTES ( RTC_BASE + 2 )
28 #define RTC_SECONDS ( RTC_BASE + 1 )
29 #define RTC_CENTURY ( RTC_BASE + 0 )
31 #define RTC_CONTROLA RTC_CENTURY
32 #define RTC_CONTROLB RTC_SECONDS
33 #define RTC_CONTROLC RTC_DAY_OF_WEEK
35 #define RTC_CA_WRITE 0x80
36 #define RTC_CA_READ 0x40
38 #define RTC_CB_OSC_DISABLE 0x80
40 #define RTC_CC_BATTERY_FLAG 0x80
41 #define RTC_CC_FREQ_TEST 0x40
44 static int phantom_flag
= -1;
45 static int century_flag
= -1;
47 static uchar
rtc_read(unsigned int addr
)
49 return *(volatile unsigned char *)(addr
);
52 static void rtc_write(unsigned int addr
, uchar val
)
54 *(volatile unsigned char *)(addr
) = val
;
57 static unsigned char phantom_rtc_sequence
[] = {
58 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
61 static unsigned char* phantom_rtc_read(int addr
, unsigned char rtc
[8])
65 unsigned char save
= rtc_read(addr
);
67 for (j
= 0; j
< 8; j
++) {
68 v
= phantom_rtc_sequence
[j
];
69 for (i
= 0; i
< 8; i
++) {
70 rtc_write(addr
, v
& 1);
74 for (j
= 0; j
< 8; j
++) {
76 for (i
= 0; i
< 8; i
++) {
77 if(rtc_read(addr
) & 1)
82 rtc_write(addr
, save
);
86 static void phantom_rtc_write(int addr
, unsigned char rtc
[8])
90 unsigned char save
= rtc_read(addr
);
91 for (j
= 0; j
< 8; j
++) {
92 v
= phantom_rtc_sequence
[j
];
93 for (i
= 0; i
< 8; i
++) {
94 rtc_write(addr
, v
& 1);
98 for (j
= 0; j
< 8; j
++) {
100 for (i
= 0; i
< 8; i
++) {
101 rtc_write(addr
, v
& 1);
105 rtc_write(addr
, save
);
108 static int get_phantom_flag(void)
111 unsigned char rtc
[8];
113 phantom_rtc_read(RTC_BASE
, rtc
);
115 for(i
= 1; i
< 8; i
++) {
116 if (rtc
[i
] != rtc
[0])
124 if (phantom_flag
< 0)
125 phantom_flag
= get_phantom_flag();
128 unsigned char rtc
[8];
129 phantom_rtc_read(RTC_BASE
, rtc
);
131 printf( "real-time-clock was stopped. Now starting...\n" );
133 phantom_rtc_write(RTC_BASE
, rtc
);
136 uchar reg_a
, reg_b
, reg_c
;
137 reg_a
= rtc_read( RTC_CONTROLA
);
138 reg_b
= rtc_read( RTC_CONTROLB
);
140 if ( reg_b
& RTC_CB_OSC_DISABLE
)
142 printf( "real-time-clock was stopped. Now starting...\n" );
143 reg_a
|= RTC_CA_WRITE
;
144 reg_b
&= ~RTC_CB_OSC_DISABLE
;
145 rtc_write( RTC_CONTROLA
, reg_a
);
146 rtc_write( RTC_CONTROLB
, reg_b
);
149 /* make sure read/write clock register bits are cleared */
150 reg_a
&= ~( RTC_CA_WRITE
| RTC_CA_READ
);
151 rtc_write( RTC_CONTROLA
, reg_a
);
153 reg_c
= rtc_read( RTC_CONTROLC
);
154 if (( reg_c
& RTC_CC_BATTERY_FLAG
) == 0 )
155 printf( "RTC battery low. Clock setting may not be reliable.\n");
159 static int get_century_flag(void)
163 bcd
= rtc_read( RTC_CENTURY
);
164 century
= bcd2bin( bcd
& 0x3F );
165 rtc_write( RTC_CENTURY
, bin2bcd(century
+1));
166 if (bcd
== rtc_read( RTC_CENTURY
))
168 rtc_write( RTC_CENTURY
, bcd
);
172 int rtc_get( struct rtc_time
*tmp
)
174 if (phantom_flag
< 0)
175 phantom_flag
= get_phantom_flag();
179 unsigned char rtc
[8];
181 phantom_rtc_read(RTC_BASE
, rtc
);
183 tmp
->tm_sec
= bcd2bin(rtc
[1] & 0x7f);
184 tmp
->tm_min
= bcd2bin(rtc
[2] & 0x7f);
185 tmp
->tm_hour
= bcd2bin(rtc
[3] & 0x1f);
186 tmp
->tm_wday
= bcd2bin(rtc
[4] & 0x7);
187 tmp
->tm_mday
= bcd2bin(rtc
[5] & 0x3f);
188 tmp
->tm_mon
= bcd2bin(rtc
[6] & 0x1f);
189 tmp
->tm_year
= bcd2bin(rtc
[7]) + 1900;
193 if( (rtc
[3] & 0x80) && (rtc
[3] & 0x40) ) tmp
->tm_hour
+= 12;
194 if (tmp
->tm_year
< 1970) tmp
->tm_year
+= 100;
196 uchar sec
, min
, hour
;
197 uchar mday
, wday
, mon
, year
;
203 if (century_flag
< 0)
204 century_flag
= get_century_flag();
206 reg_a
= rtc_read( RTC_CONTROLA
);
207 /* lock clock registers for read */
208 rtc_write( RTC_CONTROLA
, ( reg_a
| RTC_CA_READ
));
210 sec
= rtc_read( RTC_SECONDS
);
211 min
= rtc_read( RTC_MINUTES
);
212 hour
= rtc_read( RTC_HOURS
);
213 mday
= rtc_read( RTC_DAY_OF_MONTH
);
214 wday
= rtc_read( RTC_DAY_OF_WEEK
);
215 mon
= rtc_read( RTC_MONTH
);
216 year
= rtc_read( RTC_YEAR
);
217 century
= rtc_read( RTC_CENTURY
);
219 /* unlock clock registers after read */
220 rtc_write( RTC_CONTROLA
, ( reg_a
& ~RTC_CA_READ
));
222 tmp
->tm_sec
= bcd2bin( sec
& 0x7F );
223 tmp
->tm_min
= bcd2bin( min
& 0x7F );
224 tmp
->tm_hour
= bcd2bin( hour
& 0x3F );
225 tmp
->tm_mday
= bcd2bin( mday
& 0x3F );
226 tmp
->tm_mon
= bcd2bin( mon
& 0x1F );
227 tmp
->tm_wday
= bcd2bin( wday
& 0x07 );
230 tmp
->tm_year
= bcd2bin( year
) +
231 ( bcd2bin( century
& 0x3F ) * 100 );
233 tmp
->tm_year
= bcd2bin( year
) + 1900;
234 if (tmp
->tm_year
< 1970) tmp
->tm_year
+= 100;
244 int rtc_set( struct rtc_time
*tmp
)
246 if (phantom_flag
< 0)
247 phantom_flag
= get_phantom_flag();
251 unsigned char rtc
[8];
254 year
-= (year
< 2000) ? 1900 : 2000;
257 rtc
[1] = bin2bcd(tmp
->tm_sec
);
258 rtc
[2] = bin2bcd(tmp
->tm_min
);
259 rtc
[3] = bin2bcd(tmp
->tm_hour
);
260 rtc
[4] = bin2bcd(tmp
->tm_wday
);
261 rtc
[5] = bin2bcd(tmp
->tm_mday
);
262 rtc
[6] = bin2bcd(tmp
->tm_mon
);
263 rtc
[7] = bin2bcd(year
);
265 phantom_rtc_write(RTC_BASE
, rtc
);
268 if (century_flag
< 0)
269 century_flag
= get_century_flag();
271 /* lock clock registers for write */
272 reg_a
= rtc_read( RTC_CONTROLA
);
273 rtc_write( RTC_CONTROLA
, ( reg_a
| RTC_CA_WRITE
));
275 rtc_write( RTC_MONTH
, bin2bcd( tmp
->tm_mon
));
277 rtc_write( RTC_DAY_OF_WEEK
, bin2bcd( tmp
->tm_wday
));
278 rtc_write( RTC_DAY_OF_MONTH
, bin2bcd( tmp
->tm_mday
));
279 rtc_write( RTC_HOURS
, bin2bcd( tmp
->tm_hour
));
280 rtc_write( RTC_MINUTES
, bin2bcd( tmp
->tm_min
));
281 rtc_write( RTC_SECONDS
, bin2bcd( tmp
->tm_sec
));
283 /* break year up into century and year in century */
285 rtc_write( RTC_YEAR
, bin2bcd( tmp
->tm_year
% 100 ));
286 rtc_write( RTC_CENTURY
, bin2bcd( tmp
->tm_year
/ 100 ));
288 reg_a
|= bin2bcd( tmp
->tm_year
/ 100 );
290 rtc_write(RTC_YEAR
, bin2bcd(tmp
->tm_year
-
291 ((tmp
->tm_year
< 2000) ? 1900 : 2000)));
294 /* unlock clock registers after read */
295 rtc_write( RTC_CONTROLA
, ( reg_a
& ~RTC_CA_WRITE
));