uboot/drivers/rtc/ds1337.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2001-2008
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 * Keith Outwater, keith_outwater@mvis.com`
   6 */
   7
   8/*
   9 * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
  10 * DS1337 Real Time Clock (RTC).
  11 */
  12
  13#include <common.h>
  14#include <command.h>
  15#include <rtc.h>
  16#include <i2c.h>
  17
  18/*
  19 * RTC register addresses
  20 */
  21#if defined CONFIG_RTC_DS1337
  22#define RTC_SEC_REG_ADDR        0x0
  23#define RTC_MIN_REG_ADDR        0x1
  24#define RTC_HR_REG_ADDR         0x2
  25#define RTC_DAY_REG_ADDR        0x3
  26#define RTC_DATE_REG_ADDR       0x4
  27#define RTC_MON_REG_ADDR        0x5
  28#define RTC_YR_REG_ADDR         0x6
  29#define RTC_CTL_REG_ADDR        0x0e
  30#define RTC_STAT_REG_ADDR       0x0f
  31#define RTC_TC_REG_ADDR         0x10
  32#elif defined CONFIG_RTC_DS1388
  33#define RTC_SEC_REG_ADDR        0x1
  34#define RTC_MIN_REG_ADDR        0x2
  35#define RTC_HR_REG_ADDR         0x3
  36#define RTC_DAY_REG_ADDR        0x4
  37#define RTC_DATE_REG_ADDR       0x5
  38#define RTC_MON_REG_ADDR        0x6
  39#define RTC_YR_REG_ADDR         0x7
  40#define RTC_CTL_REG_ADDR        0x0c
  41#define RTC_STAT_REG_ADDR       0x0b
  42#define RTC_TC_REG_ADDR         0x0a
  43#endif
  44
  45/*
  46 * RTC control register bits
  47 */
  48#define RTC_CTL_BIT_A1IE        0x1     /* Alarm 1 interrupt enable     */
  49#define RTC_CTL_BIT_A2IE        0x2     /* Alarm 2 interrupt enable     */
  50#define RTC_CTL_BIT_INTCN       0x4     /* Interrupt control            */
  51#define RTC_CTL_BIT_RS1         0x8     /* Rate select 1                */
  52#define RTC_CTL_BIT_RS2         0x10    /* Rate select 2                */
  53#define RTC_CTL_BIT_DOSC        0x80    /* Disable Oscillator           */
  54
  55/*
  56 * RTC status register bits
  57 */
  58#define RTC_STAT_BIT_A1F        0x1     /* Alarm 1 flag                 */
  59#define RTC_STAT_BIT_A2F        0x2     /* Alarm 2 flag                 */
  60#define RTC_STAT_BIT_OSF        0x80    /* Oscillator stop flag         */
  61
  62
  63static uchar rtc_read (uchar reg);
  64static void rtc_write (uchar reg, uchar val);
  65
  66/*
  67 * Get the current time from the RTC
  68 */
  69int rtc_get (struct rtc_time *tmp)
  70{
  71        int rel = 0;
  72        uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
  73
  74        control = rtc_read (RTC_CTL_REG_ADDR);
  75        status = rtc_read (RTC_STAT_REG_ADDR);
  76        sec = rtc_read (RTC_SEC_REG_ADDR);
  77        min = rtc_read (RTC_MIN_REG_ADDR);
  78        hour = rtc_read (RTC_HR_REG_ADDR);
  79        wday = rtc_read (RTC_DAY_REG_ADDR);
  80        mday = rtc_read (RTC_DATE_REG_ADDR);
  81        mon_cent = rtc_read (RTC_MON_REG_ADDR);
  82        year = rtc_read (RTC_YR_REG_ADDR);
  83
  84        /* No century bit, assume year 2000 */
  85#ifdef CONFIG_RTC_DS1388
  86        mon_cent |= 0x80;
  87#endif
  88
  89        debug("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
  90                "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
  91                year, mon_cent, mday, wday, hour, min, sec, control, status);
  92
  93        if (status & RTC_STAT_BIT_OSF) {
  94                printf ("### Warning: RTC oscillator has stopped\n");
  95                /* clear the OSF flag */
  96                rtc_write (RTC_STAT_REG_ADDR,
  97                           rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
  98                rel = -1;
  99        }
 100
 101        tmp->tm_sec  = bcd2bin (sec & 0x7F);
 102        tmp->tm_min  = bcd2bin (min & 0x7F);
 103        tmp->tm_hour = bcd2bin (hour & 0x3F);
 104        tmp->tm_mday = bcd2bin (mday & 0x3F);
 105        tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
 106        tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
 107        tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
 108        tmp->tm_yday = 0;
 109        tmp->tm_isdst= 0;
 110
 111        debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 112                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 113                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 114
 115        return rel;
 116}
 117
 118
 119/*
 120 * Set the RTC
 121 */
 122int rtc_set (struct rtc_time *tmp)
 123{
 124        uchar century;
 125
 126        debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 127                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 128                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 129
 130        rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
 131
 132        century = (tmp->tm_year >= 2000) ? 0x80 : 0;
 133        rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
 134
 135        rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
 136        rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
 137        rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
 138        rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
 139        rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
 140
 141        return 0;
 142}
 143
 144
 145/*
 146 * Reset the RTC.  We also enable the oscillator output on the
 147 * SQW/INTB* pin and program it for 32,768 Hz output. Note that
 148 * according to the datasheet, turning on the square wave output
 149 * increases the current drain on the backup battery from about
 150 * 600 nA to 2uA. Define CONFIG_RTC_DS1337_NOOSC if you wish to turn
 151 * off the OSC output.
 152 */
 153
 154#ifdef CONFIG_RTC_DS1337_NOOSC
 155 #define RTC_DS1337_RESET_VAL \
 156        (RTC_CTL_BIT_INTCN | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
 157#else
 158 #define RTC_DS1337_RESET_VAL (RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
 159#endif
 160void rtc_reset (void)
 161{
 162#ifdef CONFIG_RTC_DS1337
 163        rtc_write (RTC_CTL_REG_ADDR, RTC_DS1337_RESET_VAL);
 164#elif defined CONFIG_RTC_DS1388
 165        rtc_write(RTC_CTL_REG_ADDR, 0x0); /* hw default */
 166#endif
 167#ifdef CONFIG_RTC_DS1339_TCR_VAL
 168        rtc_write (RTC_TC_REG_ADDR, CONFIG_RTC_DS1339_TCR_VAL);
 169#endif
 170#ifdef CONFIG_RTC_DS1388_TCR_VAL
 171        rtc_write(RTC_TC_REG_ADDR, CONFIG_RTC_DS1388_TCR_VAL);
 172#endif
 173}
 174
 175
 176/*
 177 * Helper functions
 178 */
 179
 180static
 181uchar rtc_read (uchar reg)
 182{
 183        return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
 184}
 185
 186
 187static void rtc_write (uchar reg, uchar val)
 188{
 189        i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
 190}
 191