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