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#include <common.h>
31#include <command.h>
32#include <rtc.h>
33
34#if defined(CONFIG_CMD_DATE)
35
36static uchar rtc_read (uchar reg);
37static void rtc_write (uchar reg, uchar val);
38static uchar bin2bcd (unsigned int n);
39static unsigned bcd2bin(uchar c);
40
41#define RTC_PORT_MC146818 CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x70
42#define RTC_SECONDS 0x00
43#define RTC_SECONDS_ALARM 0x01
44#define RTC_MINUTES 0x02
45#define RTC_MINUTES_ALARM 0x03
46#define RTC_HOURS 0x04
47#define RTC_HOURS_ALARM 0x05
48#define RTC_DAY_OF_WEEK 0x06
49#define RTC_DATE_OF_MONTH 0x07
50#define RTC_MONTH 0x08
51#define RTC_YEAR 0x09
52#define RTC_CONFIG_A 0x0A
53#define RTC_CONFIG_B 0x0B
54#define RTC_CONFIG_C 0x0C
55#define RTC_CONFIG_D 0x0D
56
57
58
59
60int rtc_get (struct rtc_time *tmp)
61{
62 uchar sec, min, hour, mday, wday, mon, year;
63
64 while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
65 sec = rtc_read (RTC_SECONDS);
66 min = rtc_read (RTC_MINUTES);
67 hour = rtc_read (RTC_HOURS);
68 mday = rtc_read (RTC_DATE_OF_MONTH);
69 wday = rtc_read (RTC_DAY_OF_WEEK);
70 mon = rtc_read (RTC_MONTH);
71 year = rtc_read (RTC_YEAR);
72#ifdef CONFIG_AMIGAONEG3SE
73 wday -= 1;
74#endif
75#ifdef RTC_DEBUG
76 printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
77 "hr: %02x min: %02x sec: %02x\n",
78 year, mon, mday, wday,
79 hour, min, sec );
80 printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
81 rtc_read (RTC_CONFIG_D) & 0x3F,
82 rtc_read (RTC_HOURS_ALARM),
83 rtc_read (RTC_MINUTES_ALARM),
84 rtc_read (RTC_SECONDS_ALARM) );
85#endif
86 tmp->tm_sec = bcd2bin (sec & 0x7F);
87 tmp->tm_min = bcd2bin (min & 0x7F);
88 tmp->tm_hour = bcd2bin (hour & 0x3F);
89 tmp->tm_mday = bcd2bin (mday & 0x3F);
90 tmp->tm_mon = bcd2bin (mon & 0x1F);
91 tmp->tm_year = bcd2bin (year);
92 tmp->tm_wday = bcd2bin (wday & 0x07);
93 if(tmp->tm_year<70)
94 tmp->tm_year+=2000;
95 else
96 tmp->tm_year+=1900;
97 tmp->tm_yday = 0;
98 tmp->tm_isdst= 0;
99#ifdef RTC_DEBUG
100 printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
101 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
102 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
103#endif
104
105 return 0;
106}
107
108int rtc_set (struct rtc_time *tmp)
109{
110#ifdef RTC_DEBUG
111 printf ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
112 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
113 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
114#endif
115 rtc_write(RTC_CONFIG_B,0x82);
116
117 rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
118 rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
119#ifdef CONFIG_AMIGAONEG3SE
120 rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1);
121#else
122 rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
123#endif
124 rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
125 rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
126 rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
127 rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
128 rtc_write(RTC_CONFIG_B,0x02);
129
130 return 0;
131}
132
133void rtc_reset (void)
134{
135 rtc_write(RTC_CONFIG_B,0x82);
136 rtc_write(RTC_CONFIG_A,0x20);
137 rtc_write(RTC_CONFIG_B,0x00);
138 rtc_write(RTC_CONFIG_B,0x00);
139 rtc_write(RTC_CONFIG_B,0x02);
140}
141
142
143
144#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR
145
146
147
148static uchar rtc_read (uchar reg)
149{
150 return(in8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg));
151}
152
153static void rtc_write (uchar reg, uchar val)
154{
155 out8(CONFIG_SYS_RTC_REG_BASE_ADDR+reg, val);
156}
157#else
158static uchar rtc_read (uchar reg)
159{
160 out8(RTC_PORT_MC146818,reg);
161 return(in8(RTC_PORT_MC146818+1));
162}
163
164static void rtc_write (uchar reg, uchar val)
165{
166 out8(RTC_PORT_MC146818,reg);
167 out8(RTC_PORT_MC146818+1,val);
168}
169#endif
170
171static unsigned bcd2bin (uchar n)
172{
173 return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
174}
175
176static unsigned char bin2bcd (unsigned int n)
177{
178 return (((n / 10) << 4) | (n % 10));
179}
180
181#endif
182