uboot/drivers/rtc/ds1307.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001, 2002, 2003
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 * Keith Outwater, keith_outwater@mvis.com`
   5 * Steven Scholz, steven.scholz@imc-berlin.de
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10/*
  11 * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
  12 * DS1307 and DS1338/9 Real Time Clock (RTC).
  13 *
  14 * based on ds1337.c
  15 */
  16
  17#include <common.h>
  18#include <command.h>
  19#include <rtc.h>
  20#include <i2c.h>
  21
  22#if defined(CONFIG_CMD_DATE)
  23
  24/*---------------------------------------------------------------------*/
  25#undef DEBUG_RTC
  26
  27#ifdef DEBUG_RTC
  28#define DEBUGR(fmt,args...) printf(fmt ,##args)
  29#else
  30#define DEBUGR(fmt,args...)
  31#endif
  32/*---------------------------------------------------------------------*/
  33
  34#ifndef CONFIG_SYS_I2C_RTC_ADDR
  35# define CONFIG_SYS_I2C_RTC_ADDR        0x68
  36#endif
  37
  38#if defined(CONFIG_RTC_DS1307) && (CONFIG_SYS_I2C_SPEED > 100000)
  39# error The DS1307 is specified only up to 100kHz!
  40#endif
  41
  42/*
  43 * RTC register addresses
  44 */
  45#define RTC_SEC_REG_ADDR        0x00
  46#define RTC_MIN_REG_ADDR        0x01
  47#define RTC_HR_REG_ADDR         0x02
  48#define RTC_DAY_REG_ADDR        0x03
  49#define RTC_DATE_REG_ADDR       0x04
  50#define RTC_MON_REG_ADDR        0x05
  51#define RTC_YR_REG_ADDR         0x06
  52#define RTC_CTL_REG_ADDR        0x07
  53
  54#define RTC_SEC_BIT_CH          0x80    /* Clock Halt (in Register 0)   */
  55
  56#define RTC_CTL_BIT_RS0         0x01    /* Rate select 0                */
  57#define RTC_CTL_BIT_RS1         0x02    /* Rate select 1                */
  58#define RTC_CTL_BIT_SQWE        0x10    /* Square Wave Enable           */
  59#define RTC_CTL_BIT_OUT         0x80    /* Output Control               */
  60
  61/* MCP7941X-specific bits */
  62#define MCP7941X_BIT_ST         0x80
  63#define MCP7941X_BIT_VBATEN     0x08
  64
  65static uchar rtc_read (uchar reg);
  66static void rtc_write (uchar reg, uchar val);
  67
  68/*
  69 * Get the current time from the RTC
  70 */
  71int rtc_get (struct rtc_time *tmp)
  72{
  73        int rel = 0;
  74        uchar sec, min, hour, mday, wday, mon, year;
  75
  76#ifdef CONFIG_RTC_MCP79411
  77read_rtc:
  78#endif
  79        sec = rtc_read (RTC_SEC_REG_ADDR);
  80        min = rtc_read (RTC_MIN_REG_ADDR);
  81        hour = rtc_read (RTC_HR_REG_ADDR);
  82        wday = rtc_read (RTC_DAY_REG_ADDR);
  83        mday = rtc_read (RTC_DATE_REG_ADDR);
  84        mon = rtc_read (RTC_MON_REG_ADDR);
  85        year = rtc_read (RTC_YR_REG_ADDR);
  86
  87        DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
  88                "hr: %02x min: %02x sec: %02x\n",
  89                year, mon, mday, wday, hour, min, sec);
  90
  91#ifdef CONFIG_RTC_DS1307
  92        if (sec & RTC_SEC_BIT_CH) {
  93                printf ("### Warning: RTC oscillator has stopped\n");
  94                /* clear the CH flag */
  95                rtc_write (RTC_SEC_REG_ADDR,
  96                           rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH);
  97                rel = -1;
  98        }
  99#endif
 100
 101#ifdef CONFIG_RTC_MCP79411
 102        /* make sure that the backup battery is enabled */
 103        if (!(wday & MCP7941X_BIT_VBATEN)) {
 104                rtc_write(RTC_DAY_REG_ADDR,
 105                          wday | MCP7941X_BIT_VBATEN);
 106        }
 107
 108        /* clock halted?  turn it on, so clock can tick. */
 109        if (!(sec & MCP7941X_BIT_ST)) {
 110                rtc_write(RTC_SEC_REG_ADDR, MCP7941X_BIT_ST);
 111                printf("Started RTC\n");
 112                goto read_rtc;
 113        }
 114#endif
 115
 116
 117        tmp->tm_sec  = bcd2bin (sec & 0x7F);
 118        tmp->tm_min  = bcd2bin (min & 0x7F);
 119        tmp->tm_hour = bcd2bin (hour & 0x3F);
 120        tmp->tm_mday = bcd2bin (mday & 0x3F);
 121        tmp->tm_mon  = bcd2bin (mon & 0x1F);
 122        tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
 123        tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
 124        tmp->tm_yday = 0;
 125        tmp->tm_isdst= 0;
 126
 127        DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 128                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 129                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 130
 131        return rel;
 132}
 133
 134
 135/*
 136 * Set the RTC
 137 */
 138int rtc_set (struct rtc_time *tmp)
 139{
 140        DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 141                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 142                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 143
 144        if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
 145                printf("WARNING: year should be between 1970 and 2069!\n");
 146
 147        rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
 148        rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
 149#ifdef CONFIG_RTC_MCP79411
 150        rtc_write (RTC_DAY_REG_ADDR,
 151                   bin2bcd (tmp->tm_wday + 1) | MCP7941X_BIT_VBATEN);
 152#else
 153        rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
 154#endif
 155        rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
 156        rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
 157        rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
 158#ifdef CONFIG_RTC_MCP79411
 159        rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec) | MCP7941X_BIT_ST);
 160#else
 161        rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
 162#endif
 163
 164        return 0;
 165}
 166
 167
 168/*
 169 * Reset the RTC. We setting the date back to 1970-01-01.
 170 * We also enable the oscillator output on the SQW/OUT pin and program
 171 * it for 32,768 Hz output. Note that according to the datasheet, turning
 172 * on the square wave output increases the current drain on the backup
 173 * battery to something between 480nA and 800nA.
 174 */
 175void rtc_reset (void)
 176{
 177        struct rtc_time tmp;
 178
 179        rtc_write (RTC_SEC_REG_ADDR, 0x00);     /* clearing Clock Halt  */
 180        rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS0);
 181
 182        tmp.tm_year = 1970;
 183        tmp.tm_mon = 1;
 184        tmp.tm_mday= 1;
 185        tmp.tm_hour = 0;
 186        tmp.tm_min = 0;
 187        tmp.tm_sec = 0;
 188
 189        rtc_set(&tmp);
 190
 191        printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
 192                tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
 193                tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
 194
 195        return;
 196}
 197
 198
 199/*
 200 * Helper functions
 201 */
 202
 203static
 204uchar rtc_read (uchar reg)
 205{
 206        return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
 207}
 208
 209
 210static void rtc_write (uchar reg, uchar val)
 211{
 212        i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
 213}
 214#endif
 215