uboot/drivers/rtc/x1205.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007
   3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   4 *
   5 * based on a the Linux rtc-x1207.c driver which is:
   6 *      Copyright 2004 Karen Spearel
   7 *      Copyright 2005 Alessandro Zummo
   8 *
   9 * Information and datasheet:
  10 * http://www.intersil.com/cda/deviceinfo/0,1477,X1205,00.html
  11 *
  12 * See file CREDITS for list of people who contributed to this
  13 * project.
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License as
  17 * published by the Free Software Foundation; either version 2 of
  18 * the License, or (at your option) any later version.
  19 *
  20 * This program is distributed in the hope that it will be useful,
  21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 * GNU General Public License for more details.
  24 *
  25 * You should have received a copy of the GNU General Public License
  26 * along with this program; if not, write to the Free Software
  27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  28 * MA 02111-1307 USA
  29 */
  30
  31/*
  32 * Date & Time support for Xicor/Intersil X1205 RTC
  33 */
  34
  35/* #define      DEBUG   */
  36
  37#include <common.h>
  38#include <command.h>
  39#include <rtc.h>
  40#include <i2c.h>
  41
  42#if defined(CONFIG_CMD_DATE)
  43
  44#define CCR_SEC                 0
  45#define CCR_MIN                 1
  46#define CCR_HOUR                2
  47#define CCR_MDAY                3
  48#define CCR_MONTH               4
  49#define CCR_YEAR                5
  50#define CCR_WDAY                6
  51#define CCR_Y2K                 7
  52
  53#define X1205_REG_SR            0x3F    /* status register */
  54#define X1205_REG_Y2K           0x37
  55#define X1205_REG_DW            0x36
  56#define X1205_REG_YR            0x35
  57#define X1205_REG_MO            0x34
  58#define X1205_REG_DT            0x33
  59#define X1205_REG_HR            0x32
  60#define X1205_REG_MN            0x31
  61#define X1205_REG_SC            0x30
  62#define X1205_REG_DTR           0x13
  63#define X1205_REG_ATR           0x12
  64#define X1205_REG_INT           0x11
  65#define X1205_REG_0             0x10
  66#define X1205_REG_Y2K1          0x0F
  67#define X1205_REG_DWA1          0x0E
  68#define X1205_REG_YRA1          0x0D
  69#define X1205_REG_MOA1          0x0C
  70#define X1205_REG_DTA1          0x0B
  71#define X1205_REG_HRA1          0x0A
  72#define X1205_REG_MNA1          0x09
  73#define X1205_REG_SCA1          0x08
  74#define X1205_REG_Y2K0          0x07
  75#define X1205_REG_DWA0          0x06
  76#define X1205_REG_YRA0          0x05
  77#define X1205_REG_MOA0          0x04
  78#define X1205_REG_DTA0          0x03
  79#define X1205_REG_HRA0          0x02
  80#define X1205_REG_MNA0          0x01
  81#define X1205_REG_SCA0          0x00
  82
  83#define X1205_CCR_BASE          0x30    /* Base address of CCR */
  84#define X1205_ALM0_BASE         0x00    /* Base address of ALARM0 */
  85
  86#define X1205_SR_RTCF           0x01    /* Clock failure */
  87#define X1205_SR_WEL            0x02    /* Write Enable Latch */
  88#define X1205_SR_RWEL           0x04    /* Register Write Enable */
  89
  90#define X1205_DTR_DTR0          0x01
  91#define X1205_DTR_DTR1          0x02
  92#define X1205_DTR_DTR2          0x04
  93
  94#define X1205_HR_MIL            0x80    /* Set in ccr.hour for 24 hr mode */
  95
  96static void rtc_write(int reg, u8 val)
  97{
  98        i2c_write(CONFIG_SYS_I2C_RTC_ADDR, reg, 2, &val, 1);
  99}
 100
 101/*
 102 * In the routines that deal directly with the x1205 hardware, we use
 103 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
 104 * Epoch is initialized as 2000. Time is set to UTC.
 105 */
 106int rtc_get(struct rtc_time *tm)
 107{
 108        u8 buf[8];
 109
 110        i2c_read(CONFIG_SYS_I2C_RTC_ADDR, X1205_CCR_BASE, 2, buf, 8);
 111
 112        debug("%s: raw read data - sec=%02x, min=%02x, hr=%02x, "
 113              "mday=%02x, mon=%02x, year=%02x, wday=%02x, y2k=%02x\n",
 114              __FUNCTION__,
 115              buf[0], buf[1], buf[2], buf[3],
 116              buf[4], buf[5], buf[6], buf[7]);
 117
 118        tm->tm_sec = bcd2bin(buf[CCR_SEC]);
 119        tm->tm_min = bcd2bin(buf[CCR_MIN]);
 120        tm->tm_hour = bcd2bin(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
 121        tm->tm_mday = bcd2bin(buf[CCR_MDAY]);
 122        tm->tm_mon = bcd2bin(buf[CCR_MONTH]); /* mon is 0-11 */
 123        tm->tm_year = bcd2bin(buf[CCR_YEAR])
 124                + (bcd2bin(buf[CCR_Y2K]) * 100);
 125        tm->tm_wday = buf[CCR_WDAY];
 126
 127        debug("%s: tm is secs=%d, mins=%d, hours=%d, "
 128              "mday=%d, mon=%d, year=%d, wday=%d\n",
 129              __FUNCTION__,
 130              tm->tm_sec, tm->tm_min, tm->tm_hour,
 131              tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 132
 133        return 0;
 134}
 135
 136int rtc_set(struct rtc_time *tm)
 137{
 138        int i;
 139        u8 buf[8];
 140
 141        debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 142              tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
 143              tm->tm_hour, tm->tm_min, tm->tm_sec);
 144
 145        buf[CCR_SEC] = bin2bcd(tm->tm_sec);
 146        buf[CCR_MIN] = bin2bcd(tm->tm_min);
 147
 148        /* set hour and 24hr bit */
 149        buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL;
 150
 151        buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
 152
 153        /* month, 1 - 12 */
 154        buf[CCR_MONTH] = bin2bcd(tm->tm_mon);
 155
 156        /* year, since the rtc epoch*/
 157        buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
 158        buf[CCR_WDAY] = tm->tm_wday & 0x07;
 159        buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
 160
 161        /* this sequence is required to unlock the chip */
 162        rtc_write(X1205_REG_SR, X1205_SR_WEL);
 163        rtc_write(X1205_REG_SR, X1205_SR_WEL | X1205_SR_RWEL);
 164
 165        /* write register's data */
 166        for (i = 0; i < 8; i++)
 167                rtc_write(X1205_CCR_BASE + i, buf[i]);
 168
 169        rtc_write(X1205_REG_SR, 0);
 170
 171        return 0;
 172}
 173
 174void rtc_reset(void)
 175{
 176        /*
 177         * Nothing to do
 178         */
 179}
 180
 181#endif
 182