~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to drivers/rtc/m41t11.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2002
 
3
 * Andrew May, Viasat Inc, amay@viasat.com
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License as
 
7
 * published by the Free Software Foundation; either version 2 of
 
8
 * the License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 
18
 * MA 02111-1307 USA
 
19
 */
 
20
 
 
21
/*
 
22
 * M41T11 Serial Access Timekeeper(R) SRAM
 
23
 * can you believe a trademark on that?
 
24
 */
 
25
 
 
26
/* #define DEBUG 1 */
 
27
 
 
28
#include <common.h>
 
29
#include <command.h>
 
30
#include <rtc.h>
 
31
#include <i2c.h>
 
32
 
 
33
/*
 
34
        I Don't have an example config file but this
 
35
        is what should be done.
 
36
 
 
37
#define CONFIG_RTC_M41T11 1
 
38
#define CONFIG_SYS_I2C_RTC_ADDR 0x68
 
39
#if 0
 
40
#define CONFIG_SYS_M41T11_EXT_CENTURY_DATA
 
41
#else
 
42
#define CONFIG_SYS_M41T11_BASE_YEAR 2000
 
43
#endif
 
44
*/
 
45
 
 
46
#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
 
47
 
 
48
/* ------------------------------------------------------------------------- */
 
49
/*
 
50
  these are simple defines for the chip local to here so they aren't too
 
51
  verbose
 
52
  DAY/DATE aren't nice but that is how they are on the data sheet
 
53
*/
 
54
#define RTC_SEC_ADDR       0x0
 
55
#define RTC_MIN_ADDR       0x1
 
56
#define RTC_HOUR_ADDR      0x2
 
57
#define RTC_DAY_ADDR       0x3
 
58
#define RTC_DATE_ADDR      0x4
 
59
#define RTC_MONTH_ADDR     0x5
 
60
#define RTC_YEARS_ADDR     0x6
 
61
 
 
62
#define RTC_REG_CNT        7
 
63
 
 
64
#define RTC_CONTROL_ADDR   0x7
 
65
 
 
66
 
 
67
#ifndef CONFIG_SYS_M41T11_EXT_CENTURY_DATA
 
68
 
 
69
#define REG_CNT            (RTC_REG_CNT+1)
 
70
 
 
71
/*
 
72
  you only get 00-99 for the year we will asume you
 
73
  want from the year 2000 if you don't set the config
 
74
*/
 
75
#ifndef CONFIG_SYS_M41T11_BASE_YEAR
 
76
#define CONFIG_SYS_M41T11_BASE_YEAR 2000
 
77
#endif
 
78
 
 
79
#else
 
80
/* we will store extra year info in byte 9*/
 
81
#define M41T11_YEAR_DATA   0x8
 
82
#define M41T11_YEAR_SIZE   1
 
83
#define REG_CNT            (RTC_REG_CNT+1+M41T11_YEAR_SIZE)
 
84
#endif
 
85
 
 
86
#define M41T11_STORAGE_SZ  (64-REG_CNT)
 
87
 
 
88
int rtc_get (struct rtc_time *tmp)
 
