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_xicor1241.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
#include <
linux/bcd.h
>
13
#include <linux/types.h>
14
#include <linux/time.h>
15
16
#include <asm/time.h>
17
#include <asm/addrspace.h>
18
#include <asm/io.h>
19
20
#include <
asm/sibyte/sb1250.h
>
21
#include <
asm/sibyte/sb1250_regs.h
>
22
#include <
asm/sibyte/sb1250_smbus.h
>
23
24
25
/* Xicor 1241 definitions */
26
27
/*
28
* Register bits
29
*/
30
31
#define X1241REG_SR_BAT 0x80
/* currently on battery power */
32
#define X1241REG_SR_RWEL 0x04
/* r/w latch is enabled, can write RTC */
33
#define X1241REG_SR_WEL 0x02
/* r/w latch is unlocked, can enable r/w now */
34
#define X1241REG_SR_RTCF 0x01
/* clock failed */
35
#define X1241REG_BL_BP2 0x80
/* block protect 2 */
36
#define X1241REG_BL_BP1 0x40
/* block protect 1 */
37
#define X1241REG_BL_BP0 0x20
/* block protect 0 */
38
#define X1241REG_BL_WD1 0x10
39
#define X1241REG_BL_WD0 0x08
40
#define X1241REG_HR_MIL 0x80
/* military time format */
41
42
/*
43
* Register numbers
44
*/
45
46
#define X1241REG_BL 0x10
/* block protect bits */
47
#define X1241REG_INT 0x11
/* */
48
#define X1241REG_SC 0x30
/* Seconds */
49
#define X1241REG_MN 0x31
/* Minutes */
50
#define X1241REG_HR 0x32
/* Hours */
51
#define X1241REG_DT 0x33
/* Day of month */
52
#define X1241REG_MO 0x34
/* Month */
53
#define X1241REG_YR 0x35
/* Year */
54
#define X1241REG_DW 0x36
/* Day of Week */
55
#define X1241REG_Y2K 0x37
/* Year 2K */
56
#define X1241REG_SR 0x3F
/* Status register */
57
58
#define X1241_CCR_ADDRESS 0x6F
59
60
#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
61
62
static
int
xicor_read(
uint8_t
addr
)
63
{
64
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_BUSY
)
65
;
66
67
__raw_writeq
((addr >> 8) & 0x7,
SMB_CSR
(
R_SMB_CMD
));
68
__raw_writeq
(addr & 0xff,
SMB_CSR
(
R_SMB_DATA
));
69
__raw_writeq
(
V_SMB_ADDR
(
X1241_CCR_ADDRESS
) |
V_SMB_TT_WR2BYTE
,
70
SMB_CSR
(
R_SMB_START
));
71
72
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
73
;
74
75
__raw_writeq
(
V_SMB_ADDR
(
X1241_CCR_ADDRESS
) |
V_SMB_TT_RD1BYTE
,
76
SMB_CSR
(
R_SMB_START
));
77
78
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
79
;
80
81
if
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_ERROR
) {
82
/* Clear error bit by writing a 1 */
83
__raw_writeq
(M_SMB_ERROR,
SMB_CSR
(
R_SMB_STATUS
));
84
return
-1;
85
}
86
87
return
(
__raw_readq
(
SMB_CSR
(
R_SMB_DATA
)) & 0xff);
88
}
89
90
static
int
xicor_write(
uint8_t
addr
,
int
b
)
91
{
92
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_BUSY
)
93
;
94
95
__raw_writeq
(addr,
SMB_CSR
(
R_SMB_CMD
));
96
__raw_writeq
((addr & 0xff) | ((b & 0xff) << 8),
SMB_CSR
(
R_SMB_DATA
));
97
__raw_writeq
(
V_SMB_ADDR
(
X1241_CCR_ADDRESS
) |
V_SMB_TT_WR3BYTE
,
98
SMB_CSR
(
R_SMB_START
));
99
100
while
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) & M_SMB_BUSY)
101
;
102
103
if
(
__raw_readq
(
SMB_CSR
(
R_SMB_STATUS
)) &
M_SMB_ERROR
) {
104
/* Clear error bit by writing a 1 */
105
__raw_writeq
(M_SMB_ERROR,
SMB_CSR
(
R_SMB_STATUS
));
106
return
-1;
107
}
else
{
108
return
0;
109
}
110
}
111
112
int
xicor_set_time
(
unsigned
long
t
)
113
{
114
struct
rtc_time
tm;
115
int
tmp
;
116
unsigned
long
flags
;
117
118
rtc_time_to_tm
(t, &tm);
119
tm.
tm_year
+= 1900;
120
121
spin_lock_irqsave
(&
rtc_lock
, flags);
122
/* unlock writes to the CCR */
123
xicor_write(
X1241REG_SR
,
X1241REG_SR_WEL
);
124
xicor_write(
X1241REG_SR
,
X1241REG_SR_WEL
|
X1241REG_SR_RWEL
);
125
126
/* trivial ones */
127
tm.
tm_sec
=
bin2bcd
(tm.
tm_sec
);
128
xicor_write(
X1241REG_SC
, tm.
tm_sec
);
129
130
tm.
tm_min
=
bin2bcd
(tm.
tm_min
);
131
xicor_write(
X1241REG_MN
, tm.
tm_min
);
132
133
tm.
tm_mday
=
bin2bcd
(tm.
tm_mday
);
134
xicor_write(
X1241REG_DT
, tm.
tm_mday
);
135
136
/* tm_mon starts from 0, *ick* */
137
tm.
tm_mon
++;
138
tm.
tm_mon
=
bin2bcd
(tm.
tm_mon
);
139
xicor_write(
X1241REG_MO
, tm.
tm_mon
);
140
141
/* year is split */
142
tmp = tm.
tm_year
/ 100;
143
tm.
tm_year
%= 100;
144
xicor_write(
X1241REG_YR
, tm.
tm_year
);
145
xicor_write(
X1241REG_Y2K
, tmp);
146
147
/* hour is the most tricky one */
148
tmp = xicor_read(
X1241REG_HR
);
149
if
(tmp &
X1241REG_HR_MIL
) {
150
/* 24 hour format */
151
tm.
tm_hour
=
bin2bcd
(tm.
tm_hour
);
152
tmp = (tmp & ~0x3f) | (tm.
tm_hour
& 0x3f);
153
}
else
{
154
/* 12 hour format, with 0x2 for pm */
155
tmp = tmp & ~0x3f;
156
if
(tm.
tm_hour
>= 12) {
157
tmp |= 0x20;
158
tm.
tm_hour
-= 12;
159
}
160
tm.
tm_hour
=
bin2bcd
(tm.
tm_hour
);
161
tmp |= tm.
tm_hour
;
162
}
163
xicor_write(
X1241REG_HR
, tmp);
164
165
xicor_write(
X1241REG_SR
, 0);
166
spin_unlock_irqrestore(&
rtc_lock
, flags);
167
168
return
0;
169
}
170
171
unsigned
long
xicor_get_time
(
void
)
172
{
173
unsigned
int
year
, mon,
day
,
hour
,
min
,
sec
, y2k;
174
unsigned
long
flags
;
175
176
spin_lock_irqsave
(&
rtc_lock
, flags);
177
sec = xicor_read(
X1241REG_SC
);
178
min = xicor_read(
X1241REG_MN
);
179
hour = xicor_read(
X1241REG_HR
);
180
181
if
(hour &
X1241REG_HR_MIL
) {
182
hour &= 0x3f;
183
}
else
{
184
if
(hour & 0x20)
185
hour = (hour & 0xf) + 0x12;
186
}
187
188
day = xicor_read(
X1241REG_DT
);
189
mon = xicor_read(
X1241REG_MO
);
190
year = xicor_read(
X1241REG_YR
);
191
y2k = xicor_read(
X1241REG_Y2K
);
192
spin_unlock_irqrestore(&
rtc_lock
, flags);
193
194
sec =
bcd2bin
(sec);
195
min =
bcd2bin
(min);
196
hour =
bcd2bin
(hour);
197
day =
bcd2bin
(day);
198
mon =
bcd2bin
(mon);
199
year =
bcd2bin
(year);
200
y2k =
bcd2bin
(y2k);
201
202
year += (y2k * 100);
203
204
return
mktime
(year, mon, day, hour, min, sec);
205
}
206
207
int
xicor_probe
(
void
)
208
{
209
return
(xicor_read(
X1241REG_SC
) != -1);
210
}
Generated on Thu Jan 10 2013 13:12:19 for Linux Kernel by
1.8.2