10c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 20c698dcaSJean-Christophe PLAGNIOL-VILLARD * rs5c372.c 30c698dcaSJean-Christophe PLAGNIOL-VILLARD * 40c698dcaSJean-Christophe PLAGNIOL-VILLARD * Device driver for Ricoh's Real Time Controller RS5C372A. 50c698dcaSJean-Christophe PLAGNIOL-VILLARD * 60c698dcaSJean-Christophe PLAGNIOL-VILLARD * Copyright (C) 2004 Gary Jennejohn garyj@denx.de 70c698dcaSJean-Christophe PLAGNIOL-VILLARD * 80c698dcaSJean-Christophe PLAGNIOL-VILLARD * Based in part in ds1307.c - 90c698dcaSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2001, 2002, 2003 100c698dcaSJean-Christophe PLAGNIOL-VILLARD * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 110c698dcaSJean-Christophe PLAGNIOL-VILLARD * Keith Outwater, keith_outwater@mvis.com` 120c698dcaSJean-Christophe PLAGNIOL-VILLARD * Steven Scholz, steven.scholz@imc-berlin.de 130c698dcaSJean-Christophe PLAGNIOL-VILLARD * 140c698dcaSJean-Christophe PLAGNIOL-VILLARD * See file CREDITS for list of people who contributed to this 150c698dcaSJean-Christophe PLAGNIOL-VILLARD * project. 160c698dcaSJean-Christophe PLAGNIOL-VILLARD * 170c698dcaSJean-Christophe PLAGNIOL-VILLARD * This program is free software; you can redistribute it and/or modify 180c698dcaSJean-Christophe PLAGNIOL-VILLARD * it under the terms of the GNU General Public License version 2 as 190c698dcaSJean-Christophe PLAGNIOL-VILLARD * published by the Free Software Foundation. 200c698dcaSJean-Christophe PLAGNIOL-VILLARD * 210c698dcaSJean-Christophe PLAGNIOL-VILLARD * This program is distributed in the hope that it will be useful, 220c698dcaSJean-Christophe PLAGNIOL-VILLARD * but WITHOUT ANY WARRANTY; without even the implied warranty of 230c698dcaSJean-Christophe PLAGNIOL-VILLARD * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 240c698dcaSJean-Christophe PLAGNIOL-VILLARD * GNU General Public License for more details. 250c698dcaSJean-Christophe PLAGNIOL-VILLARD * 260c698dcaSJean-Christophe PLAGNIOL-VILLARD * You should have received a copy of the GNU General Public License 270c698dcaSJean-Christophe PLAGNIOL-VILLARD * along with this program; if not, write to the Free Software 280c698dcaSJean-Christophe PLAGNIOL-VILLARD * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 290c698dcaSJean-Christophe PLAGNIOL-VILLARD * MA 02111-1307 USA 300c698dcaSJean-Christophe PLAGNIOL-VILLARD */ 310c698dcaSJean-Christophe PLAGNIOL-VILLARD 320c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 330c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <command.h> 340c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <rtc.h> 350c698dcaSJean-Christophe PLAGNIOL-VILLARD #include <i2c.h> 360c698dcaSJean-Christophe PLAGNIOL-VILLARD 370c698dcaSJean-Christophe PLAGNIOL-VILLARD #if defined(CONFIG_RTC_RS5C372A) && defined(CONFIG_CMD_DATE) 380c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 390c698dcaSJean-Christophe PLAGNIOL-VILLARD * Reads are always done starting with register 15, which requires some 400c698dcaSJean-Christophe PLAGNIOL-VILLARD * jumping-through-hoops to access the data correctly. 410c698dcaSJean-Christophe PLAGNIOL-VILLARD * 420c698dcaSJean-Christophe PLAGNIOL-VILLARD * Writes are always done starting with register 0. 430c698dcaSJean-Christophe PLAGNIOL-VILLARD */ 440c698dcaSJean-Christophe PLAGNIOL-VILLARD 450c698dcaSJean-Christophe PLAGNIOL-VILLARD #define DEBUG 0 460c698dcaSJean-Christophe PLAGNIOL-VILLARD 470c698dcaSJean-Christophe PLAGNIOL-VILLARD #if DEBUG 480c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned int rtc_debug = DEBUG; 490c698dcaSJean-Christophe PLAGNIOL-VILLARD #else 500c698dcaSJean-Christophe PLAGNIOL-VILLARD #define rtc_debug 0 /* gcc will remove all the debug code for us */ 510c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif 520c698dcaSJean-Christophe PLAGNIOL-VILLARD 530c698dcaSJean-Christophe PLAGNIOL-VILLARD #ifndef CFG_I2C_RTC_ADDR 540c698dcaSJean-Christophe PLAGNIOL-VILLARD #define CFG_I2C_RTC_ADDR 0x32 550c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif 560c698dcaSJean-Christophe PLAGNIOL-VILLARD 570c698dcaSJean-Christophe PLAGNIOL-VILLARD #define RS5C372_RAM_SIZE 0x10 580c698dcaSJean-Christophe PLAGNIOL-VILLARD #define RATE_32000HZ 0x80 /* Rate Select 32.000KHz */ 590c698dcaSJean-Christophe PLAGNIOL-VILLARD #define RATE_32768HZ 0x00 /* Rate Select 32.768KHz */ 600c698dcaSJean-Christophe PLAGNIOL-VILLARD 610c698dcaSJean-Christophe PLAGNIOL-VILLARD #define STATUS_XPT 0x10 /* data invalid because voltage was 0 */ 620c698dcaSJean-Christophe PLAGNIOL-VILLARD 630c698dcaSJean-Christophe PLAGNIOL-VILLARD #define USE_24HOUR_MODE 0x20 640c698dcaSJean-Christophe PLAGNIOL-VILLARD #define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0) 650c698dcaSJean-Christophe PLAGNIOL-VILLARD #define HOURS_AP(n) (((n) >> 5) & 1) 660c698dcaSJean-Christophe PLAGNIOL-VILLARD #define HOURS_12(n) bcd2bin((n) & 0x1F) 670c698dcaSJean-Christophe PLAGNIOL-VILLARD #define HOURS_24(n) bcd2bin((n) & 0x3F) 680c698dcaSJean-Christophe PLAGNIOL-VILLARD 690c698dcaSJean-Christophe PLAGNIOL-VILLARD 700c698dcaSJean-Christophe PLAGNIOL-VILLARD static uchar bin2bcd (unsigned int n); 710c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned bcd2bin (uchar c); 720c698dcaSJean-Christophe PLAGNIOL-VILLARD 730c698dcaSJean-Christophe PLAGNIOL-VILLARD static int setup_done = 0; 740c698dcaSJean-Christophe PLAGNIOL-VILLARD 750c698dcaSJean-Christophe PLAGNIOL-VILLARD static int 760c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_readram(unsigned char *buf, int len) 770c698dcaSJean-Christophe PLAGNIOL-VILLARD { 780c698dcaSJean-Christophe PLAGNIOL-VILLARD int ret; 790c698dcaSJean-Christophe PLAGNIOL-VILLARD 800c698dcaSJean-Christophe PLAGNIOL-VILLARD ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, len); 810c698dcaSJean-Christophe PLAGNIOL-VILLARD if (ret != 0) { 820c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("%s: failed to read\n", __FUNCTION__); 830c698dcaSJean-Christophe PLAGNIOL-VILLARD return ret; 840c698dcaSJean-Christophe PLAGNIOL-VILLARD } 850c698dcaSJean-Christophe PLAGNIOL-VILLARD 860c698dcaSJean-Christophe PLAGNIOL-VILLARD if (buf[0] & STATUS_XPT) 870c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("### Warning: RTC lost power\n"); 880c698dcaSJean-Christophe PLAGNIOL-VILLARD 890c698dcaSJean-Christophe PLAGNIOL-VILLARD return ret; 900c698dcaSJean-Christophe PLAGNIOL-VILLARD } 910c698dcaSJean-Christophe PLAGNIOL-VILLARD 920c698dcaSJean-Christophe PLAGNIOL-VILLARD static void 930c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_enable(void) 940c698dcaSJean-Christophe PLAGNIOL-VILLARD { 950c698dcaSJean-Christophe PLAGNIOL-VILLARD unsigned char buf[RS5C372_RAM_SIZE + 1]; 960c698dcaSJean-Christophe PLAGNIOL-VILLARD int ret; 970c698dcaSJean-Christophe PLAGNIOL-VILLARD 980c698dcaSJean-Christophe PLAGNIOL-VILLARD /* note that this returns reg. 15 in buf[1] */ 990c698dcaSJean-Christophe PLAGNIOL-VILLARD ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE); 1000c698dcaSJean-Christophe PLAGNIOL-VILLARD if (ret != 0) { 1010c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("%s: failed\n", __FUNCTION__); 1020c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 1030c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1040c698dcaSJean-Christophe PLAGNIOL-VILLARD 1050c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[0] = 0; 1060c698dcaSJean-Christophe PLAGNIOL-VILLARD /* we want to start writing at register 0 so we have to copy the */ 1070c698dcaSJean-Christophe PLAGNIOL-VILLARD /* register contents up one slot */ 1080c698dcaSJean-Christophe PLAGNIOL-VILLARD for (ret = 2; ret < 9; ret++) 1090c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[ret - 1] = buf[ret]; 1100c698dcaSJean-Christophe PLAGNIOL-VILLARD /* registers 0 to 6 (time values) are not touched */ 1110c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[8] = RATE_32768HZ; /* reg. 7 */ 1120c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[9] = 0; /* reg. 8 */ 1130c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[10] = 0; /* reg. 9 */ 1140c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[11] = 0; /* reg. 10 */ 1150c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[12] = 0; /* reg. 11 */ 1160c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[13] = 0; /* reg. 12 */ 1170c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[14] = 0; /* reg. 13 */ 1180c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[15] = 0; /* reg. 14 */ 1190c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[16] = USE_24HOUR_MODE; /* reg. 15 */ 1200c698dcaSJean-Christophe PLAGNIOL-VILLARD ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1); 1210c698dcaSJean-Christophe PLAGNIOL-VILLARD if (ret != 0) { 1220c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("%s: failed\n", __FUNCTION__); 1230c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 1240c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1250c698dcaSJean-Christophe PLAGNIOL-VILLARD setup_done = 1; 1260c698dcaSJean-Christophe PLAGNIOL-VILLARD 1270c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 1280c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1290c698dcaSJean-Christophe PLAGNIOL-VILLARD 1300c698dcaSJean-Christophe PLAGNIOL-VILLARD static void 1310c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf) 1320c698dcaSJean-Christophe PLAGNIOL-VILLARD { 1330c698dcaSJean-Christophe PLAGNIOL-VILLARD /* buf[0] is register 15 */ 1340c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_sec = bcd2bin(buf[1]); 1350c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_min = bcd2bin(buf[2]); 1360c698dcaSJean-Christophe PLAGNIOL-VILLARD 1370c698dcaSJean-Christophe PLAGNIOL-VILLARD if (TWELVE_HOUR_MODE(buf[0])) { 1380c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_hour = HOURS_12(buf[3]); 1390c698dcaSJean-Christophe PLAGNIOL-VILLARD if (HOURS_AP(buf[3])) /* PM */ 1400c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_hour += 12; 1410c698dcaSJean-Christophe PLAGNIOL-VILLARD } else /* 24-hour-mode */ 1420c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_hour = HOURS_24(buf[3]); 1430c698dcaSJean-Christophe PLAGNIOL-VILLARD 1440c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_mday = bcd2bin(buf[5]); 1450c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_mon = bcd2bin(buf[6]); 1460c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_year = bcd2bin(buf[7]); 1470c698dcaSJean-Christophe PLAGNIOL-VILLARD if (dt->tm_year >= 70) 1480c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_year += 1900; 1490c698dcaSJean-Christophe PLAGNIOL-VILLARD else 1500c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_year += 2000; 1510c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 0 is Sunday */ 1520c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_wday = bcd2bin(buf[4] & 0x07); 1530c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_yday = 0; 1540c698dcaSJean-Christophe PLAGNIOL-VILLARD dt->tm_isdst= 0; 1550c698dcaSJean-Christophe PLAGNIOL-VILLARD 1560c698dcaSJean-Christophe PLAGNIOL-VILLARD if(rtc_debug > 2) { 1570c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year); 1580c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_convert_to_time: mon = %d\n", dt->tm_mon); 1590c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday); 1600c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour); 1610c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_convert_to_time: min = %d\n", dt->tm_min); 1620c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_convert_to_time: sec = %d\n", dt->tm_sec); 1630c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1640c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1650c698dcaSJean-Christophe PLAGNIOL-VILLARD 1660c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 1670c698dcaSJean-Christophe PLAGNIOL-VILLARD * Get the current time from the RTC 1680c698dcaSJean-Christophe PLAGNIOL-VILLARD */ 169*b73a19e1SYuri Tikhonov int 1700c698dcaSJean-Christophe PLAGNIOL-VILLARD rtc_get (struct rtc_time *tmp) 1710c698dcaSJean-Christophe PLAGNIOL-VILLARD { 1720c698dcaSJean-Christophe PLAGNIOL-VILLARD unsigned char buf[RS5C372_RAM_SIZE]; 1730c698dcaSJean-Christophe PLAGNIOL-VILLARD int ret; 1740c698dcaSJean-Christophe PLAGNIOL-VILLARD 1750c698dcaSJean-Christophe PLAGNIOL-VILLARD if (!setup_done) 1760c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_enable(); 1770c698dcaSJean-Christophe PLAGNIOL-VILLARD 1780c698dcaSJean-Christophe PLAGNIOL-VILLARD if (!setup_done) 179*b73a19e1SYuri Tikhonov return -1; 1800c698dcaSJean-Christophe PLAGNIOL-VILLARD 1810c698dcaSJean-Christophe PLAGNIOL-VILLARD memset(buf, 0, sizeof(buf)); 1820c698dcaSJean-Christophe PLAGNIOL-VILLARD 1830c698dcaSJean-Christophe PLAGNIOL-VILLARD /* note that this returns reg. 15 in buf[0] */ 1840c698dcaSJean-Christophe PLAGNIOL-VILLARD ret = rs5c372_readram(buf, RS5C372_RAM_SIZE); 1850c698dcaSJean-Christophe PLAGNIOL-VILLARD if (ret != 0) { 1860c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("%s: failed\n", __FUNCTION__); 187*b73a19e1SYuri Tikhonov return -1; 1880c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1890c698dcaSJean-Christophe PLAGNIOL-VILLARD 1900c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_convert_to_time(tmp, buf); 1910c698dcaSJean-Christophe PLAGNIOL-VILLARD 192*b73a19e1SYuri Tikhonov return 0; 1930c698dcaSJean-Christophe PLAGNIOL-VILLARD } 1940c698dcaSJean-Christophe PLAGNIOL-VILLARD 1950c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 1960c698dcaSJean-Christophe PLAGNIOL-VILLARD * Set the RTC 1970c698dcaSJean-Christophe PLAGNIOL-VILLARD */ 1980c698dcaSJean-Christophe PLAGNIOL-VILLARD void 1990c698dcaSJean-Christophe PLAGNIOL-VILLARD rtc_set (struct rtc_time *tmp) 2000c698dcaSJean-Christophe PLAGNIOL-VILLARD { 2010c698dcaSJean-Christophe PLAGNIOL-VILLARD unsigned char buf[8], reg15; 2020c698dcaSJean-Christophe PLAGNIOL-VILLARD int ret; 2030c698dcaSJean-Christophe PLAGNIOL-VILLARD 2040c698dcaSJean-Christophe PLAGNIOL-VILLARD if (!setup_done) 2050c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_enable(); 2060c698dcaSJean-Christophe PLAGNIOL-VILLARD 2070c698dcaSJean-Christophe PLAGNIOL-VILLARD if (!setup_done) 2080c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 2090c698dcaSJean-Christophe PLAGNIOL-VILLARD 2100c698dcaSJean-Christophe PLAGNIOL-VILLARD if(rtc_debug > 2) { 2110c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rtc_set: tm_year = %d\n", tmp->tm_year); 2120c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rtc_set: tm_mon = %d\n", tmp->tm_mon); 2130c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rtc_set: tm_mday = %d\n", tmp->tm_mday); 2140c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rtc_set: tm_hour = %d\n", tmp->tm_hour); 2150c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rtc_set: tm_min = %d\n", tmp->tm_min); 2160c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rtc_set: tm_sec = %d\n", tmp->tm_sec); 2170c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2180c698dcaSJean-Christophe PLAGNIOL-VILLARD 2190c698dcaSJean-Christophe PLAGNIOL-VILLARD memset(buf, 0, sizeof(buf)); 2200c698dcaSJean-Christophe PLAGNIOL-VILLARD 2210c698dcaSJean-Christophe PLAGNIOL-VILLARD /* only read register 15 */ 2220c698dcaSJean-Christophe PLAGNIOL-VILLARD ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, 1); 2230c698dcaSJean-Christophe PLAGNIOL-VILLARD 2240c698dcaSJean-Christophe PLAGNIOL-VILLARD if (ret == 0) { 2250c698dcaSJean-Christophe PLAGNIOL-VILLARD /* need to save register 15 */ 2260c698dcaSJean-Christophe PLAGNIOL-VILLARD reg15 = buf[0]; 2270c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[0] = 0; /* register address on RS5C372 */ 2280c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[1] = bin2bcd(tmp->tm_sec); 2290c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[2] = bin2bcd(tmp->tm_min); 2300c698dcaSJean-Christophe PLAGNIOL-VILLARD /* need to handle 12 hour mode */ 2310c698dcaSJean-Christophe PLAGNIOL-VILLARD if (TWELVE_HOUR_MODE(reg15)) { 2320c698dcaSJean-Christophe PLAGNIOL-VILLARD if (tmp->tm_hour >= 12) { /* PM */ 2330c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 12 PM is a special case */ 2340c698dcaSJean-Christophe PLAGNIOL-VILLARD if (tmp->tm_hour == 12) 2350c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[3] = bin2bcd(tmp->tm_hour); 2360c698dcaSJean-Christophe PLAGNIOL-VILLARD else 2370c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[3] = bin2bcd(tmp->tm_hour - 12); 2380c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[3] |= 0x20; 2390c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2400c698dcaSJean-Christophe PLAGNIOL-VILLARD } else { 2410c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[3] = bin2bcd(tmp->tm_hour); 2420c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2430c698dcaSJean-Christophe PLAGNIOL-VILLARD 2440c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[4] = bin2bcd(tmp->tm_wday); 2450c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[5] = bin2bcd(tmp->tm_mday); 2460c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[6] = bin2bcd(tmp->tm_mon); 2470c698dcaSJean-Christophe PLAGNIOL-VILLARD if (tmp->tm_year < 1970 || tmp->tm_year > 2069) 2480c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("WARNING: year should be between 1970 and 2069!\n"); 2490c698dcaSJean-Christophe PLAGNIOL-VILLARD buf[7] = bin2bcd(tmp->tm_year % 100); 2500c698dcaSJean-Christophe PLAGNIOL-VILLARD 2510c698dcaSJean-Christophe PLAGNIOL-VILLARD ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, 8); 2520c698dcaSJean-Christophe PLAGNIOL-VILLARD if (ret != 0) 2530c698dcaSJean-Christophe PLAGNIOL-VILLARD printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret); 2540c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2550c698dcaSJean-Christophe PLAGNIOL-VILLARD 2560c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 2570c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2580c698dcaSJean-Christophe PLAGNIOL-VILLARD 2590c698dcaSJean-Christophe PLAGNIOL-VILLARD /* 2600c698dcaSJean-Christophe PLAGNIOL-VILLARD * Reset the RTC. We set the date back to 1970-01-01. 2610c698dcaSJean-Christophe PLAGNIOL-VILLARD */ 2620c698dcaSJean-Christophe PLAGNIOL-VILLARD void 2630c698dcaSJean-Christophe PLAGNIOL-VILLARD rtc_reset (void) 2640c698dcaSJean-Christophe PLAGNIOL-VILLARD { 2650c698dcaSJean-Christophe PLAGNIOL-VILLARD struct rtc_time tmp; 2660c698dcaSJean-Christophe PLAGNIOL-VILLARD 2670c698dcaSJean-Christophe PLAGNIOL-VILLARD if (!setup_done) 2680c698dcaSJean-Christophe PLAGNIOL-VILLARD rs5c372_enable(); 2690c698dcaSJean-Christophe PLAGNIOL-VILLARD 2700c698dcaSJean-Christophe PLAGNIOL-VILLARD if (!setup_done) 2710c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 2720c698dcaSJean-Christophe PLAGNIOL-VILLARD 2730c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_year = 1970; 2740c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_mon = 1; 2750c698dcaSJean-Christophe PLAGNIOL-VILLARD /* Jan. 1, 1970 was a Thursday */ 2760c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_wday= 4; 2770c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_mday= 1; 2780c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_hour = 0; 2790c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_min = 0; 2800c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_sec = 0; 2810c698dcaSJean-Christophe PLAGNIOL-VILLARD 2820c698dcaSJean-Christophe PLAGNIOL-VILLARD rtc_set(&tmp); 2830c698dcaSJean-Christophe PLAGNIOL-VILLARD 2840c698dcaSJean-Christophe PLAGNIOL-VILLARD printf ("RTC: %4d-%02d-%02d %2d:%02d:%02d UTC\n", 2850c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_year, tmp.tm_mon, tmp.tm_mday, 2860c698dcaSJean-Christophe PLAGNIOL-VILLARD tmp.tm_hour, tmp.tm_min, tmp.tm_sec); 2870c698dcaSJean-Christophe PLAGNIOL-VILLARD 2880c698dcaSJean-Christophe PLAGNIOL-VILLARD return; 2890c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2900c698dcaSJean-Christophe PLAGNIOL-VILLARD 2910c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned int 2920c698dcaSJean-Christophe PLAGNIOL-VILLARD bcd2bin (unsigned char n) 2930c698dcaSJean-Christophe PLAGNIOL-VILLARD { 2940c698dcaSJean-Christophe PLAGNIOL-VILLARD return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F)); 2950c698dcaSJean-Christophe PLAGNIOL-VILLARD } 2960c698dcaSJean-Christophe PLAGNIOL-VILLARD 2970c698dcaSJean-Christophe PLAGNIOL-VILLARD static unsigned char 2980c698dcaSJean-Christophe PLAGNIOL-VILLARD bin2bcd (unsigned int n) 2990c698dcaSJean-Christophe PLAGNIOL-VILLARD { 3000c698dcaSJean-Christophe PLAGNIOL-VILLARD return (((n / 10) << 4) | (n % 10)); 3010c698dcaSJean-Christophe PLAGNIOL-VILLARD } 3020c698dcaSJean-Christophe PLAGNIOL-VILLARD #endif 303