1*39ba774fSPo-Yu Chuang /* 2*39ba774fSPo-Yu Chuang * Faraday FTRTC010 Real Time Clock 3*39ba774fSPo-Yu Chuang * 4*39ba774fSPo-Yu Chuang * (C) Copyright 2009 Faraday Technology 5*39ba774fSPo-Yu Chuang * Po-Yu Chuang <ratbert@faraday-tech.com> 6*39ba774fSPo-Yu Chuang * 7*39ba774fSPo-Yu Chuang * This program is free software; you can redistribute it and/or modify 8*39ba774fSPo-Yu Chuang * it under the terms of the GNU General Public License as published by 9*39ba774fSPo-Yu Chuang * the Free Software Foundation; either version 2 of the License, or 10*39ba774fSPo-Yu Chuang * (at your option) any later version. 11*39ba774fSPo-Yu Chuang * 12*39ba774fSPo-Yu Chuang * This program is distributed in the hope that it will be useful, 13*39ba774fSPo-Yu Chuang * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*39ba774fSPo-Yu Chuang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*39ba774fSPo-Yu Chuang * GNU General Public License for more details. 16*39ba774fSPo-Yu Chuang * 17*39ba774fSPo-Yu Chuang * You should have received a copy of the GNU General Public License 18*39ba774fSPo-Yu Chuang * along with this program; if not, write to the Free Software 19*39ba774fSPo-Yu Chuang * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*39ba774fSPo-Yu Chuang */ 21*39ba774fSPo-Yu Chuang 22*39ba774fSPo-Yu Chuang #include <config.h> 23*39ba774fSPo-Yu Chuang #include <common.h> 24*39ba774fSPo-Yu Chuang #include <rtc.h> 25*39ba774fSPo-Yu Chuang #include <asm/io.h> 26*39ba774fSPo-Yu Chuang 27*39ba774fSPo-Yu Chuang struct ftrtc010 { 28*39ba774fSPo-Yu Chuang unsigned int sec; /* 0x00 */ 29*39ba774fSPo-Yu Chuang unsigned int min; /* 0x04 */ 30*39ba774fSPo-Yu Chuang unsigned int hour; /* 0x08 */ 31*39ba774fSPo-Yu Chuang unsigned int day; /* 0x0c */ 32*39ba774fSPo-Yu Chuang unsigned int alarm_sec; /* 0x10 */ 33*39ba774fSPo-Yu Chuang unsigned int alarm_min; /* 0x14 */ 34*39ba774fSPo-Yu Chuang unsigned int alarm_hour; /* 0x18 */ 35*39ba774fSPo-Yu Chuang unsigned int record; /* 0x1c */ 36*39ba774fSPo-Yu Chuang unsigned int cr; /* 0x20 */ 37*39ba774fSPo-Yu Chuang }; 38*39ba774fSPo-Yu Chuang 39*39ba774fSPo-Yu Chuang /* 40*39ba774fSPo-Yu Chuang * RTC Control Register 41*39ba774fSPo-Yu Chuang */ 42*39ba774fSPo-Yu Chuang #define FTRTC010_CR_ENABLE (1 << 0) 43*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_SEC (1 << 1) /* per second irq */ 44*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_MIN (1 << 2) /* per minute irq */ 45*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_HR (1 << 3) /* per hour irq */ 46*39ba774fSPo-Yu Chuang #define FTRTC010_CR_INTERRUPT_DAY (1 << 4) /* per day irq */ 47*39ba774fSPo-Yu Chuang 48*39ba774fSPo-Yu Chuang static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE; 49*39ba774fSPo-Yu Chuang 50*39ba774fSPo-Yu Chuang static void ftrtc010_enable(void) 51*39ba774fSPo-Yu Chuang { 52*39ba774fSPo-Yu Chuang writel(FTRTC010_CR_ENABLE, &rtc->cr); 53*39ba774fSPo-Yu Chuang } 54*39ba774fSPo-Yu Chuang 55*39ba774fSPo-Yu Chuang /* 56*39ba774fSPo-Yu Chuang * return current time in seconds 57*39ba774fSPo-Yu Chuang */ 58*39ba774fSPo-Yu Chuang static unsigned long ftrtc010_time(void) 59*39ba774fSPo-Yu Chuang { 60*39ba774fSPo-Yu Chuang unsigned long day; 61*39ba774fSPo-Yu Chuang unsigned long hour; 62*39ba774fSPo-Yu Chuang unsigned long minute; 63*39ba774fSPo-Yu Chuang unsigned long second; 64*39ba774fSPo-Yu Chuang unsigned long second2; 65*39ba774fSPo-Yu Chuang 66*39ba774fSPo-Yu Chuang do { 67*39ba774fSPo-Yu Chuang second = readl(&rtc->sec); 68*39ba774fSPo-Yu Chuang day = readl(&rtc->day); 69*39ba774fSPo-Yu Chuang hour = readl(&rtc->hour); 70*39ba774fSPo-Yu Chuang minute = readl(&rtc->min); 71*39ba774fSPo-Yu Chuang second2 = readl(&rtc->sec); 72*39ba774fSPo-Yu Chuang } while (second != second2); 73*39ba774fSPo-Yu Chuang 74*39ba774fSPo-Yu Chuang return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; 75*39ba774fSPo-Yu Chuang } 76*39ba774fSPo-Yu Chuang 77*39ba774fSPo-Yu Chuang /* 78*39ba774fSPo-Yu Chuang * Get the current time from the RTC 79*39ba774fSPo-Yu Chuang */ 80*39ba774fSPo-Yu Chuang 81*39ba774fSPo-Yu Chuang int rtc_get(struct rtc_time *tmp) 82*39ba774fSPo-Yu Chuang { 83*39ba774fSPo-Yu Chuang unsigned long now; 84*39ba774fSPo-Yu Chuang 85*39ba774fSPo-Yu Chuang debug("%s(): record register: %x\n", 86*39ba774fSPo-Yu Chuang __func__, readl(&rtc->record)); 87*39ba774fSPo-Yu Chuang 88*39ba774fSPo-Yu Chuang now = ftrtc010_time() + readl(&rtc->record); 89*39ba774fSPo-Yu Chuang 90*39ba774fSPo-Yu Chuang to_tm(now, tmp); 91*39ba774fSPo-Yu Chuang 92*39ba774fSPo-Yu Chuang return 0; 93*39ba774fSPo-Yu Chuang } 94*39ba774fSPo-Yu Chuang 95*39ba774fSPo-Yu Chuang /* 96*39ba774fSPo-Yu Chuang * Set the RTC 97*39ba774fSPo-Yu Chuang */ 98*39ba774fSPo-Yu Chuang int rtc_set(struct rtc_time *tmp) 99*39ba774fSPo-Yu Chuang { 100*39ba774fSPo-Yu Chuang unsigned long new; 101*39ba774fSPo-Yu Chuang unsigned long now; 102*39ba774fSPo-Yu Chuang 103*39ba774fSPo-Yu Chuang debug("%s(): DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", 104*39ba774fSPo-Yu Chuang __func__, 105*39ba774fSPo-Yu Chuang tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, 106*39ba774fSPo-Yu Chuang tmp->tm_hour, tmp->tm_min, tmp->tm_sec); 107*39ba774fSPo-Yu Chuang 108*39ba774fSPo-Yu Chuang new = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour, 109*39ba774fSPo-Yu Chuang tmp->tm_min, tmp->tm_sec); 110*39ba774fSPo-Yu Chuang 111*39ba774fSPo-Yu Chuang now = ftrtc010_time(); 112*39ba774fSPo-Yu Chuang 113*39ba774fSPo-Yu Chuang debug("%s(): write %lx to record register\n", __func__, new - now); 114*39ba774fSPo-Yu Chuang 115*39ba774fSPo-Yu Chuang writel(new - now, &rtc->record); 116*39ba774fSPo-Yu Chuang 117*39ba774fSPo-Yu Chuang return 0; 118*39ba774fSPo-Yu Chuang } 119*39ba774fSPo-Yu Chuang 120*39ba774fSPo-Yu Chuang void rtc_reset(void) 121*39ba774fSPo-Yu Chuang { 122*39ba774fSPo-Yu Chuang debug("%s()\n", __func__); 123*39ba774fSPo-Yu Chuang ftrtc010_enable(); 124*39ba774fSPo-Yu Chuang } 125