1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
27 #if CONFIG_RTC == RTC_E8564
28 #include "i2c-pp5020.h"
29 #endif /*CONFIG_RTC == RTC_E8564*/
33 #define RTC_DEV_WRITE (RTC_ADR | 0x00)
34 #define RTC_DEV_READ (RTC_ADR | 0x01)
36 #if CONFIG_RTC == RTC_E8564
41 int rtc_read_datetime(unsigned char* buf
)
46 /*RTC_E8564's slave address is 0x51*/
47 read
= i2c_readbytes(0x51,0x02,7,buf
);
49 /* swap wday and mday to be compatible with
50 * get_time() from firmware/common/timefuncs.c */
58 int rtc_write_datetime(unsigned char* buf
)
63 /* swap wday and mday to be compatible with
64 * set_time() in firmware/common/timefuncs.c */
70 ipod_i2c_send(0x51, 0x02+i
,buf
[i
]);
75 #elif CONFIG_RTC == RTC_PCF50605
80 int rtc_read_datetime(unsigned char* buf
)
82 return pcf50605_read_multiple(0x0a, buf
, 7);
85 int rtc_write_datetime(unsigned char* buf
)
90 pcf50605_write(0x0a+i
, buf
[i
]);
95 #elif CONFIG_RTC == RTC_PCF50606
100 int rtc_read_datetime(unsigned char* buf
) {
102 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
104 rc
= pcf50606_read_multiple(0x0a, buf
, 7);
106 set_irq_level(oldlevel
);
110 int rtc_write_datetime(unsigned char* buf
) {
112 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
114 rc
= pcf50606_write_multiple(0x0a, buf
, 7);
116 set_irq_level(oldlevel
);
126 #ifdef HAVE_ALARM_MOD
127 /* Check + save alarm bit first, before the power thread starts watching */
128 rtc_check_alarm_started(false);
131 rtc_write(0x13, 0x10); /* 32 kHz square wave */
133 /* Clear the Stop bit if it is set */
134 data
= rtc_read(0x01);
136 rtc_write(0x01, 0x00);
138 /* Clear the HT bit if it is set */
139 data
= rtc_read(0x0c);
144 rtc_write(0x0c,data
);
147 #ifdef HAVE_ALARM_MOD
149 /* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */
150 /* without this, the alarm won't work! */
152 data
= rtc_read(0x04);
156 rtc_write(0x04, data
);
159 /* Also, make sure that the OUT bit in register 8 is 1,
160 otherwise the player can't be turned off. */
161 rtc_write(8, rtc_read(8) | 0x80);
166 #ifdef HAVE_ALARM_MOD
168 /* check whether the unit has been started by the RTC alarm function */
169 /* (check for AF, which => started using wakeup alarm) */
170 bool rtc_check_alarm_started(bool release_alarm
)
172 static bool alarm_state
, run_before
;
177 alarm_state
&= ~release_alarm
;
179 /* This call resets AF, so we store the state for later recall */
180 rc
= alarm_state
= rtc_check_alarm_flag();
187 * Checks the AL register. This call resets AL once read.
189 * We're only interested if ABE is set. AL is still raised regardless
190 * even if the unit is off when the alarm occurs.
192 bool rtc_check_alarm_flag(void)
194 return ( ( (rtc_read(0x0f) & 0x40) != 0) &&
195 (rtc_read(0x0a) & 0x20) );
198 /* set alarm time registers to the given time (repeat once per day) */
199 void rtc_set_alarm(int h
, int m
)
203 /* for daily alarm, RPT5=RPT4=on, RPT1=RPT2=RPT3=off */
205 rtc_write(0x0e, 0x00); /* seconds 0 and RTP1 */
206 rtc_write(0x0d, ((m
/ 10) << 4) | (m
% 10)); /* minutes and RPT2 */
207 rtc_write(0x0c, ((h
/ 10) << 4) | (h
% 10)); /* hour and RPT3 */
208 rtc_write(0x0b, 0xc1); /* set date 01 and RPT4 and RTP5 */
210 /* set month to 1, if it's invalid, the rtc does an alarm every second instead */
211 data
= rtc_read(0x0a);
214 rtc_write(0x0a, data
);
217 /* read out the current alarm time */
218 void rtc_get_alarm(int *h
, int *m
)
222 data
= rtc_read(0x0c);
223 *h
= ((data
& 0x30) >> 4) * 10 + (data
& 0x0f);
225 data
= rtc_read(0x0d);
226 *m
= ((data
& 0x70) >> 4) * 10 + (data
& 0x0f);
229 /* turn alarm on or off by setting the alarm flag enable */
230 /* the alarm is automatically disabled when the RTC gets Vcc power at startup */
231 /* avoid that an alarm occurs when the device is on because this locks the ON key forever */
232 /* returns false if alarm was set and alarm flag (output) is off */
233 /* returns true if alarm flag went on, which would lock the device, so the alarm was disabled again */
234 bool rtc_enable_alarm(bool enable
)
236 unsigned char data
= rtc_read(0x0a);
239 data
|= 0xa0; /* turn bit d7=AFE and d5=ABE on */
242 data
&= 0x5f; /* turn bit d7=AFE and d5=ABE off */
243 rtc_write(0x0a, data
);
245 /* check if alarm flag AF is off (as it should be) */
246 /* in some cases enabling the alarm results in an activated AF flag */
247 /* this should not happen, but it does */
248 /* if you know why, tell me! */
249 /* for now, we try again forever in this case */
250 while (rtc_check_alarm_flag()) /* on */
252 data
&= 0x5f; /* turn bit d7=AFE and d5=ABE off */
253 rtc_write(0x0a, data
);
255 rtc_check_alarm_flag();
256 data
|= 0xa0; /* turn bit d7=AFE and d5=ABE on */
257 rtc_write(0x0a, data
);
260 return false; /* all ok */
263 #endif /* HAVE_ALARM_MOD */
265 int rtc_write(unsigned char address
, unsigned char value
)
268 unsigned char buf
[2];
275 /* send run command */
276 if (i2c_write(RTC_DEV_WRITE
,buf
,2))
285 int rtc_read(unsigned char address
)
288 unsigned char buf
[1];
294 /* send read command */
295 if (i2c_write(RTC_DEV_READ
,buf
,1) >= 0)
298 i2c_outb(RTC_DEV_READ
);
311 int rtc_read_multiple(unsigned char address
, unsigned char *buf
, int numbytes
)
314 unsigned char obuf
[1];
321 /* send read command */
322 if (i2c_write(RTC_DEV_READ
, obuf
, 1) >= 0)
325 i2c_outb(RTC_DEV_READ
);
328 for(i
= 0;i
< numbytes
-1;i
++)
345 int rtc_read_datetime(unsigned char* buf
) {
348 rc
= rtc_read_multiple(1, buf
, 7);
357 int rtc_write_datetime(unsigned char* buf
) {
365 for (i
= 0; i
< 7 ; i
++)
367 rc
|= rtc_write(i
+1, buf
[i
]);
369 rc
|= rtc_write(8, 0x80); /* Out=1, calibration = 0 */
373 #endif /* CONFIG_RTC == RTC_PCF50606 */
375 #endif /* CONFIG_RTC */