uboot/drivers/rtc/ds164x.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * ARIO Data Networks, Inc. dchiu@ariodata.com
   4 *
   5 * modified for DS164x:
   6 * The LEOX team <team@leox.org>, http://www.leox.org
   7 *
   8 * Based on MontaVista DS1743 code and U-Boot mc146818 code
   9 *
  10 * SPDX-License-Identifier:     GPL-2.0+
  11 */
  12
  13/*
  14 * Date & Time support for the DS164x RTC
  15 */
  16
  17/* #define      RTC_DEBUG */
  18
  19#include <common.h>
  20#include <command.h>
  21#include <rtc.h>
  22
  23
  24#if defined(CONFIG_CMD_DATE)
  25
  26static uchar    rtc_read(unsigned int addr );
  27static void     rtc_write(unsigned int addr, uchar val);
  28
  29#define RTC_EPOCH                 2000  /* century */
  30
  31/*
  32 * DS164x registers layout
  33 */
  34#define RTC_BASE                ( CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE )
  35
  36#define RTC_YEAR                ( RTC_BASE + 0x07 )
  37#define RTC_MONTH               ( RTC_BASE + 0x06 )
  38#define RTC_DAY_OF_MONTH        ( RTC_BASE + 0x05 )
  39#define RTC_DAY_OF_WEEK         ( RTC_BASE + 0x04 )
  40#define RTC_HOURS               ( RTC_BASE + 0x03 )
  41#define RTC_MINUTES             ( RTC_BASE + 0x02 )
  42#define RTC_SECONDS             ( RTC_BASE + 0x01 )
  43#define RTC_CONTROL             ( RTC_BASE + 0x00 )
  44
  45#define RTC_CONTROLA            RTC_CONTROL     /* W=bit6, R=bit5 */
  46#define   RTC_CA_WRITE            0x80
  47#define   RTC_CA_READ             0x40
  48#define RTC_CONTROLB            RTC_SECONDS     /* OSC=bit7       */
  49#define   RTC_CB_OSC_DISABLE      0x80
  50#define RTC_CONTROLC            RTC_DAY_OF_WEEK /* FT=bit6        */
  51#define   RTC_CC_FREQ_TEST        0x40
  52
  53/* ------------------------------------------------------------------------- */
  54
  55int rtc_get( struct rtc_time *tmp )
  56{
  57        uchar sec, min, hour;
  58        uchar mday, wday, mon, year;
  59
  60        uchar reg_a;
  61
  62        reg_a = rtc_read( RTC_CONTROLA );
  63        /* lock clock registers for read */
  64        rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
  65
  66        sec     = rtc_read( RTC_SECONDS );
  67        min     = rtc_read( RTC_MINUTES );
  68        hour    = rtc_read( RTC_HOURS );
  69        mday    = rtc_read( RTC_DAY_OF_MONTH );
  70        wday    = rtc_read( RTC_DAY_OF_WEEK );
  71        mon     = rtc_read( RTC_MONTH );
  72        year    = rtc_read( RTC_YEAR );
  73
  74        /* unlock clock registers after read */
  75        rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
  76
  77#ifdef RTC_DEBUG
  78        printf( "Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
  79                "hr: %02x min: %02x sec: %02x\n",
  80                year, mon, mday, wday,
  81                hour, min, sec );
  82#endif
  83        tmp->tm_sec  = bcd2bin( sec  & 0x7F );
  84        tmp->tm_min  = bcd2bin( min  & 0x7F );
  85        tmp->tm_hour = bcd2bin( hour & 0x3F );
  86        tmp->tm_mday = bcd2bin( mday & 0x3F );
  87        tmp->tm_mon  = bcd2bin( mon  & 0x1F );
  88        tmp->tm_wday = bcd2bin( wday & 0x07 );
  89
  90        /* glue year in century (2000) */
  91        tmp->tm_year = bcd2bin( year ) + RTC_EPOCH;
  92
  93        tmp->tm_yday = 0;
  94        tmp->tm_isdst= 0;
  95#ifdef RTC_DEBUG
  96        printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
  97                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
  98                tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
  99#endif
 100
 101        return 0;
 102}
 103
 104int rtc_set( struct rtc_time *tmp )
 105{
 106        uchar reg_a;
 107
 108#ifdef RTC_DEBUG
 109        printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 110                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 111                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 112#endif
 113        /* lock clock registers for write */
 114        reg_a = rtc_read( RTC_CONTROLA );
 115        rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
 116
 117        rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
 118
 119        rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
 120        rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
 121        rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
 122        rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
 123        rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
 124
 125        /* break year in century */
 126        rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
 127
 128        /* unlock clock registers after read */
 129        rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
 130
 131        return 0;
 132}
 133
 134void rtc_reset (void)
 135{
 136        uchar reg_a, reg_b;
 137
 138        reg_a = rtc_read( RTC_CONTROLA );
 139        reg_b = rtc_read( RTC_CONTROLB );
 140
 141        if ( reg_b & RTC_CB_OSC_DISABLE )
 142        {
 143                printf( "real-time-clock was stopped. Now starting...\n" );
 144                reg_a |= RTC_CA_WRITE;
 145                reg_b &= ~RTC_CB_OSC_DISABLE;
 146
 147                rtc_write( RTC_CONTROLA, reg_a );
 148                rtc_write( RTC_CONTROLB, reg_b );
 149        }
 150
 151        /* make sure read/write clock register bits are cleared */
 152        reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
 153        rtc_write( RTC_CONTROLA, reg_a );
 154}
 155
 156/* ------------------------------------------------------------------------- */
 157
 158static uchar rtc_read( unsigned int addr )
 159{
 160        uchar val = *(volatile unsigned char*)(addr);
 161
 162#ifdef RTC_DEBUG
 163        printf( "rtc_read: %x:%x\n", addr, val );
 164#endif
 165        return( val );
 166}
 167
 168static void rtc_write( unsigned int addr, uchar val )
 169{
 170#ifdef RTC_DEBUG
 171        printf( "rtc_write: %x:%x\n", addr, val );
 172#endif
 173        *(volatile unsigned char*)(addr) = val;
 174}
 175
 176#endif
 177