mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-25 03:18:51 +09:00
![Simon Glass](/assets/img/avatar_default.png)
Rename this function so that it is clear that it is provided by the RTC. Also return an error when it cannot function as expected. This is unlikely to occur since it works for dates since 1752 and many RTCs do not support such old dates. Still it is better to be accurate. Signed-off-by: Simon Glass <sjg@chromium.org> Acked-by: Heiko Schocher <hs@denx.de>
110 lines
2.3 KiB
C
110 lines
2.3 KiB
C
/*
|
|
* Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
|
|
* TsiChung Liew (Tsi-Chung.Liew@freescale.com)
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#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;
|
|
|
|
rtc_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 */
|