139ba774fSPo-Yu Chuang /* 239ba774fSPo-Yu Chuang * Faraday FTRTC010 Real Time Clock 339ba774fSPo-Yu Chuang * 439ba774fSPo-Yu Chuang * (C) Copyright 2009 Faraday Technology 539ba774fSPo-Yu Chuang * Po-Yu Chuang <ratbert@faraday-tech.com> 639ba774fSPo-Yu Chuang * 739ba774fSPo-Yu Chuang * This program is free software; you can redistribute it and/or modify 839ba774fSPo-Yu Chuang * it under the terms of the GNU General Public License as published by 939ba774fSPo-Yu Chuang * the Free Software Foundation; either version 2 of the License, or 1039ba774fSPo-Yu Chuang * (at your option) any later version. 1139ba774fSPo-Yu Chuang * 1239ba774fSPo-Yu Chuang * This program is distributed in the hope that it will be useful, 1339ba774fSPo-Yu Chuang * but WITHOUT ANY WARRANTY; without even the implied warranty of 1439ba774fSPo-Yu Chuang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1539ba774fSPo-Yu Chuang * GNU General Public License for more details. 1639ba774fSPo-Yu Chuang * 1739ba774fSPo-Yu Chuang * You should have received a copy of the GNU General Public License 1839ba774fSPo-Yu Chuang * along with this program; if not, write to the Free Software 1939ba774fSPo-Yu Chuang * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 2039ba774fSPo-Yu Chuang */ 2139ba774fSPo-Yu Chuang 2239ba774fSPo-Yu Chuang #include <config.h> 2339ba774fSPo-Yu Chuang #include <common.h> 2439ba774fSPo-Yu Chuang #include <rtc.h> 2539ba774fSPo-Yu Chuang #include <asm/io.h> 2639ba774fSPo-Yu Chuang 2739ba774fSPo-Yu Chuang struct ftrtc010 { 2839ba774fSPo-Yu Chuang unsigned int sec; /* 0x00 */ 2939ba774fSPo-Yu Chuang unsigned int min; /* 0x04 */ 3039ba774fSPo-Yu Chuang unsigned int hour; /* 0x08 */ 3139ba774fSPo-Yu Chuang unsigned int day; /* 0x0c */ 3239ba774fSPo-Yu Chuang unsigned int alarm_sec; /* 0x10 */ 3339ba774fSPo-Yu Chuang unsigned int alarm_min; /* 0x14 */ 3439ba774fSPo-Yu Chuang unsigned int alarm_hour; /* 0x18 */ 3539ba774fSPo-Yu Chuang unsigned int record; /* 0x1c */ 3639ba774fSPo-Yu Chuang unsigned int cr; /* 0x20 */ 37*0284816eSMacpaul Lin unsigned int wsec; /* 0x24 */ 38*0284816eSMacpaul Lin unsigned int wmin; /* 0x28 */ 39*0284816eSMacpaul Lin unsigned int whour; /* 0x2c */ 40*0284816eSMacpaul Lin unsigned int wday; /* 0x30 */ 41*0284816eSMacpaul Lin unsigned int intr; /* 0x34 */ 42*0284816eSMacpaul Lin unsigned int div; /* 0x38 */ 43*0284816eSMacpaul Lin unsigned int rev; /* 0x3c */ 4439ba774fSPo-Yu Chuang }; 4539ba774fSPo-Yu Chuang 4639ba774fSPo-Yu Chuang /* 4739ba774fSPo-Yu Chuang * RTC Control Register 4839ba774fSPo-Yu Chuang */ 4939ba774fSPo-Yu Chuang #define FTRTC010_CR_ENABLE (1 << 0) 5039ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_SEC (1 << 1) /* per second irq */ 5139ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_MIN (1 << 2) /* per minute irq */ 5239ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_HR (1 << 3) /* per hour irq */ 5339ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_DAY (1 << 4) /* per day irq */ 5439ba774fSPo-Yu Chuang 5539ba774fSPo-Yu Chuang static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE; 5639ba774fSPo-Yu Chuang 5739ba774fSPo-Yu Chuang static void ftrtc010_enable(void) 5839ba774fSPo-Yu Chuang { 5939ba774fSPo-Yu Chuang writel(FTRTC010_CR_ENABLE, &rtc->cr); 6039ba774fSPo-Yu Chuang } 6139ba774fSPo-Yu Chuang 6239ba774fSPo-Yu Chuang /* 6339ba774fSPo-Yu Chuang * return current time in seconds 6439ba774fSPo-Yu Chuang */ 6539ba774fSPo-Yu Chuang static unsigned long ftrtc010_time(void) 6639ba774fSPo-Yu Chuang { 6739ba774fSPo-Yu Chuang unsigned long day; 6839ba774fSPo-Yu Chuang unsigned long hour; 6939ba774fSPo-Yu Chuang unsigned long minute; 7039ba774fSPo-Yu Chuang unsigned long second; 7139ba774fSPo-Yu Chuang unsigned long second2; 7239ba774fSPo-Yu Chuang 7339ba774fSPo-Yu Chuang do { 7439ba774fSPo-Yu Chuang second = readl(&rtc->sec); 7539ba774fSPo-Yu Chuang day = readl(&rtc->day); 7639ba774fSPo-Yu Chuang hour = readl(&rtc->hour); 7739ba774fSPo-Yu Chuang minute = readl(&rtc->min); 7839ba774fSPo-Yu Chuang second2 = readl(&rtc->sec); 7939ba774fSPo-Yu Chuang } while (second != second2); 8039ba774fSPo-Yu Chuang 8139ba774fSPo-Yu Chuang return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; 8239ba774fSPo-Yu Chuang } 8339ba774fSPo-Yu Chuang 8439ba774fSPo-Yu Chuang /* 8539ba774fSPo-Yu Chuang * Get the current time from the RTC 8639ba774fSPo-Yu Chuang */ 8739ba774fSPo-Yu Chuang 8839ba774fSPo-Yu Chuang int rtc_get(struct rtc_time *tmp) 8939ba774fSPo-Yu Chuang { 9039ba774fSPo-Yu Chuang unsigned long now; 9139ba774fSPo-Yu Chuang 9239ba774fSPo-Yu Chuang debug("%s(): record register: %x\n", 9339ba774fSPo-Yu Chuang __func__, readl(&rtc->record)); 9439ba774fSPo-Yu Chuang 95*0284816eSMacpaul Lin #ifdef CONFIG_FTRTC010_PCLK 96*0284816eSMacpaul Lin now = (ftrtc010_time() + readl(&rtc->record)) / RTC_DIV_COUNT; 97*0284816eSMacpaul Lin #else /* CONFIG_FTRTC010_EXTCLK */ 9839ba774fSPo-Yu Chuang now = ftrtc010_time() + readl(&rtc->record); 99*0284816eSMacpaul Lin #endif 10039ba774fSPo-Yu Chuang 10139ba774fSPo-Yu Chuang to_tm(now, tmp); 10239ba774fSPo-Yu Chuang 10339ba774fSPo-Yu Chuang return 0; 10439ba774fSPo-Yu Chuang } 10539ba774fSPo-Yu Chuang 10639ba774fSPo-Yu Chuang /* 10739ba774fSPo-Yu Chuang * Set the RTC 10839ba774fSPo-Yu Chuang */ 10939ba774fSPo-Yu Chuang int rtc_set(struct rtc_time *tmp) 11039ba774fSPo-Yu Chuang { 11139ba774fSPo-Yu Chuang unsigned long new; 11239ba774fSPo-Yu Chuang unsigned long now; 11339ba774fSPo-Yu Chuang 11439ba774fSPo-Yu Chuang debug("%s(): DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 11539ba774fSPo-Yu Chuang __func__, 11639ba774fSPo-Yu Chuang tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 11739ba774fSPo-Yu Chuang tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 11839ba774fSPo-Yu Chuang 11939ba774fSPo-Yu Chuang new = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour, 12039ba774fSPo-Yu Chuang tmp->tm_min, tmp->tm_sec); 12139ba774fSPo-Yu Chuang 12239ba774fSPo-Yu Chuang now = ftrtc010_time(); 12339ba774fSPo-Yu Chuang 12439ba774fSPo-Yu Chuang debug("%s(): write %lx to record register\n", __func__, new - now); 12539ba774fSPo-Yu Chuang 12639ba774fSPo-Yu Chuang writel(new - now, &rtc->record); 12739ba774fSPo-Yu Chuang 12839ba774fSPo-Yu Chuang return 0; 12939ba774fSPo-Yu Chuang } 13039ba774fSPo-Yu Chuang 13139ba774fSPo-Yu Chuang void rtc_reset(void) 13239ba774fSPo-Yu Chuang { 13339ba774fSPo-Yu Chuang debug("%s()\n", __func__); 13439ba774fSPo-Yu Chuang ftrtc010_enable(); 13539ba774fSPo-Yu Chuang } 136