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