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#include <common.h>
35#include <command.h>
36#include <rtc.h>
37#include <spi.h>
38
39#if defined(CONFIG_CMD_DATE)
40
41#define RTC_SECONDS 0x00
42#define RTC_MINUTES 0x01
43#define RTC_HOURS 0x02
44#define RTC_DAY_OF_WEEK 0x03
45#define RTC_DATE_OF_MONTH 0x04
46#define RTC_MONTH 0x05
47#define RTC_YEAR 0x06
48
49#define RTC_SECONDS_ALARM0 0x07
50#define RTC_MINUTES_ALARM0 0x08
51#define RTC_HOURS_ALARM0 0x09
52#define RTC_DAY_OF_WEEK_ALARM0 0x0a
53
54#define RTC_SECONDS_ALARM1 0x0b
55#define RTC_MINUTES_ALARM1 0x0c
56#define RTC_HOURS_ALARM1 0x0d
57#define RTC_DAY_OF_WEEK_ALARM1 0x0e
58
59#define RTC_CONTROL 0x0f
60#define RTC_STATUS 0x10
61#define RTC_TRICKLE_CHARGER 0x11
62
63#define RTC_USER_RAM_BASE 0x20
64
65static unsigned int bin2bcd (unsigned int n);
66static unsigned char bcd2bin (unsigned char c);
67
68
69#ifdef CONFIG_SXNI855T
70
71static void soft_spi_send (unsigned char n);
72static unsigned char soft_spi_read (void);
73static void init_spi (void);
74
75
76
77
78
79#define PB_SPISCK 0x00000002
80#define PB_SPIMOSI 0x00000004
81#define PB_SPIMISO 0x00000008
82#define PB_SPI_CE 0x00010000
83
84
85
86
87int rtc_get (struct rtc_time *tmp)
88{
89 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
90 unsigned char spi_byte;
91
92 init_spi ();
93
94
95 immap->im_cpm.cp_pbdat |= PB_SPI_CE;
96 udelay (10);
97
98
99 soft_spi_send (0);
100
101
102 tmp->tm_sec = bcd2bin (soft_spi_read ());
103 tmp->tm_min = bcd2bin (soft_spi_read ());
104
105
106 spi_byte = soft_spi_read ();
107 if (spi_byte & 0x40) {
108
109 if (spi_byte & 0x20) {
110
111 tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
112 } else {
113
114 tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
115 }
116 } else {
117
118 tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
119 }
120
121 soft_spi_read ();
122 tmp->tm_mday = bcd2bin (soft_spi_read ());
123 tmp->tm_mon = bcd2bin (soft_spi_read ());
124
125
126 tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
127
128
129 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
130 udelay (10);
131
132 GregorianDay (tmp);
133
134 debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
135 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
136 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
137
138 return 0;
139}
140
141
142
143
144int rtc_set (struct rtc_time *tmp)
145{
146 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
147
148 init_spi ();
149
150
151 immap->im_cpm.cp_pbdat |= PB_SPI_CE;
152 udelay (10);
153
154
155 soft_spi_send (0x8F);
156 soft_spi_send (0x00);
157
158
159 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
160 udelay (10);
161
162
163 immap->im_cpm.cp_pbdat |= PB_SPI_CE;
164 udelay (10);
165
166
167 soft_spi_send (0x80);
168
169
170 bin2bcd (tmp->tm_sec);
171 soft_spi_send (bin2bcd (tmp->tm_sec));
172 soft_spi_send (bin2bcd (tmp->tm_min));
173 soft_spi_send (bin2bcd (tmp->tm_hour));
174 soft_spi_send (bin2bcd (tmp->tm_wday));
175 soft_spi_send (bin2bcd (tmp->tm_mday));
176 soft_spi_send (bin2bcd (tmp->tm_mon));
177 soft_spi_send (bin2bcd (tmp->tm_year - 2000));
178
179
180 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
181 udelay (10);
182
183
184 immap->im_cpm.cp_pbdat |= PB_SPI_CE;
185 udelay (10);
186
187
188 soft_spi_send (0x8F);
189 soft_spi_send (0x40);
190
191
192 immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
193 udelay (10);
194
195
196
197
198
199 {
200 ulong tim;
201
202 tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
203 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
204
205 immap->im_sitk.sitk_rtck = KAPWR_KEY;
206 immap->im_sit.sit_rtc = tim;
207 }
208
209 debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
210 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
211 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
212
213 return 0;
214}
215
216
217
218
219static void init_spi (void)
220{
221 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
222
223
224 immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
225
226
227 immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
228
229 immap->im_cpm.cp_pbdir &= ~PB_SPIMISO;
230 udelay (10);
231}
232
233
234
235
236static void soft_spi_send (unsigned char n)
237{
238 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
239 unsigned char bitpos;
240 unsigned char i;
241
242
243 bitpos = 0x80;
244
245
246 for (i = 0; i < 8; i++) {
247 immap->im_cpm.cp_pbdat |= PB_SPISCK;
248
249 if (n & bitpos)
250 immap->im_cpm.cp_pbdat |= PB_SPIMOSI;
251 else
252 immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI;
253 udelay (10);
254
255 immap->im_cpm.cp_pbdat &= ~PB_SPISCK;
256 udelay (10);
257
258 bitpos >>= 1;
259 }
260}
261
262
263
264
265static unsigned char soft_spi_read (void)
266{
267 volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
268
269 unsigned char spi_byte = 0;
270 unsigned char bitpos;
271 unsigned char i;
272
273
274 bitpos = 0x80;
275
276
277 for (i = 0; i < 8; i++) {
278 immap->im_cpm.cp_pbdat |= PB_SPISCK;
279 udelay (10);
280 if (immap->im_cpm.cp_pbdat & PB_SPIMISO)
281 spi_byte |= bitpos;
282 immap->im_cpm.cp_pbdat &= ~PB_SPISCK;
283 udelay (10);
284 bitpos >>= 1;
285 }
286
287 return spi_byte;
288}
289
290
291
292void rtc_reset (void)
293{
294 return;
295}
296
297#else
298
299
300static unsigned char rtc_read (unsigned char reg);
301static void rtc_write (unsigned char reg, unsigned char val);
302
303static struct spi_slave *slave;
304
305
306int rtc_get (struct rtc_time *tmp)
307{
308 unsigned char sec, min, hour, mday, wday, mon, year;
309
310
311
312
313
314
315
316 if (!slave) {
317 slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
318 SPI_MODE_3 | SPI_CS_HIGH);
319 if (!slave)
320 return;
321 }
322
323 if (spi_claim_bus(slave))
324 return;
325
326 sec = rtc_read (RTC_SECONDS);
327 min = rtc_read (RTC_MINUTES);
328 hour = rtc_read (RTC_HOURS);
329 mday = rtc_read (RTC_DATE_OF_MONTH);
330 wday = rtc_read (RTC_DAY_OF_WEEK);
331 mon = rtc_read (RTC_MONTH);
332 year = rtc_read (RTC_YEAR);
333
334 spi_release_bus(slave);
335
336 debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
337 "hr: %02x min: %02x sec: %02x\n",
338 year, mon, mday, wday, hour, min, sec);
339 debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
340 rtc_read (RTC_DAY_OF_WEEK_ALARM0),
341 rtc_read (RTC_HOURS_ALARM0),
342 rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
343 debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
344 rtc_read (RTC_DAY_OF_WEEK_ALARM1),
345 rtc_read (RTC_HOURS_ALARM1),
346 rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
347
348 tmp->tm_sec = bcd2bin (sec & 0x7F);
349 tmp->tm_min = bcd2bin (min & 0x7F);
350
351
352 tmp->tm_hour = (hour & 0x40)
353 ? ((hour & 0x20)
354 ? bcd2bin (hour & 0x1F) + 11
355 : bcd2bin (hour & 0x1F) - 1
356 )
357 : bcd2bin (hour & 0x3F);
358
359 tmp->tm_mday = bcd2bin (mday & 0x3F);
360 tmp->tm_mon = bcd2bin (mon & 0x1F);
361 tmp->tm_year = bcd2bin (year) + 2000;
362 tmp->tm_wday = bcd2bin (wday & 0x07) - 1;
363 tmp->tm_yday = 0;
364 tmp->tm_isdst = 0;
365
366 debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
367 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
368 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
369
370 return 0;
371}
372
373
374
375
376int rtc_set (struct rtc_time *tmp)
377{
378
379 if (!slave) {
380 slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
381 SPI_MODE_3 | SPI_CS_HIGH);
382 if (!slave)
383 return;
384 }
385
386 if (spi_claim_bus(slave))
387 return;
388
389 debug ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
390 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
391 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
392
393 rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
394 rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
395 rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
396 rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
397 rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
398 rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
399 rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
400
401 spi_release_bus(slave);
402}
403
404
405
406
407void rtc_reset (void)
408{
409
410 if (!slave) {
411 slave = spi_setup_slave(0, CONFIG_SYS_SPI_RTC_DEVID, 600000,
412 SPI_MODE_3 | SPI_CS_HIGH);
413 if (!slave)
414 return;
415 }
416
417 if (spi_claim_bus(slave))
418 return;
419
420
421 rtc_write (RTC_CONTROL, 0x00);
422 rtc_write (RTC_CONTROL, 0x00);
423
424
425 rtc_write (RTC_SECONDS_ALARM0, 0x00);
426 rtc_write (RTC_SECONDS_ALARM1, 0x00);
427 rtc_write (RTC_MINUTES_ALARM0, 0x00);
428 rtc_write (RTC_MINUTES_ALARM1, 0x00);
429 rtc_write (RTC_HOURS_ALARM0, 0x00);
430 rtc_write (RTC_HOURS_ALARM1, 0x00);
431 rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
432 rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
433
434 spi_release_bus(slave);
435}
436
437
438
439static unsigned char rtc_read (unsigned char reg)
440{
441 int ret;
442
443 ret = spi_w8r8(slave, reg);
444 return ret < 0 ? 0 : ret;
445}
446
447
448
449static void rtc_write (unsigned char reg, unsigned char val)
450{
451 unsigned char dout[2];
452 unsigned char din[2];
453
454 dout[0] = 0x80 | reg;
455 dout[1] = val;
456
457 spi_xfer (slave, 16, dout, din, SPI_XFER_BEGIN | SPI_XFER_END);
458}
459
460#endif
461
462
463
464static unsigned char bcd2bin (unsigned char n)
465{
466 return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
467}
468
469
470
471static unsigned int bin2bcd (unsigned int n)
472{
473 return (((n / 10) << 4) | (n % 10));
474}
475
476
477#endif
478