1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing, Uwe Freese, Laurent Baum
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 #define RTC_DEV_WRITE (RTC_ADR | 0x00)
30 #define RTC_DEV_READ (RTC_ADR | 0x01)
37 /* Check + save alarm bit first, before the power thread starts watching */
38 rtc_check_alarm_started(false);
41 /* Clear the Stop bit if it is set */
42 data
= rtc_read(0x01);
44 rtc_write(0x01, 0x00);
46 /* Clear the HT bit if it is set */
47 data
= rtc_read(0x0c);
57 /* Clear Trec bit, write-protecting the RTC for 200ms when shutting off */
58 /* without this, the alarm won't work! */
60 data
= rtc_read(0x04);
64 rtc_write(0x04, data
);
67 /* Also, make sure that the OUT bit in register 8 is 1,
68 otherwise the player can't be turned off. */
69 rtc_write(8, rtc_read(8) | 0x80);
76 /* check whether the unit has been started by the RTC alarm function */
77 /* (check for AF, which => started using wakeup alarm) */
78 bool rtc_check_alarm_started(bool release_alarm
)
80 static bool alarm_state
, run_before
;
85 alarm_state
&= ~release_alarm
;
87 /* This call resets AF, so we store the state for later recall */
88 rc
= alarm_state
= rtc_check_alarm_flag();
95 * Checks the AL register. This call resets AL once read.
97 * We're only interested if ABE is set. AL is still raised regardless
98 * even if the unit is off when the alarm occurs.
100 bool rtc_check_alarm_flag(void)
102 return ( ( (rtc_read(0x0f) & 0x40) != 0) &&
103 (rtc_read(0x0a) & 0x20) );
106 /* set alarm time registers to the given time (repeat once per day) */
107 void rtc_set_alarm(int h
, int m
)
111 /* for daily alarm, RPT5=RPT4=on, RPT1=RPT2=RPT3=off */
113 rtc_write(0x0e, 0x00); /* seconds 0 and RTP1 */
114 rtc_write(0x0d, DEC2BCD(m
)); /* minutes and RPT2 */
115 rtc_write(0x0c, DEC2BCD(h
)); /* hour and RPT3 */
116 rtc_write(0x0b, 0xc1); /* set date 01 and RPT4 and RTP5 */
118 /* set month to 1, if it's invalid, the rtc does an alarm every second instead */
119 data
= rtc_read(0x0a);
122 rtc_write(0x0a, data
);
125 /* read out the current alarm time */
126 void rtc_get_alarm(int *h
, int *m
)
130 data
= rtc_read(0x0c);
131 *h
= BCD2DEC(data
& 0x3f);
133 data
= rtc_read(0x0d);
134 *m
= BCD2DEC(data
& 0x7f);
137 /* turn alarm on or off by setting the alarm flag enable */
138 /* the alarm is automatically disabled when the RTC gets Vcc power at startup */
139 /* avoid that an alarm occurs when the device is on because this locks the ON key forever */
140 void rtc_enable_alarm(bool enable
)
142 unsigned char data
= rtc_read(0x0a);
145 data
|= 0xa0; /* turn bit d7=AFE and d5=ABE on */
148 data
&= 0x5f; /* turn bit d7=AFE and d5=ABE off */
149 rtc_write(0x0a, data
);
151 /* check if alarm flag AF is off (as it should be) */
152 /* in some cases enabling the alarm results in an activated AF flag */
153 /* this should not happen, but it does */
154 /* if you know why, tell me! */
155 /* for now, we try again forever in this case */
156 while (rtc_check_alarm_flag()) /* on */
158 data
&= 0x5f; /* turn bit d7=AFE and d5=ABE off */
159 rtc_write(0x0a, data
);
161 rtc_check_alarm_flag();
162 data
|= 0xa0; /* turn bit d7=AFE and d5=ABE on */
163 rtc_write(0x0a, data
);
167 #endif /* HAVE_RTC_ALARM */
169 int rtc_write(unsigned char address
, unsigned char value
)
172 unsigned char buf
[2];
179 /* send run command */
180 if (i2c_write(RTC_DEV_WRITE
,buf
,2))
189 int rtc_read(unsigned char address
)
192 unsigned char buf
[1];
198 /* send read command */
199 if (i2c_write(RTC_DEV_READ
,buf
,1) >= 0)
202 i2c_outb(RTC_DEV_READ
);
215 int rtc_read_multiple(unsigned char address
, unsigned char *buf
, int numbytes
)
218 unsigned char obuf
[1];
225 /* send read command */
226 if (i2c_write(RTC_DEV_READ
, obuf
, 1) >= 0)
229 i2c_outb(RTC_DEV_READ
);
232 for(i
= 0;i
< numbytes
-1;i
++)
249 int rtc_read_datetime(struct tm
*tm
)
252 unsigned char buf
[7];
254 rc
= rtc_read_multiple(1, buf
, sizeof(buf
));
256 /* convert from bcd, avoid getting extra bits */
257 tm
->tm_sec
= BCD2DEC(buf
[0] & 0x7f);
258 tm
->tm_min
= BCD2DEC(buf
[1] & 0x7f);
259 tm
->tm_hour
= BCD2DEC(buf
[2] & 0x3f);
260 tm
->tm_wday
= BCD2DEC(buf
[3] & 0x7);
261 tm
->tm_mday
= BCD2DEC(buf
[4] & 0x3f);
262 tm
->tm_mon
= BCD2DEC(buf
[5] & 0x1f) - 1;
263 tm
->tm_year
= BCD2DEC(buf
[6]) + 100;
266 if (tm
->tm_wday
== 7)
272 int rtc_write_datetime(const struct tm
*tm
)
276 unsigned char buf
[7];
280 buf
[2] = tm
->tm_hour
;
281 buf
[3] = tm
->tm_wday
;
282 buf
[4] = tm
->tm_mday
;
283 buf
[5] = tm
->tm_mon
+ 1;
284 buf
[6] = tm
->tm_year
- 100;
290 for (i
= 0; i
< sizeof(buf
) ;i
++)
292 rc
|= rtc_write(i
+ 1, DEC2BCD(buf
[i
]));
294 rc
|= rtc_write(8, 0x80); /* Out=1, calibration = 0 */