| /* | |
| * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. | |
| * TsiChung Liew (Tsi-Chung.Liew@freescale.com) | |
| * | |
| * See file CREDITS for list of people who contributed to this | |
| * project. | |
| * | |
| * This program is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU General Public License as | |
| * published by the Free Software Foundation; either version 2 of | |
| * the License, or (at your option) any later version. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
| * MA 02111-1307 USA | |
| */ | |
| #include <common.h> | |
| #if defined(CONFIG_CMD_DATE) | |
| #include <command.h> | |
| #include <rtc.h> | |
| #include <asm/immap.h> | |
| #include <asm/rtc.h> | |
| #undef RTC_DEBUG | |
| #ifndef CONFIG_SYS_MCFRTC_BASE | |
| #error RTC_BASE is not defined! | |
| #endif | |
| #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) | |
| #define STARTOFTIME 1970 | |
| int rtc_get(struct rtc_time *tmp) | |
| { | |
| volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); | |
| int rtc_days, rtc_hrs, rtc_mins; | |
| int tim; | |
| rtc_days = rtc->days; | |
| rtc_hrs = rtc->hourmin >> 8; | |
| rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin); | |
| tim = (rtc_days * 24) + rtc_hrs; | |
| tim = (tim * 60) + rtc_mins; | |
| tim = (tim * 60) + rtc->seconds; | |
| to_tm(tim, tmp); | |
| tmp->tm_yday = 0; | |
| tmp->tm_isdst = 0; | |
| #ifdef RTC_DEBUG | |
| printf("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", | |
| tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, | |
| tmp->tm_hour, tmp->tm_min, tmp->tm_sec); | |
| #endif | |
| return 0; | |
| } | |
| int rtc_set(struct rtc_time *tmp) | |
| { | |
| volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); | |
| static int month_days[12] = { | |
| 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 | |
| }; | |
| int days, i, months; | |
| if (tmp->tm_year > 2037) { | |
| printf("Unable to handle. Exceeding integer limitation!\n"); | |
| tmp->tm_year = 2027; | |
| } | |
| #ifdef RTC_DEBUG | |
| printf("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", | |
| tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, | |
| tmp->tm_hour, tmp->tm_min, tmp->tm_sec); | |
| #endif | |
| /* calculate days by years */ | |
| for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) { | |
| days += 365 + isleap(i); | |
| } | |
| /* calculate days by months */ | |
| months = tmp->tm_mon - 1; | |
| for (i = 0; i < months; i++) { | |
| days += month_days[i]; | |
| if (i == 1) | |
| days += isleap(i); | |
| } | |
| days += tmp->tm_mday - 1; | |
| rtc->days = days; | |
| rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min; | |
| rtc->seconds = tmp->tm_sec; | |
| return 0; | |
| } | |
| void rtc_reset(void) | |
| { | |
| volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); | |
| if ((rtc->cr & RTC_CR_EN) == 0) { | |
| printf("real-time-clock was stopped. Now starting...\n"); | |
| rtc->cr |= RTC_CR_EN; | |
| } | |
| rtc->cr |= RTC_CR_SWR; | |
| } | |
| #endif /* CONFIG_MCFRTC && CONFIG_CMD_DATE */ |