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