1 /* 2 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> 3 * Andreas Heppel <aheppel@sysgo.de> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * Date & Time support for the MK48T59 RTC 10 */ 11 12 #undef RTC_DEBUG 13 14 #include <common.h> 15 #include <command.h> 16 #include <config.h> 17 #include <rtc.h> 18 #include <mk48t59.h> 19 20 #if defined(CONFIG_BAB7xx) 21 22 static uchar rtc_read (short reg) 23 { 24 out8(RTC_PORT_ADDR0, reg & 0xFF); 25 out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF); 26 return in8(RTC_PORT_DATA); 27 } 28 29 static void rtc_write (short reg, uchar val) 30 { 31 out8(RTC_PORT_ADDR0, reg & 0xFF); 32 out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF); 33 out8(RTC_PORT_DATA, val); 34 } 35 36 #elif defined(CONFIG_EVAL5200) 37 38 static uchar rtc_read (short reg) 39 { 40 return in8(RTC(reg)); 41 } 42 43 static void rtc_write (short reg, uchar val) 44 { 45 out8(RTC(reg),val); 46 } 47 48 #else 49 # error Board specific rtc access functions should be supplied 50 #endif 51 52 /* ------------------------------------------------------------------------- */ 53 54 void *nvram_read(void *dest, const short src, size_t count) 55 { 56 uchar *d = (uchar *) dest; 57 short s = src; 58 59 while (count--) 60 *d++ = rtc_read(s++); 61 62 return dest; 63 } 64 65 void nvram_write(short dest, const void *src, size_t count) 66 { 67 short d = dest; 68 uchar *s = (uchar *) src; 69 70 while (count--) 71 rtc_write(d++, *s++); 72 } 73 74 #if defined(CONFIG_CMD_DATE) 75 76 /* ------------------------------------------------------------------------- */ 77 78 int rtc_get (struct rtc_time *tmp) 79 { 80 uchar save_ctrl_a; 81 uchar sec, min, hour, mday, wday, mon, year; 82 83 /* Simple: freeze the clock, read it and allow updates again */ 84 save_ctrl_a = rtc_read(RTC_CONTROLA); 85 86 /* Set the register to read the value. */ 87 save_ctrl_a |= RTC_CA_READ; 88 rtc_write(RTC_CONTROLA, save_ctrl_a); 89 90 sec = rtc_read (RTC_SECONDS); 91 min = rtc_read (RTC_MINUTES); 92 hour = rtc_read (RTC_HOURS); 93 mday = rtc_read (RTC_DAY_OF_MONTH); 94 wday = rtc_read (RTC_DAY_OF_WEEK); 95 mon = rtc_read (RTC_MONTH); 96 year = rtc_read (RTC_YEAR); 97 98 /* re-enable update */ 99 save_ctrl_a &= ~RTC_CA_READ; 100 rtc_write(RTC_CONTROLA, save_ctrl_a); 101 102 #ifdef RTC_DEBUG 103 printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " 104 "hr: %02x min: %02x sec: %02x\n", 105 year, mon, mday, wday, 106 hour, min, sec ); 107 #endif 108 tmp->tm_sec = bcd2bin (sec & 0x7F); 109 tmp->tm_min = bcd2bin (min & 0x7F); 110 tmp->tm_hour = bcd2bin (hour & 0x3F); 111 tmp->tm_mday = bcd2bin (mday & 0x3F); 112 tmp->tm_mon = bcd2bin (mon & 0x1F); 113 tmp->tm_year = bcd2bin (year); 114 tmp->tm_wday = bcd2bin (wday & 0x07); 115 if(tmp->tm_year<70) 116 tmp->tm_year+=2000; 117 else 118 tmp->tm_year+=1900; 119 tmp->tm_yday = 0; 120 tmp->tm_isdst= 0; 121 #ifdef RTC_DEBUG 122 printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 123 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 124 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 125 #endif 126 127 return 0; 128 } 129 130 int rtc_set (struct rtc_time *tmp) 131 { 132 uchar save_ctrl_a; 133 134 #ifdef RTC_DEBUG 135 printf ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 136 tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 137 tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 138 #endif 139 save_ctrl_a = rtc_read(RTC_CONTROLA); 140 141 save_ctrl_a |= RTC_CA_WRITE; 142 rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */ 143 144 rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100)); 145 rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon)); 146 147 rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); 148 rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday)); 149 rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour)); 150 rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min )); 151 rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec )); 152 153 save_ctrl_a &= ~RTC_CA_WRITE; 154 rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */ 155 156 return 0; 157 } 158 159 void rtc_reset (void) 160 { 161 uchar control_b; 162 163 /* 164 * Start oscillator here. 165 */ 166 control_b = rtc_read(RTC_CONTROLB); 167 168 control_b &= ~RTC_CB_STOP; 169 rtc_write(RTC_CONTROLB, control_b); 170 } 171 172 void rtc_set_watchdog(short multi, short res) 173 { 174 uchar wd_value; 175 176 wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3); 177 rtc_write(RTC_WATCHDOG, wd_value); 178 } 179 180 #endif 181