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