Blame view

drivers/rtc/rx8025.c 5.04 KB
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
1
2
3
4
  /*
   * (C) Copyright 2007
   * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
6
7
8
9
10
11
12
13
14
15
   */
  
  /*
   * Epson RX8025 RTC driver.
   */
  
  #include <common.h>
  #include <command.h>
  #include <rtc.h>
  #include <i2c.h>
871c18dd3   Michal Simek   rtc: Clean driver...
16
  #if defined(CONFIG_CMD_DATE)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
17
18
19
20
21
22
23
24
25
26
  
  /*---------------------------------------------------------------------*/
  #undef DEBUG_RTC
  
  #ifdef DEBUG_RTC
  #define DEBUGR(fmt,args...) printf(fmt ,##args)
  #else
  #define DEBUGR(fmt,args...)
  #endif
  /*---------------------------------------------------------------------*/
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
27
28
  #ifndef CONFIG_SYS_I2C_RTC_ADDR
  # define CONFIG_SYS_I2C_RTC_ADDR	0x32
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  #endif
  
  /*
   * RTC register addresses
   */
  #define RTC_SEC_REG_ADDR	0x00
  #define RTC_MIN_REG_ADDR	0x01
  #define RTC_HR_REG_ADDR		0x02
  #define RTC_DAY_REG_ADDR	0x03
  #define RTC_DATE_REG_ADDR	0x04
  #define RTC_MON_REG_ADDR	0x05
  #define RTC_YR_REG_ADDR		0x06
  
  #define RTC_CTL1_REG_ADDR	0x0e
  #define RTC_CTL2_REG_ADDR	0x0f
  
  /*
   * Control register 1 bits
   */
  #define RTC_CTL1_BIT_2412	0x20
  
  /*
   * Control register 2 bits
   */
  #define RTC_CTL2_BIT_PON	0x10
  #define RTC_CTL2_BIT_VDET	0x40
  #define RTC_CTL2_BIT_XST	0x20
  #define RTC_CTL2_BIT_VDSL	0x80
  
  /*
   * Note: the RX8025 I2C RTC requires register
   * reads and write to consist of a single bus
   * cycle. It is not allowed to write the register
   * address in a first cycle that is terminated by
   * a STOP condition. The chips needs a 'restart'
   * sequence (start sequence without a prior stop).
   * This driver has been written for a 4xx board.
   * U-Boot's 4xx i2c driver is currently not capable
   * to generate such cycles to some work arounds
   * are used.
   */
  
  /* static uchar rtc_read (uchar reg); */
  #define rtc_read(reg) buf[((reg) + 1) & 0xf]
  
  static void rtc_write (uchar reg, uchar val);
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
75
76
77
78
  
  /*
   * Get the current time from the RTC
   */
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
79
  int rtc_get (struct rtc_time *tmp)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
80
  {
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
81
  	int rel = 0;
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
82
83
  	uchar sec, min, hour, mday, wday, mon, year, ctl2;
  	uchar buf[16];
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
84
  	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 16))
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  		printf("Error reading from RTC
  ");
  
  	sec = rtc_read(RTC_SEC_REG_ADDR);
  	min = rtc_read(RTC_MIN_REG_ADDR);
  	hour = rtc_read(RTC_HR_REG_ADDR);
  	wday = rtc_read(RTC_DAY_REG_ADDR);
  	mday = rtc_read(RTC_DATE_REG_ADDR);
  	mon = rtc_read(RTC_MON_REG_ADDR);
  	year = rtc_read(RTC_YR_REG_ADDR);
  
  	DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
  		"hr: %02x min: %02x sec: %02x
  ",
  		year, mon, mday, wday, hour, min, sec);
  
  	/* dump status */
  	ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
103
  	if (ctl2 & RTC_CTL2_BIT_PON) {
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
104
105
  		printf("RTC: power-on detected
  ");
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
106
107
  		rel = -1;
  	}
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
108

b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
109
  	if (ctl2 & RTC_CTL2_BIT_VDET) {
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
110
111
  		printf("RTC: voltage drop detected
  ");
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
112
113
  		rel = -1;
  	}
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
114

b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
115
  	if (!(ctl2 & RTC_CTL2_BIT_XST)) {
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
116
117
  		printf("RTC: oscillator stop detected
  ");
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
118
119
  		rel = -1;
  	}
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
120
121
122
  
  	tmp->tm_sec  = bcd2bin (sec & 0x7F);
  	tmp->tm_min  = bcd2bin (min & 0x7F);
5875d358f   Yuri Tikhonov   RX 8025 RTC: anal...
123
124
125
126
127
  	if (rtc_read(RTC_CTL1_REG_ADDR) & RTC_CTL1_BIT_2412)
  		tmp->tm_hour = bcd2bin (hour & 0x3F);
  	else
  		tmp->tm_hour = bcd2bin (hour & 0x1F) % 12 +
  			       ((hour & 0x20) ? 12 : 0);
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
128
129
130
131
132
133
134
135
136
137
138
  	tmp->tm_mday = bcd2bin (mday & 0x3F);
  	tmp->tm_mon  = bcd2bin (mon & 0x1F);
  	tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
  	tmp->tm_wday = bcd2bin (wday & 0x07);
  	tmp->tm_yday = 0;
  	tmp->tm_isdst= 0;
  
  	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d
  ",
  		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
  		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
139
140
  
  	return rel;
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
141
  }
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
142
143
144
  /*
   * Set the RTC
   */
d1e231941   Jean-Christophe PLAGNIOL-VILLARD   rtc: allow rtc_se...
145
  int rtc_set (struct rtc_time *tmp)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  {
  	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d
  ",
  		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
  		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
  
  	if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
  		printf("WARNING: year should be between 1970 and 2069!
  ");
  
  	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
  	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
  	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday));
  	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
  	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
  	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
  	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
  
  	rtc_write (RTC_CTL1_REG_ADDR, RTC_CTL1_BIT_2412);
d1e231941   Jean-Christophe PLAGNIOL-VILLARD   rtc: allow rtc_se...
165
166
  
  	return 0;
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
167
  }
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
168
169
170
171
172
173
174
175
  /*
   * Reset the RTC. We setting the date back to 1970-01-01.
   */
  void rtc_reset (void)
  {
  	struct rtc_time tmp;
  	uchar buf[16];
  	uchar ctl2;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
176
  	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0,    0,   buf, 16))
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  		printf("Error reading from RTC
  ");
  
  	ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
  	ctl2 &= ~(RTC_CTL2_BIT_PON | RTC_CTL2_BIT_VDET);
  	ctl2 |= RTC_CTL2_BIT_XST | RTC_CTL2_BIT_VDSL;
  	rtc_write (RTC_CTL2_REG_ADDR, ctl2);
  
  	tmp.tm_year = 1970;
  	tmp.tm_mon = 1;
  	tmp.tm_mday= 1;
  	tmp.tm_hour = 0;
  	tmp.tm_min = 0;
  	tmp.tm_sec = 0;
  
  	rtc_set(&tmp);
  
  	printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC
  ",
  		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
  		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
  
  	return;
  }
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
201
202
203
204
205
206
207
208
  /*
   * Helper functions
   */
  static void rtc_write (uchar reg, uchar val)
  {
  	uchar buf[2];
  	buf[0] = reg << 4;
  	buf[1] = val;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
209
  	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 2) != 0)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
210
211
212
213
  		printf("Error writing to RTC
  ");
  
  }
1b7698817   Jean-Christophe PLAGNIOL-VILLARD   Fix remaining CON...
214
  #endif /* CONFIG_RTC_RX8025 && CONFIG_CMD_DATE */