Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
mips
sibyte
swarm
rtc_m41t81.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2000, 2001 Broadcom Corporation
3
*
4
* Copyright (C) 2002 MontaVista Software Inc.
5
* Author:
[email protected]
or
[email protected]
6
*
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation; either version 2 of the License, or (at your
10
* option) any later version.
11
*
12
*/
13
#include <
linux/bcd.h
>
14
#include <linux/types.h>
15
#include <linux/time.h>
16
17
#include <asm/time.h>
18
#include <asm/addrspace.h>
19
#include <asm/io.h>
20
21
#include <
asm/sibyte/sb1250.h
>
22
#include <
asm/sibyte/sb1250_regs.h
>
23
#include <
asm/sibyte/sb1250_smbus.h
>
24
25
26
/* M41T81 definitions */
27
28
/*
29
* Register bits
30
*/
31
32
#define M41T81REG_SC_ST 0x80
/* stop bit */
33
#define M41T81REG_HR_CB 0x40
/* century bit */
34
#define M41T81REG_HR_CEB 0x80
/* century enable bit */
35
#define M41T81REG_CTL_S 0x20
/* sign bit */
36
#define M41T81REG_CTL_FT 0x40
/* frequency test bit */
37
#define M41T81REG_CTL_OUT 0x80
/* output level */
38
#define M41T81REG_WD_RB0 0x01
/* watchdog resolution bit 0 */
39
#define M41T81REG_WD_RB1 0x02
/* watchdog resolution bit 1 */
40
#define M41T81REG_WD_BMB0 0x04
/* watchdog multiplier bit 0 */
41
#define M41T81REG_WD_BMB1 0x08
/* watchdog multiplier bit 1 */
42
#define M41T81REG_WD_BMB2 0x10
/* watchdog multiplier bit 2 */
43
#define M41T81REG_WD_BMB3 0x20
/* watchdog multiplier bit 3 */
44
#define M41T81REG_WD_BMB4 0x40
/* watchdog multiplier bit 4 */
45
#define M41T81REG_AMO_ABE 0x20
/* alarm in "battery back-up mode" enable bit */
46
#define M41T81REG_AMO_SQWE 0x40
/* square wave enable */
47
#define M41T81REG_AMO_AFE 0x80
/* alarm flag enable flag */
48
#define M41T81REG_ADT_RPT5 0x40
/* alarm repeat mode bit 5 */
49
#define M41T81REG_ADT_RPT4 0x80
/* alarm repeat mode bit 4 */
50
#define M41T81REG_AHR_RPT3 0x80
/* alarm repeat mode bit 3 */
51
#define M41T81REG_AHR_HT 0x40
/* halt update bit */
52
#define M41T81REG_AMN_RPT2 0x80
/* alarm repeat mode bit 2 */
53
#define M41T81REG_ASC_RPT1 0x80
/* alarm repeat mode bit 1 */
54
#define M41T81REG_FLG_AF 0x40
/* alarm flag (read only) */
55
#define M41T81REG_FLG_WDF 0x80
/* watchdog flag (read only) */
56
#define M41T81REG_SQW_RS0 0x10
/* sqw frequency bit 0 */
57
#define M41T81REG_SQW_RS1 0x20
/* sqw frequency bit 1 */
58
#define M41T81REG_SQW_RS2 0x40
/* sqw frequency bit 2 */
59
#define M41T81REG_SQW_RS3 0x80
/* sqw frequency bit 3 */
60
61
62
/*
63
* Register numbers
64
*/
65
66
#define M41T81REG_TSC 0x00
/* tenths/hundredths of second */
67
#define M41T81REG_SC 0x01
/* seconds */
68
#define M41T81REG_MN 0x02
/* minute */
69
#define M41T81REG_HR 0x03
/* hour/century */
70
#define M41T81REG_DY 0x04
/* day of week */
71
#define M41T81REG_DT 0x05
/* date of month */
72
#define M41T81REG_MO 0x06
/* month */
73
#define M41T81REG_YR 0x07
/* year */
74
#define M41T81REG_CTL 0x08
/* control */
75
#define M41T81REG_WD 0x09
/* watchdog */
76
#define M41T81REG_AMO 0x0A
/* alarm: month */
77
#define M41T81REG_ADT 0x0B
/* alarm: date */
78
#define M41T81REG_AHR 0x0C
/* alarm: hour */
79
#define M41T81REG_AMN 0x0D
/* alarm: minute */
80
#define M41T81REG_ASC 0x0E
/* alarm: second */
81
#define M41T81REG_FLG 0x0F
/* flags */
82
#define M41T81REG_SQW 0x13
/* square wave register */
83
84
#define M41T81_CCR_ADDRESS 0x68
85
86
#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
87
88
static
int
m41t81_read(
uint8_t
addr
)
89
{
90
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_BUSY
)
91
;
92
93
__raw_writeq
(addr & 0xff,
SMB_CSR
(
R_SMB_CMD
));
94
__raw_writeq
(
V_SMB_ADDR
(
M41T81_CCR_ADDRESS
) |
V_SMB_TT_WR1BYTE
,
95
SMB_CSR
(
R_SMB_START
));
96
97
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
98
;
99
100
__raw_writeq
(
V_SMB_ADDR
(
M41T81_CCR_ADDRESS
) |
V_SMB_TT_RD1BYTE
,
101
SMB_CSR
(
R_SMB_START
));
102
103
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
104
;
105
106
if
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_ERROR
) {
107
/* Clear error bit by writing a 1 */
108
__raw_writeq
(M_SMB_ERROR,
SMB_CSR
(
R_SMB_STATUS
));
109
return
-1;
110
}
111
112
return
(
__raw_readq
(
SMB_CSR
(
R_SMB_DATA
)) & 0xff);
113
}
114
115
static
int
m41t81_write(
uint8_t
addr
,
int
b
)
116
{
117
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_BUSY
)
118
;
119
120
__raw_writeq
(addr & 0xff,
SMB_CSR
(
R_SMB_CMD
));
121
__raw_writeq
(b & 0xff,
SMB_CSR
(
R_SMB_DATA
));
122
__raw_writeq
(
V_SMB_ADDR
(
M41T81_CCR_ADDRESS
) |
V_SMB_TT_WR2BYTE
,
123
SMB_CSR
(
R_SMB_START
));
124
125
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
126
;
127
128
if
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_ERROR
) {
129
/* Clear error bit by writing a 1 */
130
__raw_writeq
(M_SMB_ERROR,
SMB_CSR
(
R_SMB_STATUS
));
131
return
-1;
132
}
133
134
/* read the same byte again to make sure it is written */
135
__raw_writeq
(
V_SMB_ADDR
(
M41T81_CCR_ADDRESS
) |
V_SMB_TT_RD1BYTE
,
136
SMB_CSR
(
R_SMB_START
));
137
138
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
139
;
140
141
return
0;
142
}
143
144
int
m41t81_set_time
(
unsigned
long
t
)
145
{
146
struct
rtc_time
tm;
147
unsigned
long
flags
;
148
149
/* Note we don't care about the century */
150
rtc_time_to_tm
(t, &tm);
151
152
/*
153
* Note the write order matters as it ensures the correctness.
154
* When we write sec, 10th sec is clear. It is reasonable to
155
* believe we should finish writing min within a second.
156
*/
157
158
spin_lock_irqsave
(&
rtc_lock
, flags);
159
tm.
tm_sec
=
bin2bcd
(tm.
tm_sec
);
160
m41t81_write(
M41T81REG_SC
, tm.
tm_sec
);
161
162
tm.
tm_min
=
bin2bcd
(tm.
tm_min
);
163
m41t81_write(
M41T81REG_MN
, tm.
tm_min
);
164
165
tm.
tm_hour
=
bin2bcd
(tm.
tm_hour
);
166
tm.
tm_hour
= (tm.
tm_hour
& 0x3f) | (m41t81_read(
M41T81REG_HR
) & 0xc0);
167
m41t81_write(
M41T81REG_HR
, tm.
tm_hour
);
168
169
/* tm_wday starts from 0 to 6 */
170
if
(tm.
tm_wday
== 0) tm.
tm_wday
= 7;
171
tm.
tm_wday
=
bin2bcd
(tm.
tm_wday
);
172
m41t81_write(
M41T81REG_DY
, tm.
tm_wday
);
173
174
tm.
tm_mday
=
bin2bcd
(tm.
tm_mday
);
175
m41t81_write(
M41T81REG_DT
, tm.
tm_mday
);
176
177
/* tm_mon starts from 0, *ick* */
178
tm.
tm_mon
++;
179
tm.
tm_mon
=
bin2bcd
(tm.
tm_mon
);
180
m41t81_write(
M41T81REG_MO
, tm.
tm_mon
);
181
182
/* we don't do century, everything is beyond 2000 */
183
tm.
tm_year
%= 100;
184
tm.
tm_year
=
bin2bcd
(tm.
tm_year
);
185
m41t81_write(
M41T81REG_YR
, tm.
tm_year
);
186
spin_unlock_irqrestore(&
rtc_lock
, flags);
187
188
return
0;
189
}
190
191
unsigned
long
m41t81_get_time
(
void
)
192
{
193
unsigned
int
year
, mon,
day
,
hour
,
min
,
sec
;
194
unsigned
long
flags
;
195
196
/*
197
* min is valid if two reads of sec are the same.
198
*/
199
for
(;;) {
200
spin_lock_irqsave
(&
rtc_lock
, flags);
201
sec = m41t81_read(
M41T81REG_SC
);
202
min = m41t81_read(
M41T81REG_MN
);
203
if
(sec == m41t81_read(
M41T81REG_SC
))
break
;
204
spin_unlock_irqrestore(&
rtc_lock
, flags);
205
}
206
hour = m41t81_read(
M41T81REG_HR
) & 0x3f;
207
day = m41t81_read(
M41T81REG_DT
);
208
mon = m41t81_read(
M41T81REG_MO
);
209
year = m41t81_read(
M41T81REG_YR
);
210
spin_unlock_irqrestore(&
rtc_lock
, flags);
211
212
sec =
bcd2bin
(sec);
213
min =
bcd2bin
(min);
214
hour =
bcd2bin
(hour);
215
day =
bcd2bin
(day);
216
mon =
bcd2bin
(mon);
217
year =
bcd2bin
(year);
218
219
year += 2000;
220
221
return
mktime
(year, mon, day, hour, min, sec);
222
}
223
224
int
m41t81_probe
(
void
)
225
{
226
unsigned
int
tmp
;
227
228
/* enable chip if it is not enabled yet */
229
tmp = m41t81_read(
M41T81REG_SC
);
230
m41t81_write(
M41T81REG_SC
, tmp & 0x7f);
231
232
return
(m41t81_read(
M41T81REG_SC
) != -1);
233
}
Generated on Thu Jan 10 2013 13:12:18 for Linux Kernel by
1.8.2