Blame view

drivers/rtc/rx8025.c 4.63 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
2
3
4
  /*
   * (C) Copyright 2007
   * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
5
6
7
8
9
10
11
12
13
14
   */
  
  /*
   * Epson RX8025 RTC driver.
   */
  
  #include <common.h>
  #include <command.h>
  #include <rtc.h>
  #include <i2c.h>
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
15
16
17
18
19
20
21
22
23
  /*---------------------------------------------------------------------*/
  #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...
24
25
  #ifndef CONFIG_SYS_I2C_RTC_ADDR
  # define CONFIG_SYS_I2C_RTC_ADDR	0x32
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
26
27
28
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
  #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 ...
72
73
74
75
  
  /*
   * Get the current time from the RTC
   */
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
76
  int rtc_get (struct rtc_time *tmp)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
77
  {
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
78
  	int rel = 0;
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
79
80
  	uchar sec, min, hour, mday, wday, mon, year, ctl2;
  	uchar buf[16];
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
81
  	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 16))
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  		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
100
  	if (ctl2 & RTC_CTL2_BIT_PON) {
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
101
102
  		printf("RTC: power-on detected
  ");
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
103
104
  		rel = -1;
  	}
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
105

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

b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
112
  	if (!(ctl2 & RTC_CTL2_BIT_XST)) {
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
113
114
  		printf("RTC: oscillator stop detected
  ");
b73a19e16   Yuri Tikhonov   LWMON5: POST RTC fix
115
116
  		rel = -1;
  	}
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
117
118
119
  
  	tmp->tm_sec  = bcd2bin (sec & 0x7F);
  	tmp->tm_min  = bcd2bin (min & 0x7F);
5875d358f   Yuri Tikhonov   RX 8025 RTC: anal...
120
121
122
123
124
  	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 ...
125
126
127
128
129
130
131
132
133
134
135
  	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
136
137
  
  	return rel;
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
138
  }
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
139
140
141
  /*
   * Set the RTC
   */
d1e231941   Jean-Christophe PLAGNIOL-VILLARD   rtc: allow rtc_se...
142
  int rtc_set (struct rtc_time *tmp)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  {
  	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...
162
163
  
  	return 0;
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
164
  }
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
165
  /*
402c8fd51   Chris Packham   rtc: rx8025: remo...
166
   * Reset the RTC
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
167
168
169
   */
  void rtc_reset (void)
  {
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
170
171
  	uchar buf[16];
  	uchar ctl2;
6d0f6bcf3   Jean-Christophe PLAGNIOL-VILLARD   rename CFG_ macro...
172
  	if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0,    0,   buf, 16))
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
173
174
175
176
177
178
179
  		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);
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
180
  }
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
181
182
183
184
185
186
187
188
  /*
   * 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...
189
  	if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 2) != 0)
95c6bc7d4   Matthias Fuchs   Add Epson RX8025 ...
190
191
192
193
  		printf("Error writing to RTC
  ");
  
  }