remove old rtc dir
This commit is contained in:
parent
2723a41e08
commit
1da61a7d97
51
rtc/Makefile
51
rtc/Makefile
|
@ -1,51 +0,0 @@
|
|||
#
|
||||
# (C) Copyright 2001-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# 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 $(TOPDIR)/config.mk
|
||||
|
||||
#CFLAGS += -DDEBUG
|
||||
|
||||
LIB = $(obj)librtc.a
|
||||
|
||||
COBJS = date.o \
|
||||
bf533_rtc.o ds12887.o ds1302.o ds1306.o ds1307.o \
|
||||
ds1337.o ds1374.o ds1556.o ds164x.o ds174x.o \
|
||||
m41t11.o max6900.o m48t35ax.o mc146818.o mk48t59.o \
|
||||
mpc5xxx.o mpc8xx.o pcf8563.o s3c24x0_rtc.o rs5c372.o
|
||||
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
145
rtc/bf533_rtc.c
145
rtc/bf533_rtc.c
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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
|
||||
* Real Time Clock interface of ADI21535 (Blackfin) for uCLinux
|
||||
*
|
||||
* Copyright (C) 2003 Motorola Corporation. All rights reserved.
|
||||
* Richard Xiao (A2590C@email.mot.com)
|
||||
*
|
||||
* Copyright (C) 1996 Paul Gortmaker
|
||||
*
|
||||
*
|
||||
* Based on other minimal char device drivers, like Alan's
|
||||
* watchdog, Ted's random, etc. etc.
|
||||
*
|
||||
* 1.07 Paul Gortmaker.
|
||||
* 1.08 Miquel van Smoorenburg: disallow certain things on the
|
||||
* DEC Alpha as the CMOS clock is also used for other things.
|
||||
* 1.09 Nikita Schmidt: epoch support and some Alpha cleanup.
|
||||
* 1.09a Pete Zaitcev: Sun SPARC
|
||||
* 1.09b Jeff Garzik: Modularize, init cleanup
|
||||
* 1.09c Jeff Garzik: SMP cleanup
|
||||
* 1.10 Paul Barton-Davis: add support for async I/O
|
||||
* 1.10a Andrea Arcangeli: Alpha updates
|
||||
* 1.10b Andrew Morton: SMP lock fix
|
||||
* 1.10c Cesar Barros: SMP locking fixes and cleanup
|
||||
* 1.10d Paul Gortmaker: delete paranoia check in rtc_exit
|
||||
* 1.10e LG Soft India: Register access is different in BF533.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_BF533) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/cpu/bf533_rtc.h>
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
return; /* nothing to do */
|
||||
}
|
||||
|
||||
/* Wait for pending writes to complete */
|
||||
void wait_for_complete (void)
|
||||
{
|
||||
while (!(*(volatile unsigned short *) RTC_ISTAT & 0x8000)) {
|
||||
printf ("");
|
||||
}
|
||||
*(volatile unsigned short *) RTC_ISTAT = 0x8000;
|
||||
}
|
||||
|
||||
/* Enable the RTC prescaler enable register */
|
||||
void rtc_init ()
|
||||
{
|
||||
*(volatile unsigned short *) RTC_PREN = 0x1;
|
||||
wait_for_complete ();
|
||||
}
|
||||
|
||||
/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers
|
||||
* based on this value.
|
||||
*/
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned long n_days_1970 = 0;
|
||||
unsigned long n_secs_rem = 0;
|
||||
unsigned long n_hrs = 0;
|
||||
unsigned long n_mins = 0;
|
||||
unsigned long n_secs = 0;
|
||||
unsigned long time_in_secs;
|
||||
|
||||
if (tmp == NULL) {
|
||||
printf ("Error setting the date/time \n");
|
||||
return;
|
||||
}
|
||||
|
||||
time_in_secs =
|
||||
mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour,
|
||||
tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
/* Compute no. of days since 1970 */
|
||||
n_days_1970 = (unsigned long) (time_in_secs / (NUM_SECS_IN_DAY));
|
||||
|
||||
/* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */
|
||||
n_secs_rem = (unsigned long) (time_in_secs % (NUM_SECS_IN_DAY));
|
||||
n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR);
|
||||
n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR);
|
||||
n_mins = n_secs_rem / (NUM_SECS_IN_MIN);
|
||||
n_secs = n_secs_rem % (NUM_SECS_IN_MIN);
|
||||
|
||||
/* Store the new time in the RTC_STAT register */
|
||||
*(volatile unsigned long *) RTC_STAT =
|
||||
((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) |
|
||||
(n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF));
|
||||
|
||||
wait_for_complete ();
|
||||
}
|
||||
|
||||
/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned long cur_rtc_stat = 0;
|
||||
unsigned long time_in_sec;
|
||||
unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0;
|
||||
|
||||
if (tmp == NULL) {
|
||||
printf ("Error getting the date/time \n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read the RTC_STAT register */
|
||||
cur_rtc_stat = *(volatile unsigned long *) RTC_STAT;
|
||||
|
||||
/* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */
|
||||
tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f;
|
||||
tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f;
|
||||
tm_hour = (cur_rtc_stat >> HOUR_BITS_OFF) & 0x1f;
|
||||
tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff;
|
||||
|
||||
/* Calculate the total number of seconds since Jan 1970 */
|
||||
time_in_sec = (tm_sec) +
|
||||
MIN_TO_SECS (tm_min) +
|
||||
HRS_TO_SECS (tm_hour) +
|
||||
DAYS_TO_SECS (tm_day);
|
||||
to_tm (time_in_sec, tmp);
|
||||
}
|
||||
#endif /* CONFIG_RTC_BF533 && CFG_CMD_DATE */
|
152
rtc/date.c
152
rtc/date.c
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for Philips PCF8563 RTC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#define FEBRUARY 2
|
||||
#define STARTOFTIME 1970
|
||||
#define SECDAY 86400L
|
||||
#define SECYR (SECDAY * 365)
|
||||
#define leapyear(year) ((year) % 4 == 0)
|
||||
#define days_in_year(a) (leapyear(a) ? 366 : 365)
|
||||
#define days_in_month(a) (month_days[(a) - 1])
|
||||
|
||||
static int month_days[12] = {
|
||||
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
/*
|
||||
* This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
|
||||
*/
|
||||
void GregorianDay(struct rtc_time * tm)
|
||||
{
|
||||
int leapsToDate;
|
||||
int lastYear;
|
||||
int day;
|
||||
int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
|
||||
|
||||
lastYear=tm->tm_year-1;
|
||||
|
||||
/*
|
||||
* Number of leap corrections to apply up to end of last year
|
||||
*/
|
||||
leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
|
||||
|
||||
/*
|
||||
* This year is a leap year if it is divisible by 4 except when it is
|
||||
* divisible by 100 unless it is divisible by 400
|
||||
*
|
||||
* e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
|
||||
*/
|
||||
if((tm->tm_year%4==0) &&
|
||||
((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
|
||||
(tm->tm_mon>2)) {
|
||||
/*
|
||||
* We are past Feb. 29 in a leap year
|
||||
*/
|
||||
day=1;
|
||||
} else {
|
||||
day=0;
|
||||
}
|
||||
|
||||
day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
|
||||
|
||||
tm->tm_wday=day%7;
|
||||
}
|
||||
|
||||
void to_tm(int tim, struct rtc_time * tm)
|
||||
{
|
||||
register int i;
|
||||
register long hms, day;
|
||||
|
||||
day = tim / SECDAY;
|
||||
hms = tim % SECDAY;
|
||||
|
||||
/* Hours, minutes, seconds are easy */
|
||||
tm->tm_hour = hms / 3600;
|
||||
tm->tm_min = (hms % 3600) / 60;
|
||||
tm->tm_sec = (hms % 3600) % 60;
|
||||
|
||||
/* Number of years in days */
|
||||
for (i = STARTOFTIME; day >= days_in_year(i); i++) {
|
||||
day -= days_in_year(i);
|
||||
}
|
||||
tm->tm_year = i;
|
||||
|
||||
/* Number of months in days left */
|
||||
if (leapyear(tm->tm_year)) {
|
||||
days_in_month(FEBRUARY) = 29;
|
||||
}
|
||||
for (i = 1; day >= days_in_month(i); i++) {
|
||||
day -= days_in_month(i);
|
||||
}
|
||||
days_in_month(FEBRUARY) = 28;
|
||||
tm->tm_mon = i;
|
||||
|
||||
/* Days are what is left over (+1) from all that. */
|
||||
tm->tm_mday = day + 1;
|
||||
|
||||
/*
|
||||
* Determine the day of week
|
||||
*/
|
||||
GregorianDay(tm);
|
||||
}
|
||||
|
||||
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
||||
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
||||
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
||||
*
|
||||
* [For the Julian calendar (which was used in Russia before 1917,
|
||||
* Britain & colonies before 1752, anywhere else before 1582,
|
||||
* and is still in use by some communities) leave out the
|
||||
* -year/100+year/400 terms, and add 10.]
|
||||
*
|
||||
* This algorithm was first published by Gauss (I think).
|
||||
*
|
||||
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
|
||||
* machines were long is 32-bit! (However, as time_t is signed, we
|
||||
* will already get problems at other places on 2038-01-19 03:14:08)
|
||||
*/
|
||||
unsigned long
|
||||
mktime (unsigned int year, unsigned int mon,
|
||||
unsigned int day, unsigned int hour,
|
||||
unsigned int min, unsigned int sec)
|
||||
{
|
||||
if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
|
||||
mon += 12; /* Puts Feb last since it has leap day */
|
||||
year -= 1;
|
||||
}
|
||||
|
||||
return (((
|
||||
(unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
|
||||
year*365 - 719499
|
||||
)*24 + hour /* now have hours */
|
||||
)*60 + min /* now have minutes */
|
||||
)*60 + sec; /* finally seconds */
|
||||
}
|
238
rtc/ds12887.c
238
rtc/ds12887.c
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the DS12887 RTC
|
||||
*/
|
||||
|
||||
#undef RTC_DEBUG
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <config.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_DS12887) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
#define RTC_SECONDS 0x00
|
||||
#define RTC_SECONDS_ALARM 0x01
|
||||
#define RTC_MINUTES 0x02
|
||||
#define RTC_MINUTES_ALARM 0x03
|
||||
#define RTC_HOURS 0x04
|
||||
#define RTC_HOURS_ALARM 0x05
|
||||
#define RTC_DAY_OF_WEEK 0x06
|
||||
#define RTC_DATE_OF_MONTH 0x07
|
||||
#define RTC_MONTH 0x08
|
||||
#define RTC_YEAR 0x09
|
||||
#define RTC_CONTROL_A 0x0A
|
||||
#define RTC_CONTROL_B 0x0B
|
||||
#define RTC_CONTROL_C 0x0C
|
||||
#define RTC_CONTROL_D 0x0D
|
||||
|
||||
#define RTC_CA_UIP 0x80
|
||||
#define RTC_CB_DM 0x04
|
||||
#define RTC_CB_24_12 0x02
|
||||
#define RTC_CB_SET 0x80
|
||||
|
||||
#if defined(CONFIG_ATC)
|
||||
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
uchar val;
|
||||
|
||||
*(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
|
||||
__asm__ __volatile__ ("sync");
|
||||
|
||||
val = *(volatile unsigned char*)(RTC_PORT_DATA);
|
||||
return (val);
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
*(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
|
||||
__asm__ __volatile__ ("sync");
|
||||
|
||||
*(volatile unsigned char*)(RTC_PORT_DATA) = val;
|
||||
__asm__ __volatile__ ("sync");
|
||||
}
|
||||
|
||||
#else
|
||||
# error Board specific rtc access functions should be supplied
|
||||
#endif
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
/* check if rtc is available for access */
|
||||
while( rtc_read(RTC_CONTROL_A) & RTC_CA_UIP)
|
||||
;
|
||||
|
||||
sec = rtc_read(RTC_SECONDS);
|
||||
min = rtc_read(RTC_MINUTES);
|
||||
hour = rtc_read(RTC_HOURS);
|
||||
mday = rtc_read(RTC_DATE_OF_MONTH);
|
||||
wday = rtc_read(RTC_DAY_OF_WEEK);
|
||||
mon = rtc_read(RTC_MONTH);
|
||||
year = rtc_read(RTC_YEAR);
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "Get RTC year: %d; mon: %d; mday: %d; wday: %d; "
|
||||
"hr: %d; min: %d; sec: %d\n",
|
||||
year, mon, mday, wday, hour, min, sec );
|
||||
|
||||
printf ( "Alarms: hour: %02x min: %02x sec: %02x\n",
|
||||
rtc_read (RTC_HOURS_ALARM),
|
||||
rtc_read (RTC_MINUTES_ALARM),
|
||||
rtc_read (RTC_SECONDS_ALARM) );
|
||||
#endif
|
||||
|
||||
if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
|
||||
{ /* Information is in BCD format */
|
||||
printf(" Get: Convert BSD to BIN\n");
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year);
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp->tm_sec = sec & 0x7F;
|
||||
tmp->tm_min = min & 0x7F;
|
||||
tmp->tm_hour = hour & 0x3F;
|
||||
tmp->tm_mday = mday & 0x3F;
|
||||
tmp->tm_mon = mon & 0x1F;
|
||||
tmp->tm_year = year;
|
||||
tmp->tm_wday = wday & 0x07;
|
||||
}
|
||||
|
||||
|
||||
if(tmp->tm_year<70)
|
||||
tmp->tm_year+=2000;
|
||||
else
|
||||
tmp->tm_year+=1900;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar save_ctrl_b;
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
#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
|
||||
|
||||
if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
|
||||
{ /* Information is in BCD format */
|
||||
year = bin2bcd(tmp->tm_year % 100);
|
||||
mon = bin2bcd(tmp->tm_mon);
|
||||
wday = bin2bcd(tmp->tm_wday);
|
||||
mday = bin2bcd(tmp->tm_mday);
|
||||
hour = bin2bcd(tmp->tm_hour);
|
||||
min = bin2bcd(tmp->tm_min);
|
||||
sec = bin2bcd(tmp->tm_sec);
|
||||
}
|
||||
else
|
||||
{
|
||||
year = tmp->tm_year % 100;
|
||||
mon = tmp->tm_mon;
|
||||
wday = tmp->tm_wday;
|
||||
mday = tmp->tm_mday;
|
||||
hour = tmp->tm_hour;
|
||||
min = tmp->tm_min;
|
||||
sec = tmp->tm_sec;
|
||||
}
|
||||
|
||||
/* disables the RTC to update the regs */
|
||||
save_ctrl_b = rtc_read(RTC_CONTROL_B);
|
||||
save_ctrl_b |= RTC_CB_SET;
|
||||
rtc_write(RTC_CONTROL_B, save_ctrl_b);
|
||||
|
||||
rtc_write (RTC_YEAR, year);
|
||||
rtc_write (RTC_MONTH, mon);
|
||||
rtc_write (RTC_DAY_OF_WEEK, wday);
|
||||
rtc_write (RTC_DATE_OF_MONTH, mday);
|
||||
rtc_write (RTC_HOURS, hour);
|
||||
rtc_write (RTC_MINUTES, min);
|
||||
rtc_write (RTC_SECONDS, sec);
|
||||
|
||||
/* enables the RTC to update the regs */
|
||||
save_ctrl_b &= ~RTC_CB_SET;
|
||||
rtc_write(RTC_CONTROL_B, save_ctrl_b);
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
struct rtc_time tmp;
|
||||
uchar ctrl_rg;
|
||||
|
||||
ctrl_rg = RTC_CB_SET;
|
||||
rtc_write(RTC_CONTROL_B,ctrl_rg);
|
||||
|
||||
tmp.tm_year = 1970 % 100;
|
||||
tmp.tm_mon = 1;
|
||||
tmp.tm_mday= 1;
|
||||
tmp.tm_hour = 0;
|
||||
tmp.tm_min = 0;
|
||||
tmp.tm_sec = 0;
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n",
|
||||
tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
|
||||
tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
|
||||
#endif
|
||||
|
||||
ctrl_rg = RTC_CB_SET | RTC_CB_24_12 | RTC_CB_DM;
|
||||
rtc_write(RTC_CONTROL_B,ctrl_rg);
|
||||
rtc_set(&tmp);
|
||||
|
||||
rtc_write(RTC_HOURS_ALARM, 0),
|
||||
rtc_write(RTC_MINUTES_ALARM, 0),
|
||||
rtc_write(RTC_SECONDS_ALARM, 0);
|
||||
|
||||
ctrl_rg = RTC_CB_24_12 | RTC_CB_DM;
|
||||
rtc_write(RTC_CONTROL_B,ctrl_rg);
|
||||
}
|
||||
|
||||
#endif /* (CONFIG_RTC_DS12887) && (CONFIG_COMMANDS & CFG_CMD_DATE) */
|
327
rtc/ds1302.c
327
rtc/ds1302.c
|
@ -1,327 +0,0 @@
|
|||
/*
|
||||
* ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
|
||||
*
|
||||
* Rex G. Feany <rfeany@zumanetworks.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_DS1302) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/* GPP Pins */
|
||||
#define DATA 0x200
|
||||
#define SCLK 0x400
|
||||
#define RST 0x800
|
||||
|
||||
/* Happy Fun Defines(tm) */
|
||||
#define RESET rtc_go_low(RST), rtc_go_low(SCLK)
|
||||
#define N_RESET rtc_go_high(RST), rtc_go_low(SCLK)
|
||||
|
||||
#define CLOCK_HIGH rtc_go_high(SCLK)
|
||||
#define CLOCK_LOW rtc_go_low(SCLK)
|
||||
|
||||
#define DATA_HIGH rtc_go_high(DATA)
|
||||
#define DATA_LOW rtc_go_low(DATA)
|
||||
#define DATA_READ (GTREGREAD(GPP_VALUE) & DATA)
|
||||
|
||||
#undef RTC_DEBUG
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
# define DPRINTF(x,args...) printf("ds1302: " x , ##args)
|
||||
static inline void DUMP(const char *ptr, int num)
|
||||
{
|
||||
while (num--) printf("%x ", *ptr++);
|
||||
printf("]\n");
|
||||
}
|
||||
#else
|
||||
# define DPRINTF(x,args...)
|
||||
# define DUMP(ptr, num)
|
||||
#endif
|
||||
|
||||
/* time data format for DS1302 */
|
||||
struct ds1302_st
|
||||
{
|
||||
unsigned char CH:1; /* clock halt 1=stop 0=start */
|
||||
unsigned char sec10:3;
|
||||
unsigned char sec:4;
|
||||
|
||||
unsigned char zero0:1;
|
||||
unsigned char min10:3;
|
||||
unsigned char min:4;
|
||||
|
||||
unsigned char fmt:1; /* 1=12 hour 0=24 hour */
|
||||
unsigned char zero1:1;
|
||||
unsigned char hr10:2; /* 10 (0-2) or am/pm (am/pm, 0-1) */
|
||||
unsigned char hr:4;
|
||||
|
||||
unsigned char zero2:2;
|
||||
unsigned char date10:2;
|
||||
unsigned char date:4;
|
||||
|
||||
unsigned char zero3:3;
|
||||
unsigned char month10:1;
|
||||
unsigned char month:4;
|
||||
|
||||
unsigned char zero4:5;
|
||||
unsigned char day:3; /* day of week */
|
||||
|
||||
unsigned char year10:4;
|
||||
unsigned char year:4;
|
||||
|
||||
unsigned char WP:1; /* write protect 1=protect 0=unprot */
|
||||
unsigned char zero5:7;
|
||||
};
|
||||
|
||||
static int ds1302_initted=0;
|
||||
|
||||
/* Pin control */
|
||||
static inline void
|
||||
rtc_go_high(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_VALUE) | mask;
|
||||
|
||||
GT_REG_WRITE(GPP_VALUE, f);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtc_go_low(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;
|
||||
|
||||
GT_REG_WRITE(GPP_VALUE, f);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtc_go_input(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;
|
||||
|
||||
GT_REG_WRITE(GPP_IO_CONTROL, f);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rtc_go_output(unsigned int mask)
|
||||
{
|
||||
unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;
|
||||
|
||||
GT_REG_WRITE(GPP_IO_CONTROL, f);
|
||||
}
|
||||
|
||||
/* Access data in RTC */
|
||||
|
||||
static void
|
||||
write_byte(unsigned char b)
|
||||
{
|
||||
int i;
|
||||
unsigned char mask=1;
|
||||
|
||||
for(i=0;i<8;i++) {
|
||||
CLOCK_LOW; /* Lower clock */
|
||||
(b&mask)?DATA_HIGH:DATA_LOW; /* set data */
|
||||
udelay(1);
|
||||
CLOCK_HIGH; /* latch data with rising clock */
|
||||
udelay(1);
|
||||
mask=mask<<1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
read_byte(void)
|
||||
{
|
||||
int i;
|
||||
unsigned char mask=1;
|
||||
unsigned char b=0;
|
||||
|
||||
for(i=0;i<8;i++) {
|
||||
CLOCK_LOW;
|
||||
udelay(1);
|
||||
if (DATA_READ) b|=mask; /* if this bit is high, set in b */
|
||||
CLOCK_HIGH; /* clock out next bit */
|
||||
udelay(1);
|
||||
mask=mask<<1;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
read_ser_drv(unsigned char addr, unsigned char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
#ifdef RTC_DEBUG
|
||||
char *foo = buf;
|
||||
#endif
|
||||
|
||||
DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);
|
||||
|
||||
addr|=1; /* READ */
|
||||
N_RESET;
|
||||
udelay(4);
|
||||
write_byte(addr);
|
||||
rtc_go_input(DATA); /* Put gpp pin into input mode */
|
||||
udelay(1);
|
||||
for(i=0;i<count;i++) *(buf++)=read_byte();
|
||||
RESET;
|
||||
rtc_go_output(DATA);/* Reset gpp for output */
|
||||
udelay(4);
|
||||
|
||||
DUMP(foo, count);
|
||||
}
|
||||
|
||||
static void
|
||||
write_ser_drv(unsigned char addr, unsigned char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
|
||||
DUMP(buf, count);
|
||||
|
||||
addr&=~1; /* WRITE */
|
||||
N_RESET;
|
||||
udelay(4);
|
||||
write_byte(addr);
|
||||
for(i=0;i<count;i++) write_byte(*(buf++));
|
||||
RESET;
|
||||
udelay(4);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
rtc_init(void)
|
||||
{
|
||||
struct ds1302_st bbclk;
|
||||
unsigned char b;
|
||||
int mod;
|
||||
|
||||
DPRINTF("init\n");
|
||||
|
||||
rtc_go_output(DATA|SCLK|RST);
|
||||
|
||||
/* disable write protect */
|
||||
b = 0;
|
||||
write_ser_drv(0x8e,&b,1);
|
||||
|
||||
/* enable trickle */
|
||||
b = 0xa5; /* 1010.0101 */
|
||||
write_ser_drv(0x90,&b,1);
|
||||
|
||||
/* read burst */
|
||||
read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);
|
||||
|
||||
/* Sanity checks */
|
||||
mod = 0;
|
||||
if (bbclk.CH) {
|
||||
printf("ds1302: Clock was halted, starting clock\n");
|
||||
bbclk.CH=0;
|
||||
mod=1;
|
||||
}
|
||||
|
||||
if (bbclk.fmt) {
|
||||
printf("ds1302: Clock was in 12 hour mode, fixing\n");
|
||||
bbclk.fmt=0;
|
||||
mod=1;
|
||||
}
|
||||
|
||||
if (bbclk.year>9) {
|
||||
printf("ds1302: Year was corrupted, fixing\n");
|
||||
bbclk.year10=100/10; /* 2000 - why not? ;) */
|
||||
bbclk.year=0;
|
||||
mod=1;
|
||||
}
|
||||
|
||||
/* Write out the changes if needed */
|
||||
if (mod) {
|
||||
/* enable write protect */
|
||||
bbclk.WP = 1;
|
||||
write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
|
||||
} else {
|
||||
/* Else just turn write protect on */
|
||||
b = 0x80;
|
||||
write_ser_drv(0x8e,&b,1);
|
||||
}
|
||||
DPRINTF("init done\n");
|
||||
|
||||
ds1302_initted=1;
|
||||
}
|
||||
|
||||
void
|
||||
rtc_reset(void)
|
||||
{
|
||||
if(!ds1302_initted) rtc_init();
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void
|
||||
rtc_get(struct rtc_time *tmp)
|
||||
{
|
||||
struct ds1302_st bbclk;
|
||||
|
||||
if(!ds1302_initted) rtc_init();
|
||||
|
||||
read_ser_drv(0xbe,(unsigned char *)&bbclk, 8); /* read burst */
|
||||
|
||||
if (bbclk.CH) {
|
||||
printf("ds1302: rtc_get: Clock was halted, clock probably "
|
||||
"corrupt\n");
|
||||
}
|
||||
|
||||
tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
|
||||
tmp->tm_min=10*bbclk.min10+bbclk.min;
|
||||
tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
|
||||
tmp->tm_wday=bbclk.day;
|
||||
tmp->tm_mday=10*bbclk.date10+bbclk.date;
|
||||
tmp->tm_mon=10*bbclk.month10+bbclk.month;
|
||||
tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;
|
||||
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
DPRINTF("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 );
|
||||
}
|
||||
|
||||
void
|
||||
rtc_set(struct rtc_time *tmp)
|
||||
{
|
||||
struct ds1302_st bbclk;
|
||||
unsigned char b=0;
|
||||
|
||||
if(!ds1302_initted) rtc_init();
|
||||
|
||||
DPRINTF("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);
|
||||
|
||||
memset(&bbclk,0,sizeof(bbclk));
|
||||
bbclk.CH=0; /* dont halt */
|
||||
bbclk.WP=1; /* write protect when we're done */
|
||||
|
||||
bbclk.sec10=tmp->tm_sec/10;
|
||||
bbclk.sec=tmp->tm_sec%10;
|
||||
|
||||
bbclk.min10=tmp->tm_min/10;
|
||||
bbclk.min=tmp->tm_min%10;
|
||||
|
||||
bbclk.hr10=tmp->tm_hour/10;
|
||||
bbclk.hr=tmp->tm_hour%10;
|
||||
|
||||
bbclk.day=tmp->tm_wday;
|
||||
|
||||
bbclk.date10=tmp->tm_mday/10;
|
||||
bbclk.date=tmp->tm_mday%10;
|
||||
|
||||
bbclk.month10=tmp->tm_mon/10;
|
||||
bbclk.month=tmp->tm_mon%10;
|
||||
|
||||
tmp->tm_year -= 1900;
|
||||
bbclk.year10=tmp->tm_year/10;
|
||||
bbclk.year=tmp->tm_year%10;
|
||||
|
||||
write_ser_drv(0x8e,&b,1); /* disable write protect */
|
||||
write_ser_drv(0xbe,(unsigned char *)&bbclk, 8); /* write burst */
|
||||
}
|
||||
|
||||
#endif
|
438
rtc/ds1306.c
438
rtc/ds1306.c
|
@ -1,438 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2002 SIXNET, dge@sixnetio.com.
|
||||
*
|
||||
* (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
|
||||
* Stephan Linz <linz@li-pro.net>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for DS1306 RTC using SPI:
|
||||
*
|
||||
* - SXNI855T: it uses its own soft SPI here in this file
|
||||
* - all other: use the external spi_xfer() function
|
||||
* (see include/spi.h)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <spi.h>
|
||||
|
||||
#if defined(CONFIG_RTC_DS1306) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
#define RTC_SECONDS 0x00
|
||||
#define RTC_MINUTES 0x01
|
||||
#define RTC_HOURS 0x02
|
||||
#define RTC_DAY_OF_WEEK 0x03
|
||||
#define RTC_DATE_OF_MONTH 0x04
|
||||
#define RTC_MONTH 0x05
|
||||
#define RTC_YEAR 0x06
|
||||
|
||||
#define RTC_SECONDS_ALARM0 0x07
|
||||
#define RTC_MINUTES_ALARM0 0x08
|
||||
#define RTC_HOURS_ALARM0 0x09
|
||||
#define RTC_DAY_OF_WEEK_ALARM0 0x0a
|
||||
|
||||
#define RTC_SECONDS_ALARM1 0x0b
|
||||
#define RTC_MINUTES_ALARM1 0x0c
|
||||
#define RTC_HOURS_ALARM1 0x0d
|
||||
#define RTC_DAY_OF_WEEK_ALARM1 0x0e
|
||||
|
||||
#define RTC_CONTROL 0x0f
|
||||
#define RTC_STATUS 0x10
|
||||
#define RTC_TRICKLE_CHARGER 0x11
|
||||
|
||||
#define RTC_USER_RAM_BASE 0x20
|
||||
|
||||
/*
|
||||
* External table of chip select functions (see the appropriate board
|
||||
* support for the actual definition of the table).
|
||||
*/
|
||||
extern spi_chipsel_type spi_chipsel[];
|
||||
extern int spi_chipsel_cnt;
|
||||
|
||||
static unsigned int bin2bcd (unsigned int n);
|
||||
static unsigned char bcd2bin (unsigned char c);
|
||||
|
||||
/* ************************************************************************* */
|
||||
#ifdef CONFIG_SXNI855T /* !!! SHOULD BE CHANGED TO NEW CODE !!! */
|
||||
|
||||
static void soft_spi_send (unsigned char n);
|
||||
static unsigned char soft_spi_read (void);
|
||||
static void init_spi (void);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Definitions
|
||||
*/
|
||||
|
||||
#define PB_SPISCK 0x00000002 /* PB 30 */
|
||||
#define PB_SPIMOSI 0x00000004 /* PB 29 */
|
||||
#define PB_SPIMISO 0x00000008 /* PB 28 */
|
||||
#define PB_SPI_CE 0x00010000 /* PB 15 */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* read clock time from DS1306 and return it in *tmp */
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
unsigned char spi_byte; /* Data Byte */
|
||||
|
||||
init_spi (); /* set port B for software SPI */
|
||||
|
||||
/* Now we can enable the DS1306 RTC */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE;
|
||||
udelay (10);
|
||||
|
||||
/* Shift out the address (0) of the time in the Clock Chip */
|
||||
soft_spi_send (0);
|
||||
|
||||
/* Put the clock readings into the rtc_time structure */
|
||||
tmp->tm_sec = bcd2bin (soft_spi_read ()); /* Read seconds */
|
||||
tmp->tm_min = bcd2bin (soft_spi_read ()); /* Read minutes */
|
||||
|
||||
/* Hours are trickier */
|
||||
spi_byte = soft_spi_read (); /* Read Hours into temporary value */
|
||||
if (spi_byte & 0x40) {
|
||||
/* 12 hour mode bit is set (time is in 1-12 format) */
|
||||
if (spi_byte & 0x20) {
|
||||
/* since PM we add 11 to get 0-23 for hours */
|
||||
tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
|
||||
} else {
|
||||
/* since AM we subtract 1 to get 0-23 for hours */
|
||||
tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
|
||||
}
|
||||
} else {
|
||||
/* Otherwise, 0-23 hour format */
|
||||
tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
|
||||
}
|
||||
|
||||
soft_spi_read (); /* Read and discard Day of week */
|
||||
tmp->tm_mday = bcd2bin (soft_spi_read ()); /* Read Day of the Month */
|
||||
tmp->tm_mon = bcd2bin (soft_spi_read ()); /* Read Month */
|
||||
|
||||
/* Read Year and convert to this century */
|
||||
tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
|
||||
|
||||
/* Now we can disable the DS1306 RTC */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
|
||||
udelay (10);
|
||||
|
||||
GregorianDay (tmp); /* Determine the day of week */
|
||||
|
||||
debug ("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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* set clock time in DS1306 RTC and in MPC8xx RTC */
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
|
||||
init_spi (); /* set port B for software SPI */
|
||||
|
||||
/* Now we can enable the DS1306 RTC */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */
|
||||
udelay (10);
|
||||
|
||||
/* First disable write protect in the clock chip control register */
|
||||
soft_spi_send (0x8F); /* send address of the control register */
|
||||
soft_spi_send (0x00); /* send control register contents */
|
||||
|
||||
/* Now disable the DS1306 to terminate the write */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
|
||||
udelay (10);
|
||||
|
||||
/* Now enable the DS1306 to initiate a new write */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE;
|
||||
udelay (10);
|
||||
|
||||
/* Next, send the address of the clock time write registers */
|
||||
soft_spi_send (0x80); /* send address of the first time register */
|
||||
|
||||
/* Use Burst Mode to send all of the time data to the clock */
|
||||
bin2bcd (tmp->tm_sec);
|
||||
soft_spi_send (bin2bcd (tmp->tm_sec)); /* Send Seconds */
|
||||
soft_spi_send (bin2bcd (tmp->tm_min)); /* Send Minutes */
|
||||
soft_spi_send (bin2bcd (tmp->tm_hour)); /* Send Hour */
|
||||
soft_spi_send (bin2bcd (tmp->tm_wday)); /* Send Day of the Week */
|
||||
soft_spi_send (bin2bcd (tmp->tm_mday)); /* Send Day of Month */
|
||||
soft_spi_send (bin2bcd (tmp->tm_mon)); /* Send Month */
|
||||
soft_spi_send (bin2bcd (tmp->tm_year - 2000)); /* Send Year */
|
||||
|
||||
/* Now we can disable the Clock chip to terminate the burst write */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
|
||||
udelay (10);
|
||||
|
||||
/* Now we can enable the Clock chip to initiate a new write */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPI_CE; /* Enable DS1306 Chip */
|
||||
udelay (10);
|
||||
|
||||
/* First we Enable write protect in the clock chip control register */
|
||||
soft_spi_send (0x8F); /* send address of the control register */
|
||||
soft_spi_send (0x40); /* send out Control Register contents */
|
||||
|
||||
/* Now disable the DS1306 */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */
|
||||
udelay (10);
|
||||
|
||||
/* Set standard MPC8xx clock to the same time so Linux will
|
||||
* see the time even if it doesn't have a DS1306 clock driver.
|
||||
* This helps with experimenting with standard kernels.
|
||||
*/
|
||||
{
|
||||
ulong tim;
|
||||
|
||||
tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
immap->im_sitk.sitk_rtck = KAPWR_KEY;
|
||||
immap->im_sit.sit_rtc = tim;
|
||||
}
|
||||
|
||||
debug ("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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Initialize Port B for software SPI */
|
||||
static void init_spi (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
|
||||
/* Force output pins to begin at logic 0 */
|
||||
immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
|
||||
|
||||
/* Set these 3 signals as outputs */
|
||||
immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
|
||||
|
||||
immap->im_cpm.cp_pbdir &= ~PB_SPIMISO; /* Make MISO pin an input */
|
||||
udelay (10);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
|
||||
static void soft_spi_send (unsigned char n)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
unsigned char bitpos; /* bit position to receive */
|
||||
unsigned char i; /* Loop Control */
|
||||
|
||||
/* bit position to send, start with most significant bit */
|
||||
bitpos = 0x80;
|
||||
|
||||
/* Send 8 bits to software SPI */
|
||||
for (i = 0; i < 8; i++) { /* Loop for 8 bits */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */
|
||||
|
||||
if (n & bitpos)
|
||||
immap->im_cpm.cp_pbdat |= PB_SPIMOSI; /* Set MOSI to 1 */
|
||||
else
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI; /* Set MOSI to 0 */
|
||||
udelay (10);
|
||||
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */
|
||||
udelay (10);
|
||||
|
||||
bitpos >>= 1; /* Shift for next bit position */
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
|
||||
static unsigned char soft_spi_read (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
|
||||
unsigned char spi_byte = 0; /* Return value, assume success */
|
||||
unsigned char bitpos; /* bit position to receive */
|
||||
unsigned char i; /* Loop Control */
|
||||
|
||||
/* bit position to receive, start with most significant bit */
|
||||
bitpos = 0x80;
|
||||
|
||||
/* Read 8 bits here */
|
||||
for (i = 0; i < 8; i++) { /* Do 8 bits in loop */
|
||||
immap->im_cpm.cp_pbdat |= PB_SPISCK; /* Raise SCK */
|
||||
udelay (10);
|
||||
if (immap->im_cpm.cp_pbdat & PB_SPIMISO) /* Get a bit of data */
|
||||
spi_byte |= bitpos; /* Set data accordingly */
|
||||
immap->im_cpm.cp_pbdat &= ~PB_SPISCK; /* Lower SCK */
|
||||
udelay (10);
|
||||
bitpos >>= 1; /* Shift for next bit position */
|
||||
}
|
||||
|
||||
return spi_byte; /* Return the byte read */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
return; /* nothing to do */
|
||||
}
|
||||
|
||||
#else /* not CONFIG_SXNI855T */
|
||||
/* ************************************************************************* */
|
||||
|
||||
static unsigned char rtc_read (unsigned char reg);
|
||||
static void rtc_write (unsigned char reg, unsigned char val);
|
||||
|
||||
/* read clock time from DS1306 and return it in *tmp */
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned char sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
sec = rtc_read (RTC_SECONDS);
|
||||
min = rtc_read (RTC_MINUTES);
|
||||
hour = rtc_read (RTC_HOURS);
|
||||
mday = rtc_read (RTC_DATE_OF_MONTH);
|
||||
wday = rtc_read (RTC_DAY_OF_WEEK);
|
||||
mon = rtc_read (RTC_MONTH);
|
||||
year = rtc_read (RTC_YEAR);
|
||||
|
||||
debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday, hour, min, sec);
|
||||
debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
|
||||
rtc_read (RTC_DAY_OF_WEEK_ALARM0),
|
||||
rtc_read (RTC_HOURS_ALARM0),
|
||||
rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
|
||||
debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
|
||||
rtc_read (RTC_DAY_OF_WEEK_ALARM1),
|
||||
rtc_read (RTC_HOURS_ALARM1),
|
||||
rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F); /* convert Seconds */
|
||||
tmp->tm_min = bcd2bin (min & 0x7F); /* convert Minutes */
|
||||
|
||||
/* convert Hours */
|
||||
tmp->tm_hour = (hour & 0x40)
|
||||
? ((hour & 0x20) /* 12 hour mode */
|
||||
? bcd2bin (hour & 0x1F) + 11 /* PM */
|
||||
: bcd2bin (hour & 0x1F) - 1 /* AM */
|
||||
)
|
||||
: bcd2bin (hour & 0x3F); /* 24 hour mode */
|
||||
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F); /* convert Day of the Month */
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F); /* convert Month */
|
||||
tmp->tm_year = bcd2bin (year) + 2000; /* convert Year */
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07) - 1; /* convert Day of the Week */
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst = 0;
|
||||
|
||||
debug ("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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* set clock time from *tmp in DS1306 RTC */
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
debug ("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);
|
||||
|
||||
rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
|
||||
rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
|
||||
rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
|
||||
rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
|
||||
rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
|
||||
rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
|
||||
rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* reset the DS1306 */
|
||||
void rtc_reset (void)
|
||||
{
|
||||
/* clear the control register */
|
||||
rtc_write (RTC_CONTROL, 0x00); /* 1st step: reset WP */
|
||||
rtc_write (RTC_CONTROL, 0x00); /* 2nd step: reset 1Hz, AIE1, AIE0 */
|
||||
|
||||
/* reset all alarms */
|
||||
rtc_write (RTC_SECONDS_ALARM0, 0x00);
|
||||
rtc_write (RTC_SECONDS_ALARM1, 0x00);
|
||||
rtc_write (RTC_MINUTES_ALARM0, 0x00);
|
||||
rtc_write (RTC_MINUTES_ALARM1, 0x00);
|
||||
rtc_write (RTC_HOURS_ALARM0, 0x00);
|
||||
rtc_write (RTC_HOURS_ALARM1, 0x00);
|
||||
rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
|
||||
rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static unsigned char rtc_read (unsigned char reg)
|
||||
{
|
||||
unsigned char dout[2]; /* SPI Output Data Bytes */
|
||||
unsigned char din[2]; /* SPI Input Data Bytes */
|
||||
|
||||
dout[0] = reg;
|
||||
|
||||
if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return din[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void rtc_write (unsigned char reg, unsigned char val)
|
||||
{
|
||||
unsigned char dout[2]; /* SPI Output Data Bytes */
|
||||
unsigned char din[2]; /* SPI Input Data Bytes */
|
||||
|
||||
dout[0] = 0x80 | reg;
|
||||
dout[1] = val;
|
||||
|
||||
spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din);
|
||||
}
|
||||
|
||||
#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static unsigned char bcd2bin (unsigned char n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static unsigned int bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
204
rtc/ds1307.c
204
rtc/ds1307.c
|
@ -1,204 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001, 2002, 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* Keith Outwater, keith_outwater@mvis.com`
|
||||
* Steven Scholz, steven.scholz@imc-berlin.de
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
|
||||
* DS1307 and DS1338 Real Time Clock (RTC).
|
||||
*
|
||||
* based on ds1337.c
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if (defined(CONFIG_RTC_DS1307) || defined(CONFIG_RTC_DS1338) ) && \
|
||||
(CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#undef DEBUG_RTC
|
||||
|
||||
#ifdef DEBUG_RTC
|
||||
#define DEBUGR(fmt,args...) printf(fmt ,##args)
|
||||
#else
|
||||
#define DEBUGR(fmt,args...)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef CFG_I2C_RTC_ADDR
|
||||
# define CFG_I2C_RTC_ADDR 0x68
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RTC_DS1307) && (CFG_I2C_SPEED > 100000)
|
||||
# error The DS1307 is specified only up to 100kHz!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTC register addresses
|
||||
*/
|
||||
#define RTC_SEC_REG_ADDR 0x00
|
||||
#define RTC_MIN_REG_ADDR 0x01
|
||||
#define RTC_HR_REG_ADDR 0x02
|
||||
#define RTC_DAY_REG_ADDR 0x03
|
||||
#define RTC_DATE_REG_ADDR 0x04
|
||||
#define RTC_MON_REG_ADDR 0x05
|
||||
#define RTC_YR_REG_ADDR 0x06
|
||||
#define RTC_CTL_REG_ADDR 0x07
|
||||
|
||||
#define RTC_SEC_BIT_CH 0x80 /* Clock Halt (in Register 0) */
|
||||
|
||||
#define RTC_CTL_BIT_RS0 0x01 /* Rate select 0 */
|
||||
#define RTC_CTL_BIT_RS1 0x02 /* Rate select 1 */
|
||||
#define RTC_CTL_BIT_SQWE 0x10 /* Square Wave Enable */
|
||||
#define RTC_CTL_BIT_OUT 0x80 /* Output Control */
|
||||
|
||||
static uchar rtc_read (uchar reg);
|
||||
static void rtc_write (uchar reg, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin (uchar c);
|
||||
|
||||
/*
|
||||
* Get the current time from the RTC
|
||||
*/
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
sec = rtc_read (RTC_SEC_REG_ADDR);
|
||||
min = rtc_read (RTC_MIN_REG_ADDR);
|
||||
hour = rtc_read (RTC_HR_REG_ADDR);
|
||||
wday = rtc_read (RTC_DAY_REG_ADDR);
|
||||
mday = rtc_read (RTC_DATE_REG_ADDR);
|
||||
mon = rtc_read (RTC_MON_REG_ADDR);
|
||||
year = rtc_read (RTC_YR_REG_ADDR);
|
||||
|
||||
DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday, hour, min, sec);
|
||||
|
||||
if (sec & RTC_SEC_BIT_CH) {
|
||||
printf ("### Warning: RTC oscillator has stopped\n");
|
||||
/* clear the CH flag */
|
||||
rtc_write (RTC_SEC_REG_ADDR,
|
||||
rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH);
|
||||
}
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
|
||||
tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
DEBUGR ("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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the RTC
|
||||
*/
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
DEBUGR ("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);
|
||||
|
||||
if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
|
||||
printf("WARNING: year should be between 1970 and 2069!\n");
|
||||
|
||||
rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
|
||||
rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
|
||||
rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
|
||||
rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
|
||||
rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
|
||||
rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
|
||||
rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset the RTC. We setting the date back to 1970-01-01.
|
||||
* We also enable the oscillator output on the SQW/OUT pin and program
|
||||
* it for 32,768 Hz output. Note that according to the datasheet, turning
|
||||
* on the square wave output increases the current drain on the backup
|
||||
* battery to something between 480nA and 800nA.
|
||||
*/
|
||||
void rtc_reset (void)
|
||||
{
|
||||
struct rtc_time tmp;
|
||||
|
||||
rtc_write (RTC_SEC_REG_ADDR, 0x00); /* clearing Clock Halt */
|
||||
rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS0);
|
||||
|
||||
tmp.tm_year = 1970;
|
||||
tmp.tm_mon = 1;
|
||||
tmp.tm_mday= 1;
|
||||
tmp.tm_hour = 0;
|
||||
tmp.tm_min = 0;
|
||||
tmp.tm_sec = 0;
|
||||
|
||||
rtc_set(&tmp);
|
||||
|
||||
printf ( "RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n",
|
||||
tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
|
||||
tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
static
|
||||
uchar rtc_read (uchar reg)
|
||||
{
|
||||
return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
|
||||
}
|
||||
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* (CONFIG_RTC_DS1307 || CONFIG_RTC_DS1338) && (CFG_COMMANDS & CFG_CMD_DATE) */
|
191
rtc/ds1337.c
191
rtc/ds1337.c
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001, 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* Keith Outwater, keith_outwater@mvis.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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
|
||||
* DS1337 Real Time Clock (RTC).
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if defined(CONFIG_RTC_DS1337) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#undef DEBUG_RTC
|
||||
|
||||
#ifdef DEBUG_RTC
|
||||
#define DEBUGR(fmt,args...) printf(fmt ,##args)
|
||||
#else
|
||||
#define DEBUGR(fmt,args...)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* RTC register addresses
|
||||
*/
|
||||
#define RTC_SEC_REG_ADDR 0x0
|
||||
#define RTC_MIN_REG_ADDR 0x1
|
||||
#define RTC_HR_REG_ADDR 0x2
|
||||
#define RTC_DAY_REG_ADDR 0x3
|
||||
#define RTC_DATE_REG_ADDR 0x4
|
||||
#define RTC_MON_REG_ADDR 0x5
|
||||
#define RTC_YR_REG_ADDR 0x6
|
||||
#define RTC_CTL_REG_ADDR 0x0e
|
||||
#define RTC_STAT_REG_ADDR 0x0f
|
||||
|
||||
/*
|
||||
* RTC control register bits
|
||||
*/
|
||||
#define RTC_CTL_BIT_A1IE 0x1 /* Alarm 1 interrupt enable */
|
||||
#define RTC_CTL_BIT_A2IE 0x2 /* Alarm 2 interrupt enable */
|
||||
#define RTC_CTL_BIT_INTCN 0x4 /* Interrupt control */
|
||||
#define RTC_CTL_BIT_RS1 0x8 /* Rate select 1 */
|
||||
#define RTC_CTL_BIT_RS2 0x10 /* Rate select 2 */
|
||||
#define RTC_CTL_BIT_DOSC 0x80 /* Disable Oscillator */
|
||||
|
||||
/*
|
||||
* RTC status register bits
|
||||
*/
|
||||
#define RTC_STAT_BIT_A1F 0x1 /* Alarm 1 flag */
|
||||
#define RTC_STAT_BIT_A2F 0x2 /* Alarm 2 flag */
|
||||
#define RTC_STAT_BIT_OSF 0x80 /* Oscillator stop flag */
|
||||
|
||||
|
||||
static uchar rtc_read (uchar reg);
|
||||
static void rtc_write (uchar reg, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin (uchar c);
|
||||
|
||||
|
||||
/*
|
||||
* Get the current time from the RTC
|
||||
*/
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
|
||||
|
||||
control = rtc_read (RTC_CTL_REG_ADDR);
|
||||
status = rtc_read (RTC_STAT_REG_ADDR);
|
||||
sec = rtc_read (RTC_SEC_REG_ADDR);
|
||||
min = rtc_read (RTC_MIN_REG_ADDR);
|
||||
hour = rtc_read (RTC_HR_REG_ADDR);
|
||||
wday = rtc_read (RTC_DAY_REG_ADDR);
|
||||
mday = rtc_read (RTC_DATE_REG_ADDR);
|
||||
mon_cent = rtc_read (RTC_MON_REG_ADDR);
|
||||
year = rtc_read (RTC_YR_REG_ADDR);
|
||||
|
||||
DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
|
||||
year, mon_cent, mday, wday, hour, min, sec, control, status);
|
||||
|
||||
if (status & RTC_STAT_BIT_OSF) {
|
||||
printf ("### Warning: RTC oscillator has stopped\n");
|
||||
/* clear the OSF flag */
|
||||
rtc_write (RTC_STAT_REG_ADDR,
|
||||
rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
|
||||
}
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon_cent & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
|
||||
tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
DEBUGR ("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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set the RTC
|
||||
*/
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar century;
|
||||
|
||||
DEBUGR ("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);
|
||||
|
||||
rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
|
||||
|
||||
century = (tmp->tm_year >= 2000) ? 0x80 : 0;
|
||||
rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
|
||||
|
||||
rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
|
||||
rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
|
||||
rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
|
||||
rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
|
||||
rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Reset the RTC. We also enable the oscillator output on the
|
||||
* SQW/INTB* pin and program it for 32,768 Hz output. Note that
|
||||
* according to the datasheet, turning on the square wave output
|
||||
* increases the current drain on the backup battery from about
|
||||
* 600 nA to 2uA.
|
||||
*/
|
||||
void rtc_reset (void)
|
||||
{
|
||||
rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
static
|
||||
uchar rtc_read (uchar reg)
|
||||
{
|
||||
return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
|
||||
}
|
||||
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_DS1337 && (CFG_COMMANDS & CFG_CMD_DATE) */
|
253
rtc/ds1374.c
253
rtc/ds1374.c
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001, 2002, 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* Keith Outwater, keith_outwater@mvis.com`
|
||||
* Steven Scholz, steven.scholz@imc-berlin.de
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
|
||||
* DS1374 Real Time Clock (RTC).
|
||||
*
|
||||
* based on ds1337.c
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if (defined(CONFIG_RTC_DS1374)) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/*---------------------------------------------------------------------*/
|
||||
#undef DEBUG_RTC
|
||||
#define DEBUG_RTC
|
||||
|
||||
#ifdef DEBUG_RTC
|
||||
#define DEBUGR(fmt,args...) printf(fmt ,##args)
|
||||
#else
|
||||
#define DEBUGR(fmt,args...)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
||||
#ifndef CFG_I2C_RTC_ADDR
|
||||
# define CFG_I2C_RTC_ADDR 0x68
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_RTC_DS1374) && (CFG_I2C_SPEED > 400000)
|
||||
# error The DS1374 is specified up to 400kHz in fast mode!
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTC register addresses
|
||||
*/
|
||||
#define RTC_TOD_CNT_BYTE0_ADDR 0x00 /* TimeOfDay */
|
||||
#define RTC_TOD_CNT_BYTE1_ADDR 0x01
|
||||
#define RTC_TOD_CNT_BYTE2_ADDR 0x02
|
||||
#define RTC_TOD_CNT_BYTE3_ADDR 0x03
|
||||
|
||||
#define RTC_WD_ALM_CNT_BYTE0_ADDR 0x04
|
||||
#define RTC_WD_ALM_CNT_BYTE1_ADDR 0x05
|
||||
#define RTC_WD_ALM_CNT_BYTE2_ADDR 0x06
|
||||
|
||||
#define RTC_CTL_ADDR 0x07 /* RTC-CoNTrol-register */
|
||||
#define RTC_SR_ADDR 0x08 /* RTC-StatusRegister */
|
||||
#define RTC_TCS_DS_ADDR 0x09 /* RTC-TrickleChargeSelect DiodeSelect-register */
|
||||
|
||||
#define RTC_CTL_BIT_AIE (1<<0) /* Bit 0 - Alarm Interrupt enable */
|
||||
#define RTC_CTL_BIT_RS1 (1<<1) /* Bit 1/2 - Rate Select square wave output */
|
||||
#define RTC_CTL_BIT_RS2 (1<<2) /* Bit 2/2 - Rate Select square wave output */
|
||||
#define RTC_CTL_BIT_WDSTR (1<<3) /* Bit 3 - Watchdog Reset Steering */
|
||||
#define RTC_CTL_BIT_BBSQW (1<<4) /* Bit 4 - Battery-Backed Square-Wave */
|
||||
#define RTC_CTL_BIT_WD_ALM (1<<5) /* Bit 5 - Watchdoc/Alarm Counter Select */
|
||||
#define RTC_CTL_BIT_WACE (1<<6) /* Bit 6 - Watchdog/Alarm Counter Enable WACE*/
|
||||
#define RTC_CTL_BIT_EN_OSC (1<<7) /* Bit 7 - Enable Oscilator */
|
||||
|
||||
#define RTC_SR_BIT_AF 0x01 /* Bit 0 = Alarm Flag */
|
||||
#define RTC_SR_BIT_OSF 0x80 /* Bit 7 - Osc Stop Flag */
|
||||
|
||||
typedef unsigned char boolean_t;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE ((boolean_t)(0==0))
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE (!TRUE)
|
||||
#endif
|
||||
|
||||
const char RtcTodAddr[] = {
|
||||
RTC_TOD_CNT_BYTE0_ADDR,
|
||||
RTC_TOD_CNT_BYTE1_ADDR,
|
||||
RTC_TOD_CNT_BYTE2_ADDR,
|
||||
RTC_TOD_CNT_BYTE3_ADDR
|
||||
};
|
||||
|
||||
static uchar rtc_read (uchar reg);
|
||||
static void rtc_write (uchar reg, uchar val, boolean_t set);
|
||||
static void rtc_write_raw (uchar reg, uchar val);
|
||||
|
||||
/*
|
||||
* Get the current time from the RTC
|
||||
*/
|
||||
void rtc_get (struct rtc_time *tm){
|
||||
|
||||
unsigned long time1, time2;
|
||||
unsigned int limit;
|
||||
unsigned char tmp;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* Since the reads are being performed one byte at a time,
|
||||
* there is a chance that a carry will occur during the read.
|
||||
* To detect this, 2 reads are performed and compared.
|
||||
*/
|
||||
limit = 10;
|
||||
do {
|
||||
i = 4;
|
||||
time1 = 0;
|
||||
while (i--) {
|
||||
tmp = rtc_read(RtcTodAddr[i]);
|
||||
time1 = (time1 << 8) | (tmp & 0xff);
|
||||
}
|
||||
|
||||
i = 4;
|
||||
time2 = 0;
|
||||
while (i--) {
|
||||
tmp = rtc_read(RtcTodAddr[i]);
|
||||
time2 = (time2 << 8) | (tmp & 0xff);
|
||||
}
|
||||
} while ((time1 != time2) && limit--);
|
||||
|
||||
if (time1 != time2) {
|
||||
printf("can't get consistent time from rtc chip\n");
|
||||
}
|
||||
|
||||
DEBUGR ("Get RTC s since 1.1.1970: %d\n", time1);
|
||||
|
||||
to_tm(time1, tm); /* To Gregorian Date */
|
||||
|
||||
if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF)
|
||||
printf ("### Warning: RTC oscillator has stopped\n");
|
||||
|
||||
DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
|
||||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the RTC
|
||||
*/
|
||||
void rtc_set (struct rtc_time *tmp){
|
||||
|
||||
unsigned long time;
|
||||
unsigned i;
|
||||
|
||||
DEBUGR ("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);
|
||||
|
||||
if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
|
||||
printf("WARNING: year should be between 1970 and 2069!\n");
|
||||
|
||||
time = mktime(tmp->tm_year, tmp->tm_mon,
|
||||
tmp->tm_mday, tmp->tm_hour,
|
||||
tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
DEBUGR ("Set RTC s since 1.1.1970: %d (0x%02x)\n", time, time);
|
||||
|
||||
/* write to RTC_TOD_CNT_BYTEn_ADDR */
|
||||
for (i = 0; i <= 3; i++) {
|
||||
rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff));
|
||||
time = time >> 8;
|
||||
}
|
||||
|
||||
/* Start clock */
|
||||
rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the RTC. We setting the date back to 1970-01-01.
|
||||
* We also enable the oscillator output on the SQW/OUT pin and program
|
||||
* it for 32,768 Hz output. Note that according to the datasheet, turning
|
||||
* on the square wave output increases the current drain on the backup
|
||||
* battery to something between 480nA and 800nA.
|
||||
*/
|
||||
void rtc_reset (void){
|
||||
|
||||
struct rtc_time tmp;
|
||||
|
||||
/* clear status flags */
|
||||
rtc_write (RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), FALSE); /* clearing OSF and AF */
|
||||
|
||||
/* Initialise DS1374 oriented to MPC8349E-ADS */
|
||||
rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC
|
||||
|RTC_CTL_BIT_WACE
|
||||
|RTC_CTL_BIT_AIE), FALSE);/* start osc, disable WACE, clear AIE
|
||||
- set to 0 */
|
||||
rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM
|
||||
|RTC_CTL_BIT_WDSTR
|
||||
|RTC_CTL_BIT_RS1
|
||||
|RTC_CTL_BIT_RS2
|
||||
|RTC_CTL_BIT_BBSQW), TRUE);/* disable WD/ALM, WDSTR set to INT-pin,
|
||||
set BBSQW and SQW to 32k
|
||||
- set to 1 */
|
||||
tmp.tm_year = 1970;
|
||||
tmp.tm_mon = 1;
|
||||
tmp.tm_mday= 1;
|
||||
tmp.tm_hour = 0;
|
||||
tmp.tm_min = 0;
|
||||
tmp.tm_sec = 0;
|
||||
|
||||
rtc_set(&tmp);
|
||||
|
||||
printf("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n",
|
||||
tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
|
||||
tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
|
||||
|
||||
rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAC, TRUE);
|
||||
rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR,0xDE, TRUE);
|
||||
rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAD, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val, boolean_t set)
|
||||
{
|
||||
if (set == TRUE) {
|
||||
val |= i2c_reg_read (CFG_I2C_RTC_ADDR, reg);
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
} else {
|
||||
val = i2c_reg_read (CFG_I2C_RTC_ADDR, reg) & ~val;
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtc_write_raw (uchar reg, uchar val)
|
||||
{
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
}
|
||||
#endif /* (CONFIG_RTC_DS1374) && (CFG_COMMANDS & CFG_CMD_DATE) */
|
206
rtc/ds1556.c
206
rtc/ds1556.c
|
@ -1,206 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* ARIO Data Networks, Inc. dchiu@ariodata.com
|
||||
*
|
||||
* modified for DS1556:
|
||||
* Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
|
||||
*
|
||||
* Based on MontaVista DS1743 code and U-Boot mc146818 code
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the DS1556 RTC
|
||||
*/
|
||||
|
||||
/*#define RTC_DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
|
||||
#if defined(CONFIG_RTC_DS1556) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static uchar rtc_read( unsigned int addr );
|
||||
static void rtc_write( unsigned int addr, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin(uchar c);
|
||||
|
||||
#define RTC_BASE ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
|
||||
|
||||
#define RTC_YEAR ( RTC_BASE + 0xf )
|
||||
#define RTC_MONTH ( RTC_BASE + 0xe )
|
||||
#define RTC_DAY_OF_MONTH ( RTC_BASE + 0xd )
|
||||
#define RTC_DAY_OF_WEEK ( RTC_BASE + 0xc )
|
||||
#define RTC_HOURS ( RTC_BASE + 0xb )
|
||||
#define RTC_MINUTES ( RTC_BASE + 0xa )
|
||||
#define RTC_SECONDS ( RTC_BASE + 0x9 )
|
||||
#define RTC_CENTURY ( RTC_BASE + 0x8 )
|
||||
|
||||
#define RTC_CONTROLA RTC_CENTURY
|
||||
#define RTC_CONTROLB RTC_SECONDS
|
||||
#define RTC_CONTROLC RTC_BASE
|
||||
|
||||
#define RTC_CA_WRITE 0x80
|
||||
#define RTC_CA_READ 0x40
|
||||
|
||||
#define RTC_CB_OSC_DISABLE 0x80
|
||||
|
||||
#define RTC_CC_BATTERY_FLAG 0x10
|
||||
#define RTC_CC_FREQ_TEST 0x40
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get( struct rtc_time *tmp )
|
||||
{
|
||||
uchar sec, min, hour;
|
||||
uchar mday, wday, mon, year;
|
||||
|
||||
int century;
|
||||
|
||||
uchar reg_a;
|
||||
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
/* lock clock registers for read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
|
||||
|
||||
sec = rtc_read( RTC_SECONDS );
|
||||
min = rtc_read( RTC_MINUTES );
|
||||
hour = rtc_read( RTC_HOURS );
|
||||
mday = rtc_read( RTC_DAY_OF_MONTH );
|
||||
wday = rtc_read( RTC_DAY_OF_WEEK );
|
||||
mon = rtc_read( RTC_MONTH );
|
||||
year = rtc_read( RTC_YEAR );
|
||||
century = rtc_read( RTC_CENTURY );
|
||||
|
||||
/* unlock clock registers after read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, century, mon, mday, wday,
|
||||
hour, min, sec );
|
||||
#endif
|
||||
tmp->tm_sec = bcd2bin( sec & 0x7F );
|
||||
tmp->tm_min = bcd2bin( min & 0x7F );
|
||||
tmp->tm_hour = bcd2bin( hour & 0x3F );
|
||||
tmp->tm_mday = bcd2bin( mday & 0x3F );
|
||||
tmp->tm_mon = bcd2bin( mon & 0x1F );
|
||||
tmp->tm_wday = bcd2bin( wday & 0x07 );
|
||||
|
||||
/* glue year from century and year in century */
|
||||
tmp->tm_year = bcd2bin( year ) +
|
||||
( bcd2bin( century & 0x3F ) * 100 );
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set( struct rtc_time *tmp )
|
||||
{
|
||||
uchar reg_a;
|
||||
#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
|
||||
/* lock clock registers for write */
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
|
||||
|
||||
rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
|
||||
|
||||
rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
|
||||
rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
|
||||
rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
|
||||
rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
|
||||
rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
|
||||
|
||||
/* break year up into century and year in century */
|
||||
rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
|
||||
rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
|
||||
|
||||
/* unlock clock registers after read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_WRITE ));
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
uchar reg_a, reg_b, reg_c;
|
||||
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
reg_b = rtc_read( RTC_CONTROLB );
|
||||
|
||||
if ( reg_b & RTC_CB_OSC_DISABLE )
|
||||
{
|
||||
printf( "real-time-clock was stopped. Now starting...\n" );
|
||||
reg_a |= RTC_CA_WRITE;
|
||||
reg_b &= ~RTC_CB_OSC_DISABLE;
|
||||
|
||||
rtc_write( RTC_CONTROLA, reg_a );
|
||||
rtc_write( RTC_CONTROLB, reg_b );
|
||||
}
|
||||
|
||||
/* make sure read/write clock register bits are cleared */
|
||||
reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
|
||||
rtc_write( RTC_CONTROLA, reg_a );
|
||||
|
||||
reg_c = rtc_read( RTC_CONTROLC );
|
||||
if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
|
||||
printf( "RTC battery low. Clock setting may not be reliable.\n" );
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read( unsigned int addr )
|
||||
{
|
||||
uchar val = *(volatile unsigned char*)(addr);
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "rtc_read: %x:%x\n", addr, val );
|
||||
#endif
|
||||
return( val );
|
||||
}
|
||||
|
||||
static void rtc_write( unsigned int addr, uchar val )
|
||||
{
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "rtc_write: %x:%x\n", addr, val );
|
||||
#endif
|
||||
*(volatile unsigned char*)(addr) = val;
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_DS1556 && CFG_CMD_DATE */
|
200
rtc/ds164x.c
200
rtc/ds164x.c
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* ARIO Data Networks, Inc. dchiu@ariodata.com
|
||||
*
|
||||
* modified for DS164x:
|
||||
* The LEOX team <team@leox.org>, http://www.leox.org
|
||||
*
|
||||
* Based on MontaVista DS1743 code and U-Boot mc146818 code
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the DS164x RTC
|
||||
*/
|
||||
|
||||
/* #define RTC_DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
|
||||
#if defined(CONFIG_RTC_DS164x) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static uchar rtc_read(unsigned int addr );
|
||||
static void rtc_write(unsigned int addr, uchar val);
|
||||
static uchar bin2bcd(unsigned int n);
|
||||
static unsigned bcd2bin(uchar c);
|
||||
|
||||
#define RTC_EPOCH 2000 /* century */
|
||||
|
||||
/*
|
||||
* DS164x registers layout
|
||||
*/
|
||||
#define RTC_BASE ( CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE )
|
||||
|
||||
#define RTC_YEAR ( RTC_BASE + 0x07 )
|
||||
#define RTC_MONTH ( RTC_BASE + 0x06 )
|
||||
#define RTC_DAY_OF_MONTH ( RTC_BASE + 0x05 )
|
||||
#define RTC_DAY_OF_WEEK ( RTC_BASE + 0x04 )
|
||||
#define RTC_HOURS ( RTC_BASE + 0x03 )
|
||||
#define RTC_MINUTES ( RTC_BASE + 0x02 )
|
||||
#define RTC_SECONDS ( RTC_BASE + 0x01 )
|
||||
#define RTC_CONTROL ( RTC_BASE + 0x00 )
|
||||
|
||||
#define RTC_CONTROLA RTC_CONTROL /* W=bit6, R=bit5 */
|
||||
#define RTC_CA_WRITE 0x80
|
||||
#define RTC_CA_READ 0x40
|
||||
#define RTC_CONTROLB RTC_SECONDS /* OSC=bit7 */
|
||||
#define RTC_CB_OSC_DISABLE 0x80
|
||||
#define RTC_CONTROLC RTC_DAY_OF_WEEK /* FT=bit6 */
|
||||
#define RTC_CC_FREQ_TEST 0x40
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get( struct rtc_time *tmp )
|
||||
{
|
||||
uchar sec, min, hour;
|
||||
uchar mday, wday, mon, year;
|
||||
|
||||
uchar reg_a;
|
||||
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
/* lock clock registers for read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
|
||||
|
||||
sec = rtc_read( RTC_SECONDS );
|
||||
min = rtc_read( RTC_MINUTES );
|
||||
hour = rtc_read( RTC_HOURS );
|
||||
mday = rtc_read( RTC_DAY_OF_MONTH );
|
||||
wday = rtc_read( RTC_DAY_OF_WEEK );
|
||||
mon = rtc_read( RTC_MONTH );
|
||||
year = rtc_read( RTC_YEAR );
|
||||
|
||||
/* unlock clock registers after read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday,
|
||||
hour, min, sec );
|
||||
#endif
|
||||
tmp->tm_sec = bcd2bin( sec & 0x7F );
|
||||
tmp->tm_min = bcd2bin( min & 0x7F );
|
||||
tmp->tm_hour = bcd2bin( hour & 0x3F );
|
||||
tmp->tm_mday = bcd2bin( mday & 0x3F );
|
||||
tmp->tm_mon = bcd2bin( mon & 0x1F );
|
||||
tmp->tm_wday = bcd2bin( wday & 0x07 );
|
||||
|
||||
/* glue year in century (2000) */
|
||||
tmp->tm_year = bcd2bin( year ) + RTC_EPOCH;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set( struct rtc_time *tmp )
|
||||
{
|
||||
uchar reg_a;
|
||||
|
||||
#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
|
||||
/* lock clock registers for write */
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
|
||||
|
||||
rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
|
||||
|
||||
rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
|
||||
rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
|
||||
rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
|
||||
rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
|
||||
rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
|
||||
|
||||
/* break year in century */
|
||||
rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
|
||||
|
||||
/* unlock clock registers after read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_WRITE ));
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
uchar reg_a, reg_b;
|
||||
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
reg_b = rtc_read( RTC_CONTROLB );
|
||||
|
||||
if ( reg_b & RTC_CB_OSC_DISABLE )
|
||||
{
|
||||
printf( "real-time-clock was stopped. Now starting...\n" );
|
||||
reg_a |= RTC_CA_WRITE;
|
||||
reg_b &= ~RTC_CB_OSC_DISABLE;
|
||||
|
||||
rtc_write( RTC_CONTROLA, reg_a );
|
||||
rtc_write( RTC_CONTROLB, reg_b );
|
||||
}
|
||||
|
||||
/* make sure read/write clock register bits are cleared */
|
||||
reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
|
||||
rtc_write( RTC_CONTROLA, reg_a );
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read( unsigned int addr )
|
||||
{
|
||||
uchar val = *(volatile unsigned char*)(addr);
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "rtc_read: %x:%x\n", addr, val );
|
||||
#endif
|
||||
return( val );
|
||||
}
|
||||
|
||||
static void rtc_write( unsigned int addr, uchar val )
|
||||
{
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "rtc_write: %x:%x\n", addr, val );
|
||||
#endif
|
||||
*(volatile unsigned char*)(addr) = val;
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_DS164x && CFG_CMD_DATE */
|
202
rtc/ds174x.c
202
rtc/ds174x.c
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* ARIO Data Networks, Inc. dchiu@ariodata.com
|
||||
*
|
||||
* Based on MontaVista DS1743 code and U-Boot mc146818 code
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the DS174x RTC
|
||||
*/
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_DS174x) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static uchar rtc_read( unsigned int addr );
|
||||
static void rtc_write( unsigned int addr, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin(uchar c);
|
||||
|
||||
#define RTC_BASE ( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
|
||||
|
||||
#define RTC_YEAR ( RTC_BASE + 7 )
|
||||
#define RTC_MONTH ( RTC_BASE + 6 )
|
||||
#define RTC_DAY_OF_MONTH ( RTC_BASE + 5 )
|
||||
#define RTC_DAY_OF_WEEK ( RTC_BASE + 4 )
|
||||
#define RTC_HOURS ( RTC_BASE + 3 )
|
||||
#define RTC_MINUTES ( RTC_BASE + 2 )
|
||||
#define RTC_SECONDS ( RTC_BASE + 1 )
|
||||
#define RTC_CENTURY ( RTC_BASE + 0 )
|
||||
|
||||
#define RTC_CONTROLA RTC_CENTURY
|
||||
#define RTC_CONTROLB RTC_SECONDS
|
||||
#define RTC_CONTROLC RTC_DAY_OF_WEEK
|
||||
|
||||
#define RTC_CA_WRITE 0x80
|
||||
#define RTC_CA_READ 0x40
|
||||
|
||||
#define RTC_CB_OSC_DISABLE 0x80
|
||||
|
||||
#define RTC_CC_BATTERY_FLAG 0x80
|
||||
#define RTC_CC_FREQ_TEST 0x40
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get( struct rtc_time *tmp )
|
||||
{
|
||||
uchar sec, min, hour;
|
||||
uchar mday, wday, mon, year;
|
||||
|
||||
int century;
|
||||
|
||||
uchar reg_a;
|
||||
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
/* lock clock registers for read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
|
||||
|
||||
sec = rtc_read( RTC_SECONDS );
|
||||
min = rtc_read( RTC_MINUTES );
|
||||
hour = rtc_read( RTC_HOURS );
|
||||
mday = rtc_read( RTC_DAY_OF_MONTH );
|
||||
wday = rtc_read( RTC_DAY_OF_WEEK );
|
||||
mon = rtc_read( RTC_MONTH );
|
||||
year = rtc_read( RTC_YEAR );
|
||||
century = rtc_read( RTC_CENTURY );
|
||||
|
||||
/* unlock clock registers after read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon_cent, mday, wday,
|
||||
hour, min, sec );
|
||||
#endif
|
||||
tmp->tm_sec = bcd2bin( sec & 0x7F );
|
||||
tmp->tm_min = bcd2bin( min & 0x7F );
|
||||
tmp->tm_hour = bcd2bin( hour & 0x3F );
|
||||
tmp->tm_mday = bcd2bin( mday & 0x3F );
|
||||
tmp->tm_mon = bcd2bin( mon & 0x1F );
|
||||
tmp->tm_wday = bcd2bin( wday & 0x07 );
|
||||
|
||||
/* glue year from century and year in century */
|
||||
tmp->tm_year = bcd2bin( year ) +
|
||||
( bcd2bin( century & 0x3F ) * 100 );
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set( struct rtc_time *tmp )
|
||||
{
|
||||
uchar reg_a;
|
||||
#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
|
||||
/* lock clock registers for write */
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
|
||||
|
||||
rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
|
||||
|
||||
rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
|
||||
rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
|
||||
rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
|
||||
rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
|
||||
rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
|
||||
|
||||
/* break year up into century and year in century */
|
||||
rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
|
||||
rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
|
||||
|
||||
/* unlock clock registers after read */
|
||||
rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_WRITE ));
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
uchar reg_a, reg_b, reg_c;
|
||||
|
||||
reg_a = rtc_read( RTC_CONTROLA );
|
||||
reg_b = rtc_read( RTC_CONTROLB );
|
||||
|
||||
if ( reg_b & RTC_CB_OSC_DISABLE )
|
||||
{
|
||||
printf( "real-time-clock was stopped. Now starting...\n" );
|
||||
reg_a |= RTC_CA_WRITE;
|
||||
reg_b &= ~RTC_CB_OSC_DISABLE;
|
||||
|
||||
rtc_write( RTC_CONTROLA, reg_a );
|
||||
rtc_write( RTC_CONTROLB, reg_b );
|
||||
}
|
||||
|
||||
/* make sure read/write clock register bits are cleared */
|
||||
reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
|
||||
rtc_write( RTC_CONTROLA, reg_a );
|
||||
|
||||
reg_c = rtc_read( RTC_CONTROLC );
|
||||
if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
|
||||
printf( "RTC battery low. Clock setting may not be reliable.\n" );
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read( unsigned int addr )
|
||||
{
|
||||
uchar val = in8( addr );
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "rtc_read: %x:%x\n", addr, val );
|
||||
#endif
|
||||
return( val );
|
||||
}
|
||||
|
||||
static void rtc_write( unsigned int addr, uchar val )
|
||||
{
|
||||
#ifdef RTC_DEBUG
|
||||
printf( "rtc_write: %x:%x\n", addr, val );
|
||||
#endif
|
||||
out8( addr, val );
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_MC146818 && CFG_CMD_DATE */
|
202
rtc/m41t11.c
202
rtc/m41t11.c
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2002
|
||||
* Andrew May, Viasat Inc, amay@viasat.com
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* M41T11 Serial Access Timekeeper(R) SRAM
|
||||
* can you believe a trademark on that?
|
||||
*/
|
||||
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
/*
|
||||
I Don't have an example config file but this
|
||||
is what should be done.
|
||||
|
||||
#define CONFIG_RTC_M41T11 1
|
||||
#define CFG_I2C_RTC_ADDR 0x68
|
||||
#if 0
|
||||
#define CFG_M41T11_EXT_CENTURY_DATA
|
||||
#else
|
||||
#define CFG_M41T11_BASE_YEAR 2000
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_RTC_M41T11) && defined(CFG_I2C_RTC_ADDR) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*
|
||||
these are simple defines for the chip local to here so they aren't too
|
||||
verbose
|
||||
DAY/DATE aren't nice but that is how they are on the data sheet
|
||||
*/
|
||||
#define RTC_SEC_ADDR 0x0
|
||||
#define RTC_MIN_ADDR 0x1
|
||||
#define RTC_HOUR_ADDR 0x2
|
||||
#define RTC_DAY_ADDR 0x3
|
||||
#define RTC_DATE_ADDR 0x4
|
||||
#define RTC_MONTH_ADDR 0x5
|
||||
#define RTC_YEARS_ADDR 0x6
|
||||
|
||||
#define RTC_REG_CNT 7
|
||||
|
||||
#define RTC_CONTROL_ADDR 0x7
|
||||
|
||||
|
||||
#ifndef CFG_M41T11_EXT_CENTURY_DATA
|
||||
|
||||
#define REG_CNT (RTC_REG_CNT+1)
|
||||
|
||||
/*
|
||||
you only get 00-99 for the year we will asume you
|
||||
want from the year 2000 if you don't set the config
|
||||
*/
|
||||
#ifndef CFG_M41T11_BASE_YEAR
|
||||
#define CFG_M41T11_BASE_YEAR 2000
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* we will store extra year info in byte 9*/
|
||||
#define M41T11_YEAR_DATA 0x8
|
||||
#define M41T11_YEAR_SIZE 1
|
||||
#define REG_CNT (RTC_REG_CNT+1+M41T11_YEAR_SIZE)
|
||||
#endif
|
||||
|
||||
#define M41T11_STORAGE_SZ (64-REG_CNT)
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar data[RTC_REG_CNT];
|
||||
|
||||
i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
|
||||
|
||||
if( data[RTC_SEC_ADDR] & 0x80 ){
|
||||
printf( "m41t11 RTC Clock stopped!!!\n" );
|
||||
}
|
||||
tmp->tm_sec = bcd2bin (data[RTC_SEC_ADDR] & 0x7F);
|
||||
tmp->tm_min = bcd2bin (data[RTC_MIN_ADDR] & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (data[RTC_HOUR_ADDR] & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (data[RTC_DATE_ADDR] & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (data[RTC_MONTH_ADDR]& 0x1F);
|
||||
#ifndef CFG_M41T11_EXT_CENTURY_DATA
|
||||
tmp->tm_year = CFG_M41T11_BASE_YEAR
|
||||
+ bcd2bin(data[RTC_YEARS_ADDR])
|
||||
+ ((data[RTC_HOUR_ADDR]&0x40) ? 100 : 0);
|
||||
#else
|
||||
{
|
||||
unsigned char cent;
|
||||
i2c_read(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, ¢, M41T11_YEAR_SIZE);
|
||||
if( !(data[RTC_HOUR_ADDR] & 0x80) ){
|
||||
printf( "m41t11 RTC: cann't keep track of years without CEB set\n" );
|
||||
}
|
||||
if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){
|
||||
/*century flip store off new year*/
|
||||
cent += 1;
|
||||
i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, ¢, M41T11_YEAR_SIZE);
|
||||
}
|
||||
tmp->tm_year =((int)cent*100)+bcd2bin(data[RTC_YEARS_ADDR]);
|
||||
}
|
||||
#endif
|
||||
tmp->tm_wday = bcd2bin (data[RTC_DAY_ADDR] & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
debug ( "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);
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar data[RTC_REG_CNT];
|
||||
|
||||
debug ( "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);
|
||||
|
||||
data[RTC_SEC_ADDR] = bin2bcd(tmp->tm_sec) & 0x7F;/*just in case*/
|
||||
data[RTC_MIN_ADDR] = bin2bcd(tmp->tm_min);
|
||||
data[RTC_HOUR_ADDR] = bin2bcd(tmp->tm_hour) & 0x3F;/*handle cent stuff later*/
|
||||
data[RTC_DATE_ADDR] = bin2bcd(tmp->tm_mday) & 0x3F;
|
||||
data[RTC_MONTH_ADDR] = bin2bcd(tmp->tm_mon);
|
||||
data[RTC_DAY_ADDR] = bin2bcd(tmp->tm_wday) & 0x07;
|
||||
|
||||
data[RTC_HOUR_ADDR] |= 0x80;/*we will always use CEB*/
|
||||
|
||||
data[RTC_YEARS_ADDR] = bin2bcd(tmp->tm_year%100);/*same thing either way*/
|
||||
#ifndef CFG_M41T11_EXT_CENTURY_DATA
|
||||
if( ((tmp->tm_year - CFG_M41T11_BASE_YEAR) > 200) ||
|
||||
(tmp->tm_year < CFG_M41T11_BASE_YEAR) ){
|
||||
printf( "m41t11 RTC setting year out of range!!need recompile\n" );
|
||||
}
|
||||
data[RTC_HOUR_ADDR] |= (tmp->tm_year - CFG_M41T11_BASE_YEAR) > 100 ? 0x40 : 0;
|
||||
#else
|
||||
{
|
||||
unsigned char cent;
|
||||
cent = tmp->tm_year ? tmp->tm_year / 100 : 0;
|
||||
data[RTC_HOUR_ADDR] |= (cent & 0x1) ? 0x40 : 0;
|
||||
i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, ¢, M41T11_YEAR_SIZE);
|
||||
}
|
||||
#endif
|
||||
i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
unsigned char val;
|
||||
/* clear all control & status registers */
|
||||
i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, 1);
|
||||
val = val & 0x7F;/*make sure we are running*/
|
||||
i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, RTC_REG_CNT);
|
||||
|
||||
i2c_read(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
|
||||
val = val & 0x3F;/*turn off freq test keep calibration*/
|
||||
i2c_write(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
|
||||
}
|
||||
|
||||
int rtc_store(int addr, unsigned char* data, int size)
|
||||
{
|
||||
/*don't let things wrap onto the time on a write*/
|
||||
if( (addr+size) >= M41T11_STORAGE_SZ )
|
||||
return 1;
|
||||
return i2c_write( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
|
||||
}
|
||||
|
||||
int rtc_recall(int addr, unsigned char* data, int size)
|
||||
{
|
||||
return i2c_read( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_M41T11 && CFG_I2C_RTC_ADDR && CFG_CMD_DATE */
|
166
rtc/m48t35ax.c
166
rtc/m48t35ax.c
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Erik Theisen, Wave 7 Optics, etheisen@mindspring.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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for ST Electronics M48T35Ax RTC
|
||||
*/
|
||||
|
||||
/*#define DEBUG */
|
||||
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <config.h>
|
||||
|
||||
#if defined(CONFIG_RTC_M48T35A) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static uchar rtc_read (uchar reg);
|
||||
static void rtc_write (uchar reg, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin(uchar c);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, cent_day, date, month, year;
|
||||
uchar ccr; /* Clock control register */
|
||||
|
||||
/* Lock RTC for read using clock control register */
|
||||
ccr = rtc_read(0);
|
||||
ccr = ccr | 0x40;
|
||||
rtc_write(0, ccr);
|
||||
|
||||
sec = rtc_read (0x1);
|
||||
min = rtc_read (0x2);
|
||||
hour = rtc_read (0x3);
|
||||
cent_day= rtc_read (0x4);
|
||||
date = rtc_read (0x5);
|
||||
month = rtc_read (0x6);
|
||||
year = rtc_read (0x7);
|
||||
|
||||
/* UNLock RTC */
|
||||
ccr = rtc_read(0);
|
||||
ccr = ccr & 0xBF;
|
||||
rtc_write(0, ccr);
|
||||
|
||||
debug ( "Get RTC year: %02x month: %02x date: %02x cent_day: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, month, date, cent_day,
|
||||
hour, min, sec );
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (date & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (month & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year) + ((cent_day & 0x10) ? 2000 : 1900);
|
||||
tmp->tm_wday = bcd2bin (cent_day & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
debug ( "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);
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar ccr; /* Clock control register */
|
||||
uchar century;
|
||||
|
||||
debug ( "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);
|
||||
|
||||
/* Lock RTC for write using clock control register */
|
||||
ccr = rtc_read(0);
|
||||
ccr = ccr | 0x80;
|
||||
rtc_write(0, ccr);
|
||||
|
||||
rtc_write (0x07, bin2bcd(tmp->tm_year % 100));
|
||||
rtc_write (0x06, bin2bcd(tmp->tm_mon));
|
||||
rtc_write (0x05, bin2bcd(tmp->tm_mday));
|
||||
|
||||
century = ((tmp->tm_year >= 2000) ? 0x10 : 0) | 0x20;
|
||||
rtc_write (0x04, bin2bcd(tmp->tm_wday) | century);
|
||||
|
||||
rtc_write (0x03, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (0x02, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (0x01, bin2bcd(tmp->tm_sec ));
|
||||
|
||||
/* UNLock RTC */
|
||||
ccr = rtc_read(0);
|
||||
ccr = ccr & 0x7F;
|
||||
rtc_write(0, ccr);
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
uchar val;
|
||||
|
||||
/* Clear all clock control registers */
|
||||
rtc_write (0x0, 0x80); /* No Read Lock or calibration */
|
||||
|
||||
/* Clear stop bit */
|
||||
val = rtc_read (0x1);
|
||||
val &= 0x7f;
|
||||
rtc_write(0x1, val);
|
||||
|
||||
/* Enable century / disable frequency test */
|
||||
val = rtc_read (0x4);
|
||||
val = (val & 0xBF) | 0x20;
|
||||
rtc_write(0x4, val);
|
||||
|
||||
/* Clear write lock */
|
||||
rtc_write(0x0, 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
uchar val;
|
||||
val = *(unsigned char *)
|
||||
((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
*(unsigned char *)
|
||||
((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg) = val;
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_M48T35A && CFG_CMD_DATE */
|
131
rtc/max6900.c
131
rtc/max6900.c
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for MAXIM MAX6900 RTC
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if defined(CONFIG_RTC_MAX6900) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
#ifndef CFG_I2C_RTC_ADDR
|
||||
#define CFG_I2C_RTC_ADDR 0x50
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
udelay(2500);
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon, cent, year;
|
||||
int retry = 1;
|
||||
|
||||
do {
|
||||
sec = rtc_read (0x80);
|
||||
min = rtc_read (0x82);
|
||||
hour = rtc_read (0x84);
|
||||
mday = rtc_read (0x86);
|
||||
mon = rtc_read (0x88);
|
||||
wday = rtc_read (0x8a);
|
||||
year = rtc_read (0x8c);
|
||||
cent = rtc_read (0x92);
|
||||
/*
|
||||
* Check for seconds rollover
|
||||
*/
|
||||
if ((sec != 59) || (rtc_read(0x80) == sec)){
|
||||
retry = 0;
|
||||
}
|
||||
} while (retry);
|
||||
|
||||
debug ( "Get RTC year: %02x mon: %02x cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, cent, mday, wday,
|
||||
hour, min, sec );
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year) + bcd2bin(cent) * 100;
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
debug ( "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);
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
|
||||
debug ( "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);
|
||||
|
||||
rtc_write (0x9E, 0x00);
|
||||
rtc_write (0x80, 0); /* Clear seconds to ensure no rollover */
|
||||
rtc_write (0x92, bin2bcd(tmp->tm_year / 100));
|
||||
rtc_write (0x8c, bin2bcd(tmp->tm_year % 100));
|
||||
rtc_write (0x8a, bin2bcd(tmp->tm_wday));
|
||||
rtc_write (0x88, bin2bcd(tmp->tm_mon));
|
||||
rtc_write (0x86, bin2bcd(tmp->tm_mday));
|
||||
rtc_write (0x84, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (0x82, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (0x80, bin2bcd(tmp->tm_sec ));
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_MAX6900 && CFG_CMD_DATE */
|
178
rtc/mc146818.c
178
rtc/mc146818.c
|
@ -1,178 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Denis Peter MPL AG Switzerland. d.peter@mpl.ch
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the MC146818 (PIXX4) RTC
|
||||
*/
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_MC146818) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static uchar rtc_read (uchar reg);
|
||||
static void rtc_write (uchar reg, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin(uchar c);
|
||||
|
||||
#define RTC_PORT_MC146818 CFG_ISA_IO_BASE_ADDRESS + 0x70
|
||||
#define RTC_SECONDS 0x00
|
||||
#define RTC_SECONDS_ALARM 0x01
|
||||
#define RTC_MINUTES 0x02
|
||||
#define RTC_MINUTES_ALARM 0x03
|
||||
#define RTC_HOURS 0x04
|
||||
#define RTC_HOURS_ALARM 0x05
|
||||
#define RTC_DAY_OF_WEEK 0x06
|
||||
#define RTC_DATE_OF_MONTH 0x07
|
||||
#define RTC_MONTH 0x08
|
||||
#define RTC_YEAR 0x09
|
||||
#define RTC_CONFIG_A 0x0A
|
||||
#define RTC_CONFIG_B 0x0B
|
||||
#define RTC_CONFIG_C 0x0C
|
||||
#define RTC_CONFIG_D 0x0D
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
/* here check if rtc can be accessed */
|
||||
while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
|
||||
sec = rtc_read (RTC_SECONDS);
|
||||
min = rtc_read (RTC_MINUTES);
|
||||
hour = rtc_read (RTC_HOURS);
|
||||
mday = rtc_read (RTC_DATE_OF_MONTH);
|
||||
wday = rtc_read (RTC_DAY_OF_WEEK);
|
||||
mon = rtc_read (RTC_MONTH);
|
||||
year = rtc_read (RTC_YEAR);
|
||||
#ifdef CONFIG_AMIGAONEG3SE
|
||||
wday -= 1; /* VIA 686 stores Sunday = 1, Monday = 2, ... */
|
||||
#endif
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday,
|
||||
hour, min, sec );
|
||||
printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
|
||||
rtc_read (RTC_CONFIG_D) & 0x3F,
|
||||
rtc_read (RTC_HOURS_ALARM),
|
||||
rtc_read (RTC_MINUTES_ALARM),
|
||||
rtc_read (RTC_SECONDS_ALARM) );
|
||||
#endif
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year);
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
if(tmp->tm_year<70)
|
||||
tmp->tm_year+=2000;
|
||||
else
|
||||
tmp->tm_year+=1900;
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
#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
|
||||
rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
|
||||
|
||||
rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
|
||||
rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
|
||||
#ifdef CONFIG_AMIGAONEG3SE
|
||||
rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1);
|
||||
#else
|
||||
rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
|
||||
#endif
|
||||
rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
|
||||
rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
|
||||
rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
|
||||
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
|
||||
rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
|
||||
rtc_write(RTC_CONFIG_B,0x00);
|
||||
rtc_write(RTC_CONFIG_B,0x00);
|
||||
rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CFG_RTC_REG_BASE_ADDR
|
||||
/*
|
||||
* use direct memory access
|
||||
*/
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
return(in8(CFG_RTC_REG_BASE_ADDR+reg));
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
out8(CFG_RTC_REG_BASE_ADDR+reg, val);
|
||||
}
|
||||
#else
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
out8(RTC_PORT_MC146818,reg);
|
||||
return(in8(RTC_PORT_MC146818+1));
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
out8(RTC_PORT_MC146818,reg);
|
||||
out8(RTC_PORT_MC146818+1,val);
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_MC146818 && CFG_CMD_DATE */
|
237
rtc/mk48t59.c
237
rtc/mk48t59.c
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Andreas Heppel <aheppel@sysgo.de>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the MK48T59 RTC
|
||||
*/
|
||||
|
||||
#undef RTC_DEBUG
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <config.h>
|
||||
#include <rtc.h>
|
||||
#include <mk48t59.h>
|
||||
|
||||
#if defined(CONFIG_RTC_MK48T59)
|
||||
|
||||
#if defined(CONFIG_BAB7xx)
|
||||
|
||||
static uchar rtc_read (short reg)
|
||||
{
|
||||
out8(RTC_PORT_ADDR0, reg & 0xFF);
|
||||
out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
|
||||
return in8(RTC_PORT_DATA);
|
||||
}
|
||||
|
||||
static void rtc_write (short reg, uchar val)
|
||||
{
|
||||
out8(RTC_PORT_ADDR0, reg & 0xFF);
|
||||
out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
|
||||
out8(RTC_PORT_DATA, val);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_PCIPPC2)
|
||||
|
||||
#include "../board/pcippc2/pcippc2.h"
|
||||
|
||||
static uchar rtc_read (short reg)
|
||||
{
|
||||
return in8(RTC(reg));
|
||||
}
|
||||
|
||||
static void rtc_write (short reg, uchar val)
|
||||
{
|
||||
out8(RTC(reg),val);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_AMIGAONEG3SE)
|
||||
|
||||
#include "../board/MAI/AmigaOneG3SE/via686.h"
|
||||
#include "../board/MAI/AmigaOneG3SE/memio.h"
|
||||
|
||||
|
||||
static uchar rtc_read (short reg)
|
||||
{
|
||||
out_byte(CMOS_ADDR, (uint8)reg);
|
||||
return in_byte(CMOS_DATA);
|
||||
}
|
||||
|
||||
static void rtc_write (short reg, uchar val)
|
||||
{
|
||||
out_byte(CMOS_ADDR, (uint8)reg);
|
||||
out_byte(CMOS_DATA, (uint8)val);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_EVAL5200)
|
||||
|
||||
static uchar rtc_read (short reg)
|
||||
{
|
||||
return in8(RTC(reg));
|
||||
}
|
||||
|
||||
static void rtc_write (short reg, uchar val)
|
||||
{
|
||||
out8(RTC(reg),val);
|
||||
}
|
||||
|
||||
#else
|
||||
# error Board specific rtc access functions should be supplied
|
||||
#endif
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void *nvram_read(void *dest, const short src, size_t count)
|
||||
{
|
||||
uchar *d = (uchar *) dest;
|
||||
short s = src;
|
||||
|
||||
while (count--)
|
||||
*d++ = rtc_read(s++);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void nvram_write(short dest, const void *src, size_t count)
|
||||
{
|
||||
short d = dest;
|
||||
uchar *s = (uchar *) src;
|
||||
|
||||
while (count--)
|
||||
rtc_write(d++, *s++);
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar save_ctrl_a;
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
/* Simple: freeze the clock, read it and allow updates again */
|
||||
save_ctrl_a = rtc_read(RTC_CONTROLA);
|
||||
|
||||
/* Set the register to read the value. */
|
||||
save_ctrl_a |= RTC_CA_READ;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a);
|
||||
|
||||
sec = rtc_read (RTC_SECONDS);
|
||||
min = rtc_read (RTC_MINUTES);
|
||||
hour = rtc_read (RTC_HOURS);
|
||||
mday = rtc_read (RTC_DAY_OF_MONTH);
|
||||
wday = rtc_read (RTC_DAY_OF_WEEK);
|
||||
mon = rtc_read (RTC_MONTH);
|
||||
year = rtc_read (RTC_YEAR);
|
||||
|
||||
/* re-enable update */
|
||||
save_ctrl_a &= ~RTC_CA_READ;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a);
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday,
|
||||
hour, min, sec );
|
||||
#endif
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year);
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
if(tmp->tm_year<70)
|
||||
tmp->tm_year+=2000;
|
||||
else
|
||||
tmp->tm_year+=1900;
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar save_ctrl_a;
|
||||
|
||||
#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
|
||||
save_ctrl_a = rtc_read(RTC_CONTROLA);
|
||||
|
||||
save_ctrl_a |= RTC_CA_WRITE;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
|
||||
|
||||
rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
|
||||
rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
|
||||
|
||||
rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
|
||||
rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
|
||||
rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
|
||||
|
||||
save_ctrl_a &= ~RTC_CA_WRITE;
|
||||
rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
uchar control_b;
|
||||
|
||||
/*
|
||||
* Start oscillator here.
|
||||
*/
|
||||
control_b = rtc_read(RTC_CONTROLB);
|
||||
|
||||
control_b &= ~RTC_CB_STOP;
|
||||
rtc_write(RTC_CONTROLB, control_b);
|
||||
}
|
||||
|
||||
void rtc_set_watchdog(short multi, short res)
|
||||
{
|
||||
uchar wd_value;
|
||||
|
||||
wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
|
||||
rtc_write(RTC_WATCHDOG, wd_value);
|
||||
}
|
||||
|
||||
#endif /* (CONFIG_COMMANDS & CFG_CMD_DATE) */
|
||||
#endif /* CONFIG_RTC_MK48T59 */
|
140
rtc/mpc5xxx.c
140
rtc/mpc5xxx.c
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2004
|
||||
* Reinhard Meyer, EMK Elektronik GmbH
|
||||
* r.meyer@emk-elektronik.de
|
||||
* www.emk-elektronik.de
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* Date & Time support for internal RTC of MPC52xx
|
||||
*****************************************************************************/
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_MPC5200) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/*****************************************************************************
|
||||
* this structure should be defined in mpc5200.h ...
|
||||
*****************************************************************************/
|
||||
typedef struct rtc5200 {
|
||||
volatile ulong tsr; /* MBAR+0x800: time set register */
|
||||
volatile ulong dsr; /* MBAR+0x804: data set register */
|
||||
volatile ulong nysr; /* MBAR+0x808: new year and stopwatch register */
|
||||
volatile ulong aier; /* MBAR+0x80C: alarm and interrupt enable register */
|
||||
volatile ulong ctr; /* MBAR+0x810: current time register */
|
||||
volatile ulong cdr; /* MBAR+0x814: current data register */
|
||||
volatile ulong asir; /* MBAR+0x818: alarm and stopwatch interupt register */
|
||||
volatile ulong piber; /* MBAR+0x81C: periodic interrupt and bus error register */
|
||||
volatile ulong trdr; /* MBAR+0x820: test register/divides register */
|
||||
} RTC5200;
|
||||
|
||||
#define RTC_SET 0x02000000
|
||||
#define RTC_PAUSE 0x01000000
|
||||
|
||||
/*****************************************************************************
|
||||
* get time
|
||||
*****************************************************************************/
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800);
|
||||
ulong time, date, time2;
|
||||
|
||||
/* read twice to avoid getting a funny time when the second is just changing */
|
||||
do {
|
||||
time = rtc->ctr;
|
||||
date = rtc->cdr;
|
||||
time2 = rtc->ctr;
|
||||
} while (time != time2);
|
||||
|
||||
tmp->tm_year = date & 0xfff;
|
||||
tmp->tm_mon = (date >> 24) & 0xf;
|
||||
tmp->tm_mday = (date >> 16) & 0x1f;
|
||||
tmp->tm_wday = (date >> 21) & 7;
|
||||
/* sunday is 7 in 5200 but 0 in rtc_time */
|
||||
if (tmp->tm_wday == 7)
|
||||
tmp->tm_wday = 0;
|
||||
tmp->tm_hour = (time >> 16) & 0x1f;
|
||||
tmp->tm_min = (time >> 8) & 0x3f;
|
||||
tmp->tm_sec = time & 0x3f;
|
||||
|
||||
debug ( "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);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* set time
|
||||
*****************************************************************************/
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
RTC5200 *rtc = (RTC5200 *) (CFG_MBAR+0x800);
|
||||
ulong time, date, year;
|
||||
|
||||
debug ( "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);
|
||||
|
||||
time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
|
||||
date = (tmp->tm_mon << 16) | tmp->tm_mday;
|
||||
if (tmp->tm_wday == 0)
|
||||
date |= (7 << 8);
|
||||
else
|
||||
date |= (tmp->tm_wday << 8);
|
||||
year = tmp->tm_year;
|
||||
|
||||
/* mask unwanted bits that might show up when rtc_time is corrupt */
|
||||
time &= 0x001f3f3f;
|
||||
date &= 0x001f071f;
|
||||
year &= 0x00000fff;
|
||||
|
||||
/* pause and set the RTC */
|
||||
rtc->nysr = year;
|
||||
rtc->dsr = date | RTC_PAUSE;
|
||||
udelay (1000);
|
||||
rtc->dsr = date | RTC_PAUSE | RTC_SET;
|
||||
udelay (1000);
|
||||
rtc->dsr = date | RTC_PAUSE;
|
||||
udelay (1000);
|
||||
rtc->dsr = date;
|
||||
udelay (1000);
|
||||
|
||||
rtc->tsr = time | RTC_PAUSE;
|
||||
udelay (1000);
|
||||
rtc->tsr = time | RTC_PAUSE | RTC_SET;
|
||||
udelay (1000);
|
||||
rtc->tsr = time | RTC_PAUSE;
|
||||
udelay (1000);
|
||||
rtc->tsr = time;
|
||||
udelay (1000);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* reset rtc circuit
|
||||
*****************************************************************************/
|
||||
void rtc_reset (void)
|
||||
{
|
||||
return; /* nothing to do */
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_MPC5200 && CFG_CMD_DATE */
|
75
rtc/mpc8xx.c
75
rtc/mpc8xx.c
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for internal RTC of MPC8xx
|
||||
*/
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
|
||||
#if defined(CONFIG_RTC_MPC8xx) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
ulong tim;
|
||||
|
||||
tim = immr->im_sit.sit_rtc;
|
||||
|
||||
to_tm (tim, tmp);
|
||||
|
||||
debug ( "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);
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
volatile immap_t *immr = (immap_t *)CFG_IMMR;
|
||||
ulong tim;
|
||||
|
||||
debug ( "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);
|
||||
|
||||
tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
|
||||
|
||||
immr->im_sitk.sitk_rtck = KAPWR_KEY;
|
||||
immr->im_sit.sit_rtc = tim;
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
return; /* nothing to do */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif /* CONFIG_RTC_MPC8xx && CFG_CMD_DATE */
|
144
rtc/pcf8563.c
144
rtc/pcf8563.c
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for Philips PCF8563 RTC
|
||||
*/
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if defined(CONFIG_RTC_PCF8563) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
static uchar rtc_read (uchar reg);
|
||||
static void rtc_write (uchar reg, uchar val);
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin(uchar c);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
uchar sec, min, hour, mday, wday, mon_cent, year;
|
||||
|
||||
sec = rtc_read (0x02);
|
||||
min = rtc_read (0x03);
|
||||
hour = rtc_read (0x04);
|
||||
mday = rtc_read (0x05);
|
||||
wday = rtc_read (0x06);
|
||||
mon_cent= rtc_read (0x07);
|
||||
year = rtc_read (0x08);
|
||||
|
||||
debug ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon_cent, mday, wday,
|
||||
hour, min, sec );
|
||||
debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n",
|
||||
rtc_read (0x0C),
|
||||
rtc_read (0x0B),
|
||||
rtc_read (0x0A),
|
||||
rtc_read (0x09) );
|
||||
|
||||
if (sec & 0x80) {
|
||||
puts ("### Warning: RTC Low Voltage - date/time not reliable\n");
|
||||
}
|
||||
|
||||
tmp->tm_sec = bcd2bin (sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin (min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin (hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin (mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin (mon_cent & 0x1F);
|
||||
tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
|
||||
tmp->tm_wday = bcd2bin (wday & 0x07);
|
||||
tmp->tm_yday = 0;
|
||||
tmp->tm_isdst= 0;
|
||||
|
||||
debug ( "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);
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
uchar century;
|
||||
|
||||
debug ( "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);
|
||||
|
||||
rtc_write (0x08, bin2bcd(tmp->tm_year % 100));
|
||||
|
||||
century = (tmp->tm_year >= 2000) ? 0x80 : 0;
|
||||
rtc_write (0x07, bin2bcd(tmp->tm_mon) | century);
|
||||
|
||||
rtc_write (0x06, bin2bcd(tmp->tm_wday));
|
||||
rtc_write (0x05, bin2bcd(tmp->tm_mday));
|
||||
rtc_write (0x04, bin2bcd(tmp->tm_hour));
|
||||
rtc_write (0x03, bin2bcd(tmp->tm_min ));
|
||||
rtc_write (0x02, bin2bcd(tmp->tm_sec ));
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
/* clear all control & status registers */
|
||||
rtc_write (0x00, 0x00);
|
||||
rtc_write (0x01, 0x00);
|
||||
rtc_write (0x0D, 0x00);
|
||||
|
||||
/* clear Voltage Low bit */
|
||||
rtc_write (0x02, rtc_read (0x02) & 0x7F);
|
||||
|
||||
/* reset all alarms */
|
||||
rtc_write (0x09, 0x00);
|
||||
rtc_write (0x0A, 0x00);
|
||||
rtc_write (0x0B, 0x00);
|
||||
rtc_write (0x0C, 0x00);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static uchar rtc_read (uchar reg)
|
||||
{
|
||||
return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
|
||||
}
|
||||
|
||||
static void rtc_write (uchar reg, uchar val)
|
||||
{
|
||||
i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_PCF8563 && CFG_CMD_DATE */
|
302
rtc/rs5c372.c
302
rtc/rs5c372.c
|
@ -1,302 +0,0 @@
|
|||
/*
|
||||
* rs5c372.c
|
||||
*
|
||||
* Device driver for Ricoh's Real Time Controller RS5C372A.
|
||||
*
|
||||
* Copyright (C) 2004 Gary Jennejohn garyj@denx.de
|
||||
*
|
||||
* Based in part in ds1307.c -
|
||||
* (C) Copyright 2001, 2002, 2003
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* Keith Outwater, keith_outwater@mvis.com`
|
||||
* Steven Scholz, steven.scholz@imc-berlin.de
|
||||
*
|
||||
* 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 version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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>
|
||||
#include <command.h>
|
||||
#include <rtc.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#if defined(CONFIG_RTC_RS5C372A) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
/*
|
||||
* Reads are always done starting with register 15, which requires some
|
||||
* jumping-through-hoops to access the data correctly.
|
||||
*
|
||||
* Writes are always done starting with register 0.
|
||||
*/
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG
|
||||
static unsigned int rtc_debug = DEBUG;
|
||||
#else
|
||||
#define rtc_debug 0 /* gcc will remove all the debug code for us */
|
||||
#endif
|
||||
|
||||
#ifndef CFG_I2C_RTC_ADDR
|
||||
#define CFG_I2C_RTC_ADDR 0x32
|
||||
#endif
|
||||
|
||||
#define RS5C372_RAM_SIZE 0x10
|
||||
#define RATE_32000HZ 0x80 /* Rate Select 32.000KHz */
|
||||
#define RATE_32768HZ 0x00 /* Rate Select 32.768KHz */
|
||||
|
||||
#define STATUS_XPT 0x10 /* data invalid because voltage was 0 */
|
||||
|
||||
#define USE_24HOUR_MODE 0x20
|
||||
#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
|
||||
#define HOURS_AP(n) (((n) >> 5) & 1)
|
||||
#define HOURS_12(n) bcd2bin((n) & 0x1F)
|
||||
#define HOURS_24(n) bcd2bin((n) & 0x3F)
|
||||
|
||||
|
||||
static uchar bin2bcd (unsigned int n);
|
||||
static unsigned bcd2bin (uchar c);
|
||||
|
||||
static int setup_done = 0;
|
||||
|
||||
static int
|
||||
rs5c372_readram(unsigned char *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, len);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed to read\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (buf[0] & STATUS_XPT)
|
||||
printf("### Warning: RTC lost power\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
rs5c372_enable(void)
|
||||
{
|
||||
unsigned char buf[RS5C372_RAM_SIZE + 1];
|
||||
int ret;
|
||||
|
||||
/* note that this returns reg. 15 in buf[1] */
|
||||
ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
/* we want to start writing at register 0 so we have to copy the */
|
||||
/* register contents up one slot */
|
||||
for (ret = 2; ret < 9; ret++)
|
||||
buf[ret - 1] = buf[ret];
|
||||
/* registers 0 to 6 (time values) are not touched */
|
||||
buf[8] = RATE_32768HZ; /* reg. 7 */
|
||||
buf[9] = 0; /* reg. 8 */
|
||||
buf[10] = 0; /* reg. 9 */
|
||||
buf[11] = 0; /* reg. 10 */
|
||||
buf[12] = 0; /* reg. 11 */
|
||||
buf[13] = 0; /* reg. 12 */
|
||||
buf[14] = 0; /* reg. 13 */
|
||||
buf[15] = 0; /* reg. 14 */
|
||||
buf[16] = USE_24HOUR_MODE; /* reg. 15 */
|
||||
ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
setup_done = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
|
||||
{
|
||||
/* buf[0] is register 15 */
|
||||
dt->tm_sec = bcd2bin(buf[1]);
|
||||
dt->tm_min = bcd2bin(buf[2]);
|
||||
|
||||
if (TWELVE_HOUR_MODE(buf[0])) {
|
||||
dt->tm_hour = HOURS_12(buf[3]);
|
||||
if (HOURS_AP(buf[3])) /* PM */
|
||||
dt->tm_hour += 12;
|
||||
} else /* 24-hour-mode */
|
||||
dt->tm_hour = HOURS_24(buf[3]);
|
||||
|
||||
dt->tm_mday = bcd2bin(buf[5]);
|
||||
dt->tm_mon = bcd2bin(buf[6]);
|
||||
dt->tm_year = bcd2bin(buf[7]);
|
||||
if (dt->tm_year >= 70)
|
||||
dt->tm_year += 1900;
|
||||
else
|
||||
dt->tm_year += 2000;
|
||||
/* 0 is Sunday */
|
||||
dt->tm_wday = bcd2bin(buf[4] & 0x07);
|
||||
dt->tm_yday = 0;
|
||||
dt->tm_isdst= 0;
|
||||
|
||||
if(rtc_debug > 2) {
|
||||
printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
|
||||
printf("rs5c372_convert_to_time: mon = %d\n", dt->tm_mon);
|
||||
printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
|
||||
printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
|
||||
printf("rs5c372_convert_to_time: min = %d\n", dt->tm_min);
|
||||
printf("rs5c372_convert_to_time: sec = %d\n", dt->tm_sec);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current time from the RTC
|
||||
*/
|
||||
void
|
||||
rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned char buf[RS5C372_RAM_SIZE];
|
||||
int ret;
|
||||
|
||||
if (!setup_done)
|
||||
rs5c372_enable();
|
||||
|
||||
if (!setup_done)
|
||||
return;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
/* note that this returns reg. 15 in buf[0] */
|
||||
ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
|
||||
if (ret != 0) {
|
||||
printf("%s: failed\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
rs5c372_convert_to_time(tmp, buf);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the RTC
|
||||
*/
|
||||
void
|
||||
rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
unsigned char buf[8], reg15;
|
||||
int ret;
|
||||
|
||||
if (!setup_done)
|
||||
rs5c372_enable();
|
||||
|
||||
if (!setup_done)
|
||||
return;
|
||||
|
||||
if(rtc_debug > 2) {
|
||||
printf("rtc_set: tm_year = %d\n", tmp->tm_year);
|
||||
printf("rtc_set: tm_mon = %d\n", tmp->tm_mon);
|
||||
printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
|
||||
printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
|
||||
printf("rtc_set: tm_min = %d\n", tmp->tm_min);
|
||||
printf("rtc_set: tm_sec = %d\n", tmp->tm_sec);
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
/* only read register 15 */
|
||||
ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, 1);
|
||||
|
||||
if (ret == 0) {
|
||||
/* need to save register 15 */
|
||||
reg15 = buf[0];
|
||||
buf[0] = 0; /* register address on RS5C372 */
|
||||
buf[1] = bin2bcd(tmp->tm_sec);
|
||||
buf[2] = bin2bcd(tmp->tm_min);
|
||||
/* need to handle 12 hour mode */
|
||||
if (TWELVE_HOUR_MODE(reg15)) {
|
||||
if (tmp->tm_hour >= 12) { /* PM */
|
||||
/* 12 PM is a special case */
|
||||
if (tmp->tm_hour == 12)
|
||||
buf[3] = bin2bcd(tmp->tm_hour);
|
||||
else
|
||||
buf[3] = bin2bcd(tmp->tm_hour - 12);
|
||||
buf[3] |= 0x20;
|
||||
}
|
||||
} else {
|
||||
buf[3] = bin2bcd(tmp->tm_hour);
|
||||
}
|
||||
|
||||
buf[4] = bin2bcd(tmp->tm_wday);
|
||||
buf[5] = bin2bcd(tmp->tm_mday);
|
||||
buf[6] = bin2bcd(tmp->tm_mon);
|
||||
if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
|
||||
printf("WARNING: year should be between 1970 and 2069!\n");
|
||||
buf[7] = bin2bcd(tmp->tm_year % 100);
|
||||
|
||||
ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, 8);
|
||||
if (ret != 0)
|
||||
printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the RTC. We set the date back to 1970-01-01.
|
||||
*/
|
||||
void
|
||||
rtc_reset (void)
|
||||
{
|
||||
struct rtc_time tmp;
|
||||
|
||||
if (!setup_done)
|
||||
rs5c372_enable();
|
||||
|
||||
if (!setup_done)
|
||||
return;
|
||||
|
||||
tmp.tm_year = 1970;
|
||||
tmp.tm_mon = 1;
|
||||
/* Jan. 1, 1970 was a Thursday */
|
||||
tmp.tm_wday= 4;
|
||||
tmp.tm_mday= 1;
|
||||
tmp.tm_hour = 0;
|
||||
tmp.tm_min = 0;
|
||||
tmp.tm_sec = 0;
|
||||
|
||||
rtc_set(&tmp);
|
||||
|
||||
printf ("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n",
|
||||
tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
|
||||
tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
bcd2bin (unsigned char n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
#endif /* defined(CONFIG_RTC_RS5C372A) && (CONFIG_COMMANDS & CFG_CMD_DATE) */
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
* David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* Date & Time support for the built-in Samsung S3C24X0 RTC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
#if defined(CONFIG_RTC_S3C24X0) && (CONFIG_COMMANDS & CFG_CMD_DATE)
|
||||
|
||||
#if defined(CONFIG_S3C2400)
|
||||
#include <s3c2400.h>
|
||||
#elif defined(CONFIG_S3C2410)
|
||||
#include <s3c2410.h>
|
||||
#endif
|
||||
|
||||
#include <rtc.h>
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
typedef enum {
|
||||
RTC_ENABLE,
|
||||
RTC_DISABLE
|
||||
} RTC_ACCESS;
|
||||
|
||||
|
||||
static inline void SetRTC_Access(RTC_ACCESS a)
|
||||
{
|
||||
S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
|
||||
switch (a) {
|
||||
case RTC_ENABLE:
|
||||
rtc->RTCCON |= 0x01; break;
|
||||
|
||||
case RTC_DISABLE:
|
||||
rtc->RTCCON &= ~0x01; break;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned bcd2bin (uchar n)
|
||||
{
|
||||
return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
|
||||
}
|
||||
|
||||
static unsigned char bin2bcd (unsigned int n)
|
||||
{
|
||||
return (((n / 10) << 4) | (n % 10));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void rtc_get (struct rtc_time *tmp)
|
||||
{
|
||||
S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
uchar a_sec,a_min, a_hour, a_date, a_mon, a_year, a_armed;
|
||||
|
||||
/* enable access to RTC registers */
|
||||
SetRTC_Access(RTC_ENABLE);
|
||||
|
||||
/* read RTC registers */
|
||||
do {
|
||||
sec = rtc->BCDSEC;
|
||||
min = rtc->BCDMIN;
|
||||
hour = rtc->BCDHOUR;
|
||||
mday = rtc->BCDDATE;
|
||||
wday = rtc->BCDDAY;
|
||||
mon = rtc->BCDMON;
|
||||
year = rtc->BCDYEAR;
|
||||
} while (sec != rtc->BCDSEC);
|
||||
|
||||
/* read ALARM registers */
|
||||
a_sec = rtc->ALMSEC;
|
||||
a_min = rtc->ALMMIN;
|
||||
a_hour = rtc->ALMHOUR;
|
||||
a_date = rtc->ALMDATE;
|
||||
a_mon = rtc->ALMMON;
|
||||
a_year = rtc->ALMYEAR;
|
||||
a_armed = rtc->RTCALM;
|
||||
|
||||
/* disable access to RTC registers */
|
||||
SetRTC_Access(RTC_DISABLE);
|
||||
|
||||
#ifdef RTC_DEBUG
|
||||
printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
|
||||
"hr: %02x min: %02x sec: %02x\n",
|
||||
year, mon, mday, wday,
|
||||
hour, min, sec);
|
||||
printf ( "Alarms: %02x: year: %02x month: %02x date: %02x hour: %02x min: %02x sec: %02x\n",
|
||||
a_armed,
|
||||
a_year, a_mon, a_date,
|
||||
a_hour, a_min, a_sec);
|
||||
#endif
|
||||
|
||||
tmp->tm_sec = bcd2bin(sec & 0x7F);
|
||||
tmp->tm_min = bcd2bin(min & 0x7F);
|
||||
tmp->tm_hour = bcd2bin(hour & 0x3F);
|
||||
tmp->tm_mday = bcd2bin(mday & 0x3F);
|
||||
tmp->tm_mon = bcd2bin(mon & 0x1F);
|
||||
tmp->tm_year = bcd2bin(year);
|
||||
tmp->tm_wday = bcd2bin(wday & 0x07);
|
||||
if(tmp->tm_year<70)
|
||||
tmp->tm_year+=2000;
|
||||
else
|
||||
tmp->tm_year+=1900;
|
||||
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
|
||||
}
|
||||
|
||||
void rtc_set (struct rtc_time *tmp)
|
||||
{
|
||||
S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
|
||||
uchar sec, min, hour, mday, wday, mon, year;
|
||||
|
||||
#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
|
||||
year = bin2bcd(tmp->tm_year % 100);
|
||||
mon = bin2bcd(tmp->tm_mon);
|
||||
wday = bin2bcd(tmp->tm_wday);
|
||||
mday = bin2bcd(tmp->tm_mday);
|
||||
hour = bin2bcd(tmp->tm_hour);
|
||||
min = bin2bcd(tmp->tm_min);
|
||||
sec = bin2bcd(tmp->tm_sec);
|
||||
|
||||
/* enable access to RTC registers */
|
||||
SetRTC_Access(RTC_ENABLE);
|
||||
|
||||
/* write RTC registers */
|
||||
rtc->BCDSEC = sec;
|
||||
rtc->BCDMIN = min;
|
||||
rtc->BCDHOUR = hour;
|
||||
rtc->BCDDATE = mday;
|
||||
rtc->BCDDAY = wday;
|
||||
rtc->BCDMON = mon;
|
||||
rtc->BCDYEAR = year;
|
||||
|
||||
/* disable access to RTC registers */
|
||||
SetRTC_Access(RTC_DISABLE);
|
||||
}
|
||||
|
||||
void rtc_reset (void)
|
||||
{
|
||||
S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
|
||||
|
||||
rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
|
||||
rtc->RTCCON &= ~(0x08|0x01);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif /* CONFIG_RTC_S3C24X0 && CFG_CMD_DATE */
|
Loading…
Reference in New Issue