uboot/drivers/rtc/rx8025.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2007
   4 * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com.
   5 */
   6
   7/*
   8 * Epson RX8025 RTC driver.
   9 */
  10
  11#include <common.h>
  12#include <command.h>
  13#include <dm.h>
  14#include <i2c.h>
  15#include <rtc.h>
  16
  17/*---------------------------------------------------------------------*/
  18#undef DEBUG_RTC
  19
  20#ifdef DEBUG_RTC
  21#define DEBUGR(fmt,args...) printf(fmt ,##args)
  22#else
  23#define DEBUGR(fmt,args...)
  24#endif
  25/*---------------------------------------------------------------------*/
  26
  27enum rx_model {
  28        model_rx_8025,
  29        model_rx_8035,
  30};
  31
  32/*
  33 * RTC register addresses
  34 */
  35#define RTC_SEC_REG_ADDR        0x00
  36#define RTC_MIN_REG_ADDR        0x01
  37#define RTC_HR_REG_ADDR         0x02
  38#define RTC_DAY_REG_ADDR        0x03
  39#define RTC_DATE_REG_ADDR       0x04
  40#define RTC_MON_REG_ADDR        0x05
  41#define RTC_YR_REG_ADDR         0x06
  42#define RTC_OFFSET_REG_ADDR     0x07
  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 */
  68
  69#define rtc_read(reg) buf[(reg) & 0xf]
  70
  71static int rtc_write(struct udevice *dev, uchar reg, uchar val);
  72
  73static int rx8025_is_osc_stopped(enum rx_model model, int ctrl2)
  74{
  75        int xstp = ctrl2 & RTC_CTL2_BIT_XST;
  76        /* XSTP bit has different polarity on RX-8025 vs RX-8035.
  77         * RX-8025: 0 == oscillator stopped
  78         * RX-8035: 1 == oscillator stopped
  79         */
  80
  81        if (model == model_rx_8025)
  82                xstp = !xstp;
  83
  84        return xstp;
  85}
  86
  87/*
  88 * Get the current time from the RTC
  89 */
  90static int rx8025_rtc_get(struct udevice *dev, struct rtc_time *tmp)
  91{
  92        int rel = 0;
  93        uchar sec, min, hour, mday, wday, mon, year, ctl2;
  94        uchar buf[16];
  95
  96        if (dm_i2c_read(dev, 0, buf, sizeof(buf))) {
  97                printf("Error reading from RTC\n");
  98                return -EIO;
  99        }
 100
 101        sec = rtc_read(RTC_SEC_REG_ADDR);
 102        min = rtc_read(RTC_MIN_REG_ADDR);
 103        hour = rtc_read(RTC_HR_REG_ADDR);
 104        wday = rtc_read(RTC_DAY_REG_ADDR);
 105        mday = rtc_read(RTC_DATE_REG_ADDR);
 106        mon = rtc_read(RTC_MON_REG_ADDR);
 107        year = rtc_read(RTC_YR_REG_ADDR);
 108
 109        DEBUGR("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
 110               "hr: %02x min: %02x sec: %02x\n",
 111               year, mon, mday, wday, hour, min, sec);
 112
 113        /* dump status */
 114        ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
 115        if (ctl2 & RTC_CTL2_BIT_PON) {
 116                printf("RTC: power-on detected\n");
 117                rel = -1;
 118        }
 119
 120        if (ctl2 & RTC_CTL2_BIT_VDET) {
 121                printf("RTC: voltage drop detected\n");
 122                rel = -1;
 123        }
 124        if (rx8025_is_osc_stopped(dev->driver_data, ctl2)) {
 125                printf("RTC: oscillator stop detected\n");
 126                rel = -1;
 127        }
 128
 129        tmp->tm_sec  = bcd2bin(sec & 0x7F);
 130        tmp->tm_min  = bcd2bin(min & 0x7F);
 131        if (rtc_read(RTC_CTL1_REG_ADDR) & RTC_CTL1_BIT_2412)
 132                tmp->tm_hour = bcd2bin(hour & 0x3F);
 133        else
 134                tmp->tm_hour = bcd2bin(hour & 0x1F) % 12 +
 135                               ((hour & 0x20) ? 12 : 0);
 136
 137        tmp->tm_mday = bcd2bin (mday & 0x3F);
 138        tmp->tm_mon  = bcd2bin (mon & 0x1F);
 139        tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
 140        tmp->tm_wday = bcd2bin (wday & 0x07);
 141        tmp->tm_yday = 0;
 142        tmp->tm_isdst= 0;
 143
 144        DEBUGR("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 145               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 146               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 147
 148        return rel;
 149}
 150
 151/*
 152 * Set the RTC
 153 */
 154static int rx8025_rtc_set(struct udevice *dev, const struct rtc_time *tmp)
 155{
 156        /* To work around the read/write cycle issue mentioned
 157         * at the top of this file, write all the time registers
 158         * in one I2C transaction
 159         */
 160        u8 write_op[8];
 161
 162        /* 2412 flag must be set before doing a RTC write,
 163         * otherwise the seconds and minute register
 164         * will be cleared when the flag is set
 165         */
 166        if (rtc_write(dev, RTC_CTL1_REG_ADDR, RTC_CTL1_BIT_2412))
 167                return -EIO;
 168
 169        DEBUGR("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 170               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 171               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 172
 173        if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
 174                printf("WARNING: year should be between 1970 and 2069!\n");
 175
 176        write_op[RTC_SEC_REG_ADDR]  = bin2bcd(tmp->tm_sec);
 177        write_op[RTC_MIN_REG_ADDR]  = bin2bcd(tmp->tm_min);
 178        write_op[RTC_HR_REG_ADDR]   = bin2bcd(tmp->tm_hour);
 179        write_op[RTC_DAY_REG_ADDR]      = bin2bcd(tmp->tm_wday);
 180        write_op[RTC_DATE_REG_ADDR]     = bin2bcd(tmp->tm_mday);
 181        write_op[RTC_MON_REG_ADDR]  = bin2bcd(tmp->tm_mon);
 182        write_op[RTC_YR_REG_ADDR]       = bin2bcd(tmp->tm_year % 100);
 183        write_op[RTC_OFFSET_REG_ADDR] = 0;
 184
 185        return dm_i2c_write(dev, 0, &write_op[0], 8);
 186}
 187
 188/*
 189 * Reset the RTC
 190 */
 191static int rx8025_rtc_reset(struct udevice *dev)
 192{
 193        uchar buf[16];
 194        uchar ctl2;
 195
 196        if (dm_i2c_read(dev, 0, buf, sizeof(buf))) {
 197                printf("Error reading from RTC\n");
 198                return -EIO;
 199        }
 200
 201        ctl2 = rtc_read(RTC_CTL2_REG_ADDR);
 202        ctl2 &= ~(RTC_CTL2_BIT_PON | RTC_CTL2_BIT_VDET);
 203
 204        if (dev->driver_data == model_rx_8035)
 205                ctl2 &= ~(RTC_CTL2_BIT_XST);
 206        else
 207                ctl2 |= RTC_CTL2_BIT_XST;
 208
 209        return rtc_write(dev, RTC_CTL2_REG_ADDR, ctl2);
 210}
 211
 212/*
 213 * Helper functions
 214 */
 215static int rtc_write(struct udevice *dev, uchar reg, uchar val)
 216{
 217        /* The RX8025/RX8035 uses the top 4 bits of the
 218         * 'offset' byte as the start register address,
 219         * and the bottom 4 bits as a 'transfer' mode setting
 220         * (only applicable for reads)
 221         */
 222        u8 offset = (reg << 4);
 223
 224        if (dm_i2c_reg_write(dev, offset, val)) {
 225                printf("Error writing to RTC\n");
 226                return -EIO;
 227        }
 228
 229        return 0;
 230}
 231
 232static int rx8025_probe(struct udevice *dev)
 233{
 234        uchar buf[16];
 235        int ret = 0;
 236
 237        if (i2c_get_chip_offset_len(dev) != 1)
 238                ret = i2c_set_chip_offset_len(dev, 1);
 239
 240        if (ret)
 241                return ret;
 242
 243        return dm_i2c_read(dev, 0, buf, sizeof(buf));
 244}
 245
 246static const struct rtc_ops rx8025_rtc_ops = {
 247        .get = rx8025_rtc_get,
 248        .set = rx8025_rtc_set,
 249        .reset = rx8025_rtc_reset,
 250};
 251
 252static const struct udevice_id rx8025_rtc_ids[] = {
 253        { .compatible = "epson,rx8025", .data = model_rx_8025 },
 254        { .compatible = "epson,rx8035", .data = model_rx_8035 },
 255        { }
 256};
 257
 258U_BOOT_DRIVER(rx8025_rtc) = {
 259        .name     = "rx8025_rtc",
 260        .id           = UCLASS_RTC,
 261        .probe    = rx8025_probe,
 262        .of_match = rx8025_rtc_ids,
 263        .ops      = &rx8025_rtc_ops,
 264};
 265