From patchwork Wed Jan 12 07:20:05 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiko Schocher X-Patchwork-Id: 78518 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id D123FB6EF1 for ; Wed, 12 Jan 2011 18:28:53 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5B1142810E; Wed, 12 Jan 2011 08:28:52 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lCQRypTLQ9dX; Wed, 12 Jan 2011 08:28:52 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B872628114; Wed, 12 Jan 2011 08:28:50 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1FAB528114 for ; Wed, 12 Jan 2011 08:28:48 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7uEMjXoo9Oee for ; Wed, 12 Jan 2011 08:28:46 +0100 (CET) X-Greylist: delayed 516 seconds by postgrey-1.27 at theia; Wed, 12 Jan 2011 08:28:44 CET X-policyd-weight: IN_SBL_XBL_SPAMHAUS=4.35 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from pollux.denx.de (p4FF0750C.dip.t-dialin.net [79.240.117.12]) by theia.denx.de (Postfix) with ESMTP id 04FB42810B for ; Wed, 12 Jan 2011 08:28:44 +0100 (CET) Received: by pollux.denx.de (Postfix, from userid 515) id 822C218014D64; Wed, 12 Jan 2011 08:20:08 +0100 (CET) From: Heiko Schocher To: u-boot@lists.denx.de Date: Wed, 12 Jan 2011 08:20:05 +0100 Message-Id: <1294816806-32614-1-git-send-email-hs@denx.de> X-Mailer: git-send-email 1.7.3.4 Cc: Heiko Schocher Subject: [U-Boot] [PATCH 1/2] rtc: add support for Micro Crystal RV-3029-C2 RTC X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Signed-off-by: Heiko Schocher --- drivers/rtc/Makefile | 1 + drivers/rtc/rv3029.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 0 deletions(-) create mode 100644 drivers/rtc/rv3029.c diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 916d73f..e4be4a4 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -60,6 +60,7 @@ COBJS-$(CONFIG_RTC_PL031) += pl031.o COBJS-$(CONFIG_RTC_PT7C4338) += pt7c4338.o COBJS-$(CONFIG_RTC_RS5C372A) += rs5c372.o COBJS-$(CONFIG_RTC_RTC4543) += rtc4543.o +COBJS-$(CONFIG_RTC_RV3029) += rv3029.o COBJS-$(CONFIG_RTC_RX8025) += rx8025.o COBJS-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o COBJS-$(CONFIG_RTC_S3C44B0) += s3c44b0_rtc.o diff --git a/drivers/rtc/rv3029.c b/drivers/rtc/rv3029.c new file mode 100644 index 0000000..3ebc768 --- /dev/null +++ b/drivers/rtc/rv3029.c @@ -0,0 +1,124 @@ +/* + * (C) Copyright 2010 + * Heiko Schocher, DENX Software Engineering, hs@denx.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include + +#define RTC_RV3029_CTRL_RESET 0x04 +#define RTC_RV3029_CTRL_SYS_R (1 << 4) + +#define RTC_RV3029_CLOCK_PAGE 0x08 +#define RTC_RV3029_PAGE_LEN 7 + +#define RV3029C2_W_SECONDS 0x00 +#define RV3029C2_W_MINUTES 0x01 +#define RV3029C2_W_HOURS 0x02 +#define RV3029C2_W_DATE 0x03 +#define RV3029C2_W_DAYS 0x04 +#define RV3029C2_W_MONTHS 0x05 +#define RV3029C2_W_YEARS 0x06 + +#define RV3029C2_REG_HR_12_24 (1 << 6) /* 24h/12h mode */ +#define RV3029C2_REG_HR_PM (1 << 5) /* PM/AM bit in 12h mode */ + +int rtc_get( struct rtc_time *tmp ) +{ + int ret; + unsigned char buf[RTC_RV3029_PAGE_LEN]; + + ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1, buf, \ + RTC_RV3029_PAGE_LEN); + if (ret) { + printf("%s: error reading RTC: %x\n", __func__, ret); + return -1; + } + tmp->tm_sec = bcd2bin( buf[RV3029C2_W_SECONDS] & 0x7f); + tmp->tm_min = bcd2bin( buf[RV3029C2_W_MINUTES] & 0x7f); + if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_12_24) { + /* 12h format */ + tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x1f); + if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_PM) + /* PM flag set */ + tmp->tm_hour += 12; + } else + tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x3f); + + tmp->tm_mday = bcd2bin( buf[RV3029C2_W_DATE] & 0x3F ); + tmp->tm_mon = bcd2bin( buf[RV3029C2_W_MONTHS] & 0x1F ); + tmp->tm_wday = bcd2bin( buf[RV3029C2_W_DAYS] & 0x07 ); + /* RTC supports only years > 1999 */ + tmp->tm_year = bcd2bin( buf[RV3029C2_W_YEARS]) + 2000; + tmp->tm_yday = 0; + tmp->tm_isdst = 0; + +#ifdef RTC_DEBUG + printf( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); + +#endif + return 0; +} + +int rtc_set( struct rtc_time *tmp ) +{ + int ret; + unsigned char buf[RTC_RV3029_PAGE_LEN]; +#ifdef RTC_DEBUG + printf( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif + + if (tmp->tm_year < 2000) { + printf("RTC: year %d < 2000 not possible\n", tmp->tm_year); + return -1; + } + buf[RV3029C2_W_SECONDS] = bin2bcd(tmp->tm_sec); + buf[RV3029C2_W_MINUTES] = bin2bcd(tmp->tm_min); + buf[RV3029C2_W_HOURS] = bin2bcd(tmp->tm_hour); + /* set 24h format */ + buf[RV3029C2_W_HOURS] &= ~RV3029C2_REG_HR_12_24; + buf[RV3029C2_W_DATE] = bin2bcd(tmp->tm_mday); + buf[RV3029C2_W_DAYS] = bin2bcd(tmp->tm_wday); + buf[RV3029C2_W_MONTHS] = bin2bcd(tmp->tm_mon); + tmp->tm_year -= 2000; + buf[RV3029C2_W_YEARS] = bin2bcd(tmp->tm_year); + ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1, + buf, RTC_RV3029_PAGE_LEN); + + /* give the RTC some time to update */ + udelay(1000); + return 0; +} + +void rtc_reset (void) +{ + int ret; + unsigned char buf[RTC_RV3029_PAGE_LEN]; + + buf[0] = RTC_RV3029_CTRL_SYS_R; + ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_RESET, 1, + buf, 1); +}