uboot/drivers/rtc/rx8025.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007
   3 * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8/*
   9 * Epson RX8025 RTC driver.
  10 */
  11
  12#include <common.h>
  13#include <command.h>
  14#include <rtc.h>
  15#include <i2c.h>
  16
  17#if defined(CONFIG_CMD_DATE)
  18
  19/*---------------------------------------------------------------------*/
  20#undef DEBUG_RTC
  21
  22#ifdef DEBUG_RTC
  23#define DEBUGR(fmt,args...) printf(fmt ,##args)
  24#else
  25#define DEBUGR(fmt,args...)
  26#endif
  27/*---------------------------------------------------------------------*/
  28
  29#ifndef CONFIG_SYS_I2C_RTC_ADDR
  30# define CONFIG_SYS_I2C_RTC_ADDR        0x32
  31#endif
  32
  33/*
  34 * RTC register addresses
  35 */
  36#define RTC_SEC_REG_ADDR        0x00
  37#define RTC_MIN_REG_ADDR        0x01
  38#define RTC_HR_REG_ADDR         0x02
  39#define RTC_DAY_REG_ADDR        0x03
  40#define RTC_DATE_REG_ADDR       0x04
  41#define RTC_MON_REG_ADDR        0x05
  42#define RTC_YR_REG_ADDR         0x06
  43
  44#define RTC_CTL1_REG_ADDR       0x0e
  45#define RTC_CTL2_REG_ADDR       0x0f
  46
  47/*
  48 * Control register 1 bits
  49 */
  50#define RTC_CTL1_BIT_2412       0x20
  51
  52/*
  53 * Control register 2 bits
  54 */
  55#define RTC_CTL2_BIT_PON        0x10
  56#define RTC_CTL2_BIT_VDET       0x40
  57#define RTC_CTL2_BIT_XST        0x20
  58#define RTC_CTL2_BIT_VDSL       0x80
  59
  60/*
  61 * Note: the RX8025 I2C RTC requires register
  62 * reads and write to consist of a single bus
  63 * cycle. It is not allowed to write the register
  64 * address in a first cycle that is terminated by
  65 * a STOP condition. The chips needs a 'restart'
  66 * sequence (start sequence without a prior stop).
  67 * This driver has been written for a 4xx board.
  68 * U-Boot's 4xx i2c driver is currently not capable
  69 * to generate such cycles to some work arounds
  70 * are used.
  71 */
  72
  73/* static uchar rtc_read (uchar reg); */
  74#define rtc_read(reg) buf[((reg) + 1) & 0xf]
  75
  76static void rtc_write (uchar reg, uchar val);
  77
  78/*
  79 * Get the current time from the RTC
  80 */
  81int rtc_get (struct rtc_time *tmp)
  82{
  83        int rel = 0;
  84        uchar sec, min, hour, mday, wday, mon, year, ctl2;
  85        uchar buf[16];
  86
  87        if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 16))
  88                printf("Error reading from RTC\n");
  89
  90        sec = rtc_read(RTC_SEC_REG_ADDR);
  91        min = rtc_read(RTC_MIN_REG_ADDR);
  92        hour = rtc_read(RTC_HR_REG_ADDR);
  93        wday = rtc_read(RTC_DAY_REG_ADDR);
  94        mday = rtc_read(RTC_DATE_REG_ADDR);
  95        mon = rtc_read(RTC_MON_REG_ADDR);
  96        year = rtc_read(RTC_YR_REG_ADDR);
  97
  98        DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
  99                "hr: %02x min: %02x sec: %02x\n",
 100                year, mon, mday, wday, hour, min, sec);
 101
 102        /* dump status */
 103        ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
 104        if (ctl2 & RTC_CTL2_BIT_PON) {
 105                printf("RTC: power-on detected\n");
 106                rel = -1;
 107        }
 108
 109        if (ctl2 & RTC_CTL2_BIT_VDET) {
 110                printf("RTC: voltage drop detected\n");
 111                rel = -1;
 112        }
 113
 114        if (!(ctl2 & RTC_CTL2_BIT_XST)) {
 115                printf("RTC: oscillator stop detected\n");
 116                rel = -1;
 117        }
 118
 119        tmp->tm_sec  = bcd2bin (sec & 0x7F);
 120        tmp->tm_min  = bcd2bin (min & 0x7F);
 121        if (rtc_read(RTC_CTL1_REG_ADDR) & RTC_CTL1_BIT_2412)
 122                tmp->tm_hour = bcd2bin (hour & 0x3F);
 123        else
 124                tmp->tm_hour = bcd2bin (hour & 0x1F) % 12 +
 125                               ((hour & 0x20) ? 12 : 0);
 126        tmp->tm_mday = bcd2bin (mday & 0x3F);
 127        tmp->tm_mon  = bcd2bin (mon & 0x1F);
 128        tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
 129        tmp->tm_wday = bcd2bin (wday & 0x07);
 130        tmp->tm_yday = 0;
 131        tmp->tm_isdst= 0;
 132
 133        DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 134                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 135                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 136
 137        return rel;
 138}
 139
 140/*
 141 * Set the RTC
 142 */
 143int rtc_set (struct rtc_time *tmp)
 144{
 145        DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 146                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 147                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 148
 149        if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
 150                printf("WARNING: year should be between 1970 and 2069!\n");
 151
 152        rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
 153        rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
 154        rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday));
 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        rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
 159
 160        rtc_write (RTC_CTL1_REG_ADDR, RTC_CTL1_BIT_2412);
 161
 162        return 0;
 163}
 164
 165/*
 166 * Reset the RTC. We setting the date back to 1970-01-01.
 167 */
 168void rtc_reset (void)
 169{
 170        struct rtc_time tmp;
 171        uchar buf[16];
 172        uchar ctl2;
 173
 174        if (i2c_read(CONFIG_SYS_I2C_RTC_ADDR, 0,    0,   buf, 16))
 175                printf("Error reading from RTC\n");
 176
 177        ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
 178        ctl2 &= ~(RTC_CTL2_BIT_PON | RTC_CTL2_BIT_VDET);
 179        ctl2 |= RTC_CTL2_BIT_XST | RTC_CTL2_BIT_VDSL;
 180        rtc_write (RTC_CTL2_REG_ADDR, ctl2);
 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 * Helper functions
 200 */
 201static void rtc_write (uchar reg, uchar val)
 202{
 203        uchar buf[2];
 204        buf[0] = reg << 4;
 205        buf[1] = val;
 206        if (i2c_write(CONFIG_SYS_I2C_RTC_ADDR, 0, 0, buf, 2) != 0)
 207                printf("Error writing to RTC\n");
 208
 209}
 210
 211#endif /* CONFIG_RTC_RX8025 && CONFIG_CMD_DATE */
 212