Commit 71d19f30d6a55926ac81e86558a15701f9dbc17c
Committed by
Wolfgang Denk
1 parent
31e413985c
Exists in
master
and in
54 other branches
rtc, rv3029: add trickle charger support.
Signed-off-by: Heiko Schocher <hs@denx.de> Acked-by: Detlev Zundel <dzu@denx.de>
Showing 2 changed files with 89 additions and 0 deletions Side-by-side Diff
README
... | ... | @@ -748,6 +748,8 @@ |
748 | 748 | CONFIG_RTC_ISL1208 - use Intersil ISL1208 RTC |
749 | 749 | CONFIG_RTC_MAX6900 - use Maxim, Inc. MAX6900 RTC |
750 | 750 | CONFIG_SYS_RTC_DS1337_NOOSC - Turn off the OSC output for DS1337 |
751 | + CONFIG_SYS_RV3029_TCR - enable trickle charger on | |
752 | + RV3029 RTC. | |
751 | 753 | |
752 | 754 | Note that if the RTC uses I2C, then the I2C interface |
753 | 755 | must also be configured. See I2C Support, below. |
drivers/rtc/rv3029.c
... | ... | @@ -25,6 +25,12 @@ |
25 | 25 | #include <i2c.h> |
26 | 26 | #include <rtc.h> |
27 | 27 | |
28 | +#define RTC_RV3029_CTRL1 0x00 | |
29 | +#define RTC_RV3029_CTRL1_EERE (1 << 3) | |
30 | + | |
31 | +#define RTC_RV3029_CTRL_STATUS 0x03 | |
32 | +#define RTC_RV3029_CTRLS_EEBUSY (1 << 7) | |
33 | + | |
28 | 34 | #define RTC_RV3029_CTRL_RESET 0x04 |
29 | 35 | #define RTC_RV3029_CTRL_SYS_R (1 << 4) |
30 | 36 | |
... | ... | @@ -42,6 +48,12 @@ |
42 | 48 | #define RV3029C2_REG_HR_12_24 (1 << 6) /* 24h/12h mode */ |
43 | 49 | #define RV3029C2_REG_HR_PM (1 << 5) /* PM/AM bit in 12h mode */ |
44 | 50 | |
51 | +#define RTC_RV3029_EEPROM_CTRL 0x30 | |
52 | +#define RTC_RV3029_TRICKLE_1K (1 << 4) | |
53 | +#define RTC_RV3029_TRICKLE_5K (1 << 5) | |
54 | +#define RTC_RV3029_TRICKLE_20K (1 << 6) | |
55 | +#define RTC_RV3029_TRICKLE_80K (1 << 7) | |
56 | + | |
45 | 57 | int rtc_get( struct rtc_time *tmp ) |
46 | 58 | { |
47 | 59 | int ret; |
... | ... | @@ -113,6 +125,41 @@ |
113 | 125 | return 0; |
114 | 126 | } |
115 | 127 | |
128 | +/* sets EERE-Bit (automatic EEPROM refresh) */ | |
129 | +static void set_eere_bit(int state) | |
130 | +{ | |
131 | + int ret; | |
132 | + unsigned char reg_ctrl1; | |
133 | + | |
134 | + ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1, | |
135 | + ®_ctrl1, 1); | |
136 | + | |
137 | + if (state) | |
138 | + reg_ctrl1 |= RTC_RV3029_CTRL1_EERE; | |
139 | + else | |
140 | + reg_ctrl1 &= (~RTC_RV3029_CTRL1_EERE); | |
141 | + | |
142 | + ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1, | |
143 | + ®_ctrl1, 1); | |
144 | +} | |
145 | + | |
146 | +/* waits until EEPROM page is no longer busy (times out after 10ms*loops) */ | |
147 | +static int wait_eebusy(int loops) | |
148 | +{ | |
149 | + int i, ret; | |
150 | + unsigned char ctrl_status; | |
151 | + | |
152 | + for (i = 0; i < loops; i++) { | |
153 | + ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_STATUS, | |
154 | + 1, &ctrl_status, 1); | |
155 | + | |
156 | + if ((ctrl_status & RTC_RV3029_CTRLS_EEBUSY) == 0) | |
157 | + break; | |
158 | + udelay(10000); | |
159 | + } | |
160 | + return i; | |
161 | +} | |
162 | + | |
116 | 163 | void rtc_reset (void) |
117 | 164 | { |
118 | 165 | int ret; |
... | ... | @@ -121,5 +168,45 @@ |
121 | 168 | buf[0] = RTC_RV3029_CTRL_SYS_R; |
122 | 169 | ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_RESET, 1, |
123 | 170 | buf, 1); |
171 | + | |
172 | +#if defined(CONFIG_SYS_RV3029_TCR) | |
173 | + /* | |
174 | + * because EEPROM_CTRL register is in EEPROM page it is necessary to | |
175 | + * disable automatic EEPROM refresh and check if EEPROM is busy | |
176 | + * before EEPORM_CTRL register may be accessed | |
177 | + */ | |
178 | + set_eere_bit(0); | |
179 | + wait_eebusy(100); | |
180 | + /* read current trickle charger setting */ | |
181 | + ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_EEPROM_CTRL, | |
182 | + 1, buf, 1); | |
183 | + /* enable automatic EEPROM refresh again */ | |
184 | + set_eere_bit(1); | |
185 | + | |
186 | + /* | |
187 | + * to minimize EEPROM access write trickle charger setting only if it | |
188 | + * differs from current value | |
189 | + */ | |
190 | + if ((buf[0] & 0xF0) != CONFIG_SYS_RV3029_TCR) { | |
191 | + buf[0] = (buf[0] & 0x0F) | CONFIG_SYS_RV3029_TCR; | |
192 | + /* | |
193 | + * write trickle charger setting (disable autom. EEPROM | |
194 | + * refresh and wait until EEPROM is idle) | |
195 | + */ | |
196 | + set_eere_bit(0); | |
197 | + wait_eebusy(100); | |
198 | + ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, | |
199 | + RTC_RV3029_EEPROM_CTRL, 1, buf, 1); | |
200 | + /* | |
201 | + * it is necessary to wait 10ms before EEBUSY-Bit may be read | |
202 | + * (this is not documented in the data sheet yet, but the | |
203 | + * manufacturer recommends it) | |
204 | + */ | |
205 | + udelay(10000); | |
206 | + /* wait until EEPROM write access is finished */ | |
207 | + wait_eebusy(100); | |
208 | + set_eere_bit(1); | |
209 | + } | |
210 | +#endif | |
124 | 211 | } |