Add a get_offset API call to make codec_advance_buffer_loc_callback work.
[Rockbox.git] / firmware / drivers / rtc / rtc_as3514.c
blob15d543ec3ff87a774e23f53baec65dd988f1c012
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: rtc_as3514.c 12131 2007-01-27 20:48:48Z dan_a $
10 * Copyright (C) 2007 by Barry Wardell
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 ****************************************************************************/
19 #include <stdbool.h>
20 #include "rtc.h"
21 #include "i2c-pp.h"
22 #include "as3514.h"
24 #define MINUTE_SECONDS 60
25 #define HOUR_SECONDS 3600
26 #define DAY_SECONDS 86400
27 #define WEEK_SECONDS 604800
28 #define YEAR_SECONDS 31536000
29 #define LEAP_YEAR_SECONDS 31622400
31 #define BCD2DEC(X) (((((X)>>4) & 0x0f) * 10) + ((X) & 0xf))
32 #define DEC2BCD(X) ((((X)/10)<<4) | ((X)%10))
34 /* Days in each month */
35 static unsigned int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
37 static inline bool is_leapyear(int year)
39 if( ((year%4)==0) && (((year%100)!=0) || ((year%400)==0)) )
40 return true;
41 else
42 return false;
45 void rtc_init(void)
49 int rtc_read_datetime(unsigned char* buf)
51 char tmp[4];
52 int year;
53 int i;
54 unsigned int seconds;
56 /* RTC_AS3514's slave address is 0x46*/
57 for (i=0;i<4;i++){
58 tmp[i] = i2c_readbyte(AS3514_I2C_ADDR, RTC_0 + i);
60 seconds = tmp[0] + (tmp[1]<<8) + (tmp[2]<<16) + (tmp[3]<<24);
62 /* Convert seconds since Jan-1-1980 to format compatible with
63 * get_time() from firmware/common/timefuncs.c */
65 /* weekday */
66 buf[3] = ((seconds % WEEK_SECONDS) / DAY_SECONDS + 2) % 7;
68 /* Year */
69 year = 1980;
70 while(seconds>=LEAP_YEAR_SECONDS)
72 if(is_leapyear(year)){
73 seconds -= LEAP_YEAR_SECONDS;
74 } else {
75 seconds -= YEAR_SECONDS;
78 year++;
81 if(is_leapyear(year)) {
82 days_in_month[1] = 29;
83 } else {
84 days_in_month[1] = 28;
85 if(seconds>YEAR_SECONDS){
86 year++;
87 seconds -= YEAR_SECONDS;
90 buf[6] = year%100;
92 /* Month */
93 for(i=0; i<12; i++)
95 if(seconds < days_in_month[i]*DAY_SECONDS){
96 buf[5] = i+1;
97 break;
100 seconds -= days_in_month[i]*DAY_SECONDS;
103 /* Month Day */
104 buf[4] = seconds/DAY_SECONDS;
105 seconds -= buf[4]*DAY_SECONDS;
106 buf[4]++; /* 1 ... 31 */
108 /* Hour */
109 buf[2] = seconds/HOUR_SECONDS;
110 seconds -= buf[2]*HOUR_SECONDS;
112 /* Minute */
113 buf[1] = seconds/MINUTE_SECONDS;
114 seconds -= buf[1]*MINUTE_SECONDS;
116 /* Second */
117 buf[0] = seconds;
119 /* Convert to Binary Coded Decimal format */
120 for(i=0; i<7; i++)
121 buf[i] = DEC2BCD(buf[i]);
123 return 7;
126 int rtc_write_datetime(unsigned char* buf)
128 int i, year;
129 unsigned int year_days = 0;
130 unsigned int month_days = 0;
131 unsigned int seconds = 0;
133 /* Convert from Binary Coded Decimal format */
134 for(i=0; i<7; i++)
135 buf[i] = BCD2DEC(buf[i]);
137 year = 2000 + buf[6];
139 if(is_leapyear(year)) {
140 days_in_month[1] = 29;
141 } else {
142 days_in_month[1] = 28;
145 /* Number of days in months gone by this year*/
146 for(i=0; i<(buf[5]-1); i++){
147 month_days += days_in_month[i];
150 /* Number of days in years gone by since 1-Jan-1980 */
151 year_days = 365*(buf[6]+20) + (buf[6]-1)/4 + 6;
153 /* Convert to seconds since 1-Jan-1980 */
154 seconds = buf[0]
155 + buf[1]*MINUTE_SECONDS
156 + buf[2]*HOUR_SECONDS
157 + (buf[4]-1)*DAY_SECONDS
158 + month_days*DAY_SECONDS
159 + year_days*DAY_SECONDS;
161 /* Send data to RTC */
162 for (i=0;i<4;i++){
163 pp_i2c_send(AS3514_I2C_ADDR, RTC_0 + i, ((seconds >> (8 * i)) & 0xff));
165 return 1;