fix red
[kugel-rb.git] / firmware / drivers / rtc / rtc_jz4740.c
blobb82978ed213660ea8f623262dff41c0e7f95f373
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2008 by Maurus Cuelenaere
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 ****************************************************************************/
23 * Jz OnChip Real Time Clock interface for Linux
27 #include "config.h"
28 #include "jz4740.h"
29 #include "rtc.h"
30 #include "timefuncs.h"
31 #include "logf.h"
33 /* Stolen from dietlibc-0.29/libugly/gmtime_r.c (GPLv2) */
34 #define SPD (24*60*60)
35 #define ISLEAP(year) (!(year%4) && ((year%100) || !(year%400)))
36 static void _localtime(const time_t t, struct tm *r)
38 time_t i;
39 register time_t work = t % SPD;
40 static int m_to_d[12] = /* This could be shared with mktime() */
41 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
43 r->tm_sec = work % 60;
44 work /= 60;
45 r->tm_min = work % 60;
46 r->tm_hour = work / 60;
47 work = t / SPD;
48 r->tm_wday = (4 + work) % 7;
50 for (i=1970; ; ++i)
52 register time_t k = ISLEAP(i) ? 366 : 365;
54 if (work >= k)
55 work -= k;
56 else
57 break;
60 r->tm_year = i - 1900;
61 r->tm_yday = work;
63 r->tm_mday = 1;
64 if (ISLEAP(i) && (work>58))
66 if (work==59)
67 r->tm_mday=2; /* 29.2. */
69 work-=1;
72 for (i=11; i && (m_to_d[i] > work); --i);
73 r->tm_mon = i;
74 r->tm_mday += work - m_to_d[i];
77 int rtc_read_datetime(struct tm *tm)
79 _localtime(REG_RTC_RSR, tm);
81 return 1;
84 int rtc_write_datetime(const struct tm *tm)
86 time_t val = mktime((struct tm*)tm);
88 __cpm_start_rtc();
89 udelay(100);
90 REG_RTC_RSR = val;
91 __cpm_stop_rtc();
93 return 0;
96 void rtc_init(void)
98 __cpm_start_rtc();
99 REG_RTC_RCR = RTC_RCR_RTCE;
100 udelay(70);
101 while( !(REG_RTC_RCR & RTC_RCR_WRDY) );
102 REG_RTC_RGR = (0x7fff | RTC_RGR_LOCK);
103 udelay(70);
104 __cpm_stop_rtc();