89
{
 
90
        int rel = 0;
 
91
        uchar data[RTC_REG_CNT];
 
92
 
 
93
        i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
 
94
 
 
95
        if( data[RTC_SEC_ADDR] & 0x80 ){
 
96
                printf( "m41t11 RTC Clock stopped!!!\n" );
 
97
                rel = -1;
 
98
        }
 
99
        tmp->tm_sec  = bcd2bin (data[RTC_SEC_ADDR]  & 0x7F);
 
100
        tmp->tm_min  = bcd2bin (data[RTC_MIN_ADDR]  & 0x7F);
 
101
        tmp->tm_hour = bcd2bin (data[RTC_HOUR_ADDR] & 0x3F);
 
102
        tmp->tm_mday = bcd2bin (data[RTC_DATE_ADDR] & 0x3F);
 
103
        tmp->tm_mon  = bcd2bin (data[RTC_MONTH_ADDR]& 0x1F);
 
104
#ifndef CONFIG_SYS_M41T11_EXT_CENTURY_DATA
 
105
        tmp->tm_year = CONFIG_SYS_M41T11_BASE_YEAR
 
106
                + bcd2bin(data[RTC_YEARS_ADDR])
 
107
                + ((data[RTC_HOUR_ADDR]&0x40) ? 100 : 0);
 
108
#else
 
109
        {
 
110
                unsigned char cent;
 
111
                i2c_read(CONFIG_SYS_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
 
112
                if( !(data[RTC_HOUR_ADDR] & 0x80) ){
 
113
                        printf( "m41t11 RTC: cann't keep track of years without CEB set\n" );
 
114
                        rel = -1;
 
115
                }
 
116
                if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){
 
117
                        /*century flip store off new year*/
 
118
                        cent += 1;
 
119
                        i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
 
120
                }
 
121
                tmp->tm_year =((int)cent*100)+bcd2bin(data[RTC_YEARS_ADDR]);
 
122
        }
 
123
#endif
 
124
        tmp->tm_wday = bcd2bin (data[RTC_DAY_ADDR]  & 0x07);
 
125
        tmp->tm_yday = 0;
 
126
        tmp->tm_isdst= 0;
 
127
 
 
128
        debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 
129
                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 
130
                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 
131
 
 
132
        return rel;
 
133
}
 
134
 
 
135
int rtc_set (struct rtc_time *tmp)
 
136
{
 
137
        uchar data[RTC_REG_CNT];
 
138
 
 
139
        debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 
140
                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 
141
                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 
142
 
 
143
        data[RTC_SEC_ADDR]    = bin2bcd(tmp->tm_sec) &  0x7F;/*just in case*/
 
144
        data[RTC_MIN_ADDR]    = bin2bcd(tmp->tm_min);
 
145
        data[RTC_HOUR_ADDR]   = bin2bcd(tmp->tm_hour) & 0x3F;/*handle cent stuff later*/
 
146
        data[RTC_DATE_ADDR]   = bin2bcd(tmp->tm_mday) & 0x3F;
 
147
        data[RTC_MONTH_ADDR]  = bin2bcd(tmp->tm_mon);
 
148
        data[RTC_DAY_ADDR]    = bin2bcd(tmp->tm_wday) & 0x07;
 
149
 
 
150
        data[RTC_HOUR_ADDR]   |= 0x80;/*we will always use CEB*/
 
151
 
 
152
        data[RTC_YEARS_ADDR]  = bin2bcd(tmp->tm_year%100);/*same thing either way*/
 
153
#ifndef CONFIG_SYS_M41T11_EXT_CENTURY_DATA
 
154
        if( ((tmp->tm_year - CONFIG_SYS_M41T11_BASE_YEAR) > 200) ||
 
155
            (tmp->tm_year < CONFIG_SYS_M41T11_BASE_YEAR) ){
 
156
                printf( "m41t11 RTC setting year out of range!!need recompile\n" );
 
157
        }
 
158
        data[RTC_HOUR_ADDR] |= (tmp->tm_year - CONFIG_SYS_M41T11_BASE_YEAR) > 100 ? 0x40 : 0;
 
159
#else
 
160
        {
 
161
                unsigned char cent;
 
162
                cent = tmp->tm_year ? tmp->tm_year / 100 : 0;
 
163
                data[RTC_HOUR_ADDR] |= (cent & 0x1) ? 0x40 : 0;
 
164
                i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
 
165
        }
 
166
#endif
 
167
        i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
 
168
 
 
169
        return 0;
 
170
}
 
171
 
 
172
void rtc_reset (void)
 
173
{
 
174
        unsigned char val;
 
175
        /* clear all control & status registers */
 
176
        i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, 1);
 
177
        val = val & 0x7F;/*make sure we are running*/
 
178
        i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, RTC_REG_CNT);
 
179
 
 
180
        i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
 
181
        val = val & 0x3F;/*turn off freq test keep calibration*/
 
182
        i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
 
183
}
 
184
#endif