Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
2130835d
Commit
2130835d
authored
Mar 01, 2004
by
Tom Rini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PPC32: Update the TODC code from 2.4.
parent
37ff5b87
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
248 additions
and
91 deletions
+248
-91
arch/ppc/syslib/todc_time.c
arch/ppc/syslib/todc_time.c
+106
-46
include/asm-ppc/todc.h
include/asm-ppc/todc.h
+142
-45
No files found.
arch/ppc/syslib/todc_time.c
View file @
2130835d
...
@@ -50,6 +50,8 @@
...
@@ -50,6 +50,8 @@
* --MAG
* --MAG
*/
*/
extern
spinlock_t
rtc_lock
;
/*
/*
* 'todc_info' should be initialized in your *_setup.c file to
* 'todc_info' should be initialized in your *_setup.c file to
* point to a fully initialized 'todc_info_t' structure.
* point to a fully initialized 'todc_info_t' structure.
...
@@ -126,6 +128,54 @@ todc_mc146818_write_val(int addr, unsigned char val)
...
@@ -126,6 +128,54 @@ todc_mc146818_write_val(int addr, unsigned char val)
return
;
return
;
}
}
/*
* Routines to make RTC chips with NVRAM buried behind an addr/data pair
* have the NVRAM and clock regs appear at the same level.
* The NVRAM will appear to start at addr 0 and the clock regs will appear
* to start immediately after the NVRAM (actually, start at offset
* todc_info->nvram_size).
*/
static
inline
u_char
todc_read_val
(
int
addr
)
{
u_char
val
;
if
(
todc_info
->
sw_flags
&
TODC_FLAG_2_LEVEL_NVRAM
)
{
if
(
addr
<
todc_info
->
nvram_size
)
{
/* NVRAM */
ppc_md
.
nvram_write_val
(
todc_info
->
nvram_addr_reg
,
addr
);
val
=
ppc_md
.
nvram_read_val
(
todc_info
->
nvram_data_reg
);
}
else
{
/* Clock Reg */
addr
-=
todc_info
->
nvram_size
;
val
=
ppc_md
.
nvram_read_val
(
addr
);
}
}
else
{
val
=
ppc_md
.
nvram_read_val
(
addr
);
}
return
val
;
}
static
inline
void
todc_write_val
(
int
addr
,
u_char
val
)
{
if
(
todc_info
->
sw_flags
&
TODC_FLAG_2_LEVEL_NVRAM
)
{
if
(
addr
<
todc_info
->
nvram_size
)
{
/* NVRAM */
ppc_md
.
nvram_write_val
(
todc_info
->
nvram_addr_reg
,
addr
);
ppc_md
.
nvram_write_val
(
todc_info
->
nvram_data_reg
,
val
);
}
else
{
/* Clock Reg */
addr
-=
todc_info
->
nvram_size
;
ppc_md
.
nvram_write_val
(
addr
,
val
);
}
}
else
{
ppc_md
.
nvram_write_val
(
addr
,
val
);
}
}
/*
/*
* TODC routines
* TODC routines
*
*
...
@@ -148,7 +198,7 @@ todc_time_init(void)
...
@@ -148,7 +198,7 @@ todc_time_init(void)
if
(
not_initialized
)
{
if
(
not_initialized
)
{
u_char
cntl_b
;
u_char
cntl_b
;
cntl_b
=
ppc_md
.
nvram
_read_val
(
todc_info
->
control_b
);
cntl_b
=
todc
_read_val
(
todc_info
->
control_b
);
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
if
((
cntl_b
&
0x70
)
!=
0x20
)
{
if
((
cntl_b
&
0x70
)
!=
0x20
)
{
...
@@ -159,7 +209,18 @@ todc_time_init(void)
...
@@ -159,7 +209,18 @@ todc_time_init(void)
cntl_b
|=
0x20
;
cntl_b
|=
0x20
;
}
}
ppc_md
.
nvram_write_val
(
todc_info
->
control_b
,
cntl_b
);
todc_write_val
(
todc_info
->
control_b
,
cntl_b
);
}
else
if
(
todc_info
->
rtc_type
==
TODC_TYPE_DS17285
)
{
u_char
mode
;
mode
=
todc_read_val
(
TODC_TYPE_DS17285_CNTL_A
);
/* Make sure countdown clear is not set */
mode
&=
~
0x40
;
/* Enable oscillator, extended register set */
mode
|=
0x30
;
todc_write_val
(
TODC_TYPE_DS17285_CNTL_A
,
mode
);
}
}
else
if
(
todc_info
->
rtc_type
==
TODC_TYPE_DS1501
)
{
else
if
(
todc_info
->
rtc_type
==
TODC_TYPE_DS1501
)
{
u_char
month
;
u_char
month
;
...
@@ -167,18 +228,18 @@ todc_time_init(void)
...
@@ -167,18 +228,18 @@ todc_time_init(void)
todc_info
->
enable_read
=
TODC_DS1501_CNTL_B_TE
;
todc_info
->
enable_read
=
TODC_DS1501_CNTL_B_TE
;
todc_info
->
enable_write
=
TODC_DS1501_CNTL_B_TE
;
todc_info
->
enable_write
=
TODC_DS1501_CNTL_B_TE
;
month
=
ppc_md
.
nvram
_read_val
(
todc_info
->
month
);
month
=
todc
_read_val
(
todc_info
->
month
);
if
((
month
&
0x80
)
==
0x80
)
{
if
((
month
&
0x80
)
==
0x80
)
{
printk
(
KERN_INFO
"TODC %s %s
\n
"
,
printk
(
KERN_INFO
"TODC %s %s
\n
"
,
"real-time-clock was stopped."
,
"real-time-clock was stopped."
,
"Now starting..."
);
"Now starting..."
);
month
&=
~
0x80
;
month
&=
~
0x80
;
ppc_md
.
nvram
_write_val
(
todc_info
->
month
,
month
);
todc
_write_val
(
todc_info
->
month
,
month
);
}
}
cntl_b
&=
~
TODC_DS1501_CNTL_B_TE
;
cntl_b
&=
~
TODC_DS1501_CNTL_B_TE
;
ppc_md
.
nvram
_write_val
(
todc_info
->
control_b
,
cntl_b
);
todc
_write_val
(
todc_info
->
control_b
,
cntl_b
);
}
}
else
{
/* must be a m48txx type */
else
{
/* must be a m48txx type */
u_char
cntl_a
;
u_char
cntl_a
;
...
@@ -186,7 +247,7 @@ todc_time_init(void)
...
@@ -186,7 +247,7 @@ todc_time_init(void)
todc_info
->
enable_read
=
TODC_MK48TXX_CNTL_A_R
;
todc_info
->
enable_read
=
TODC_MK48TXX_CNTL_A_R
;
todc_info
->
enable_write
=
TODC_MK48TXX_CNTL_A_W
;
todc_info
->
enable_write
=
TODC_MK48TXX_CNTL_A_W
;
cntl_a
=
ppc_md
.
nvram
_read_val
(
todc_info
->
control_a
);
cntl_a
=
todc
_read_val
(
todc_info
->
control_a
);
/* Check & clear STOP bit in control B register */
/* Check & clear STOP bit in control B register */
if
(
cntl_b
&
TODC_MK48TXX_DAY_CB
)
{
if
(
cntl_b
&
TODC_MK48TXX_DAY_CB
)
{
...
@@ -197,16 +258,14 @@ todc_time_init(void)
...
@@ -197,16 +258,14 @@ todc_time_init(void)
cntl_a
|=
todc_info
->
enable_write
;
cntl_a
|=
todc_info
->
enable_write
;
cntl_b
&=
~
TODC_MK48TXX_DAY_CB
;
/* Start Oscil */
cntl_b
&=
~
TODC_MK48TXX_DAY_CB
;
/* Start Oscil */
ppc_md
.
nvram_write_val
(
todc_info
->
control_a
,
todc_write_val
(
todc_info
->
control_a
,
cntl_a
);
cntl_a
);
todc_write_val
(
todc_info
->
control_b
,
cntl_b
);
ppc_md
.
nvram_write_val
(
todc_info
->
control_b
,
cntl_b
);
}
}
/* Make sure READ & WRITE bits are cleared. */
/* Make sure READ & WRITE bits are cleared. */
cntl_a
&=
~
(
todc_info
->
enable_write
|
cntl_a
&=
~
(
todc_info
->
enable_write
|
todc_info
->
enable_read
);
todc_info
->
enable_read
);
ppc_md
.
nvram
_write_val
(
todc_info
->
control_a
,
cntl_a
);
todc
_write_val
(
todc_info
->
control_a
,
cntl_a
);
}
}
not_initialized
=
0
;
not_initialized
=
0
;
...
@@ -231,7 +290,8 @@ todc_get_rtc_time(void)
...
@@ -231,7 +290,8 @@ todc_get_rtc_time(void)
uint
limit
,
i
;
uint
limit
,
i
;
u_char
save_control
,
uip
;
u_char
save_control
,
uip
;
save_control
=
ppc_md
.
nvram_read_val
(
todc_info
->
control_a
);
spin_lock
(
&
rtc_lock
);
save_control
=
todc_read_val
(
todc_info
->
control_a
);
if
(
todc_info
->
rtc_type
!=
TODC_TYPE_MC146818
)
{
if
(
todc_info
->
rtc_type
!=
TODC_TYPE_MC146818
)
{
limit
=
1
;
limit
=
1
;
...
@@ -241,9 +301,10 @@ todc_get_rtc_time(void)
...
@@ -241,9 +301,10 @@ todc_get_rtc_time(void)
case
TODC_TYPE_DS1743
:
case
TODC_TYPE_DS1743
:
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS17285
:
break
;
break
;
default:
default:
ppc_md
.
nvram
_write_val
(
todc_info
->
control_a
,
todc
_write_val
(
todc_info
->
control_a
,
(
save_control
|
todc_info
->
enable_read
));
(
save_control
|
todc_info
->
enable_read
));
}
}
}
}
...
@@ -253,19 +314,18 @@ todc_get_rtc_time(void)
...
@@ -253,19 +314,18 @@ todc_get_rtc_time(void)
for
(
i
=
0
;
i
<
limit
;
i
++
)
{
for
(
i
=
0
;
i
<
limit
;
i
++
)
{
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
uip
=
ppc_md
.
nvram
_read_val
(
todc_info
->
RTC_FREQ_SELECT
);
uip
=
todc
_read_val
(
todc_info
->
RTC_FREQ_SELECT
);
}
}
sec
=
ppc_md
.
nvram
_read_val
(
todc_info
->
seconds
)
&
0x7f
;
sec
=
todc
_read_val
(
todc_info
->
seconds
)
&
0x7f
;
min
=
ppc_md
.
nvram
_read_val
(
todc_info
->
minutes
)
&
0x7f
;
min
=
todc
_read_val
(
todc_info
->
minutes
)
&
0x7f
;
hour
=
ppc_md
.
nvram
_read_val
(
todc_info
->
hours
)
&
0x3f
;
hour
=
todc
_read_val
(
todc_info
->
hours
)
&
0x3f
;
day
=
ppc_md
.
nvram
_read_val
(
todc_info
->
day_of_month
)
&
0x3f
;
day
=
todc
_read_val
(
todc_info
->
day_of_month
)
&
0x3f
;
mon
=
ppc_md
.
nvram
_read_val
(
todc_info
->
month
)
&
0x1f
;
mon
=
todc
_read_val
(
todc_info
->
month
)
&
0x1f
;
year
=
ppc_md
.
nvram
_read_val
(
todc_info
->
year
)
&
0xff
;
year
=
todc
_read_val
(
todc_info
->
year
)
&
0xff
;
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
uip
|=
ppc_md
.
nvram_read_val
(
uip
|=
todc_read_val
(
todc_info
->
RTC_FREQ_SELECT
);
todc_info
->
RTC_FREQ_SELECT
);
if
((
uip
&
RTC_UIP
)
==
0
)
break
;
if
((
uip
&
RTC_UIP
)
==
0
)
break
;
}
}
}
}
...
@@ -276,13 +336,15 @@ todc_get_rtc_time(void)
...
@@ -276,13 +336,15 @@ todc_get_rtc_time(void)
case
TODC_TYPE_DS1743
:
case
TODC_TYPE_DS1743
:
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS17285
:
break
;
break
;
default:
default:
save_control
&=
~
(
todc_info
->
enable_read
);
save_control
&=
~
(
todc_info
->
enable_read
);
ppc_md
.
nvram
_write_val
(
todc_info
->
control_a
,
todc
_write_val
(
todc_info
->
control_a
,
save_control
);
save_control
);
}
}
}
}
spin_unlock
(
&
rtc_lock
);
if
((
todc_info
->
rtc_type
!=
TODC_TYPE_MC146818
)
||
if
((
todc_info
->
rtc_type
!=
TODC_TYPE_MC146818
)
||
((
save_control
&
RTC_DM_BINARY
)
==
0
)
||
((
save_control
&
RTC_DM_BINARY
)
==
0
)
||
...
@@ -310,19 +372,19 @@ todc_set_rtc_time(unsigned long nowtime)
...
@@ -310,19 +372,19 @@ todc_set_rtc_time(unsigned long nowtime)
struct
rtc_time
tm
;
struct
rtc_time
tm
;
u_char
save_control
,
save_freq_select
;
u_char
save_control
,
save_freq_select
;
spin_lock
(
&
rtc_lock
);
to_tm
(
nowtime
,
&
tm
);
to_tm
(
nowtime
,
&
tm
);
save_control
=
ppc_md
.
nvram
_read_val
(
todc_info
->
control_a
);
save_control
=
todc
_read_val
(
todc_info
->
control_a
);
/* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
/* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
ppc_md
.
nvram
_write_val
(
todc_info
->
control_a
,
todc
_write_val
(
todc_info
->
control_a
,
(
save_control
|
todc_info
->
enable_write
));
(
save_control
|
todc_info
->
enable_write
));
save_control
&=
~
(
todc_info
->
enable_write
);
/* in case it was set */
save_control
&=
~
(
todc_info
->
enable_write
);
/* in case it was set */
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
save_freq_select
=
save_freq_select
=
todc_read_val
(
todc_info
->
RTC_FREQ_SELECT
);
ppc_md
.
nvram_read_val
(
todc_info
->
RTC_FREQ_SELECT
);
todc_write_val
(
todc_info
->
RTC_FREQ_SELECT
,
ppc_md
.
nvram_write_val
(
todc_info
->
RTC_FREQ_SELECT
,
save_freq_select
|
RTC_DIV_RESET2
);
save_freq_select
|
RTC_DIV_RESET2
);
}
}
...
@@ -341,19 +403,19 @@ todc_set_rtc_time(unsigned long nowtime)
...
@@ -341,19 +403,19 @@ todc_set_rtc_time(unsigned long nowtime)
BIN_TO_BCD
(
tm
.
tm_year
);
BIN_TO_BCD
(
tm
.
tm_year
);
}
}
ppc_md
.
nvram
_write_val
(
todc_info
->
seconds
,
tm
.
tm_sec
);
todc
_write_val
(
todc_info
->
seconds
,
tm
.
tm_sec
);
ppc_md
.
nvram
_write_val
(
todc_info
->
minutes
,
tm
.
tm_min
);
todc
_write_val
(
todc_info
->
minutes
,
tm
.
tm_min
);
ppc_md
.
nvram
_write_val
(
todc_info
->
hours
,
tm
.
tm_hour
);
todc
_write_val
(
todc_info
->
hours
,
tm
.
tm_hour
);
ppc_md
.
nvram
_write_val
(
todc_info
->
month
,
tm
.
tm_mon
);
todc
_write_val
(
todc_info
->
month
,
tm
.
tm_mon
);
ppc_md
.
nvram
_write_val
(
todc_info
->
day_of_month
,
tm
.
tm_mday
);
todc
_write_val
(
todc_info
->
day_of_month
,
tm
.
tm_mday
);
ppc_md
.
nvram
_write_val
(
todc_info
->
year
,
tm
.
tm_year
);
todc
_write_val
(
todc_info
->
year
,
tm
.
tm_year
);
ppc_md
.
nvram
_write_val
(
todc_info
->
control_a
,
save_control
);
todc
_write_val
(
todc_info
->
control_a
,
save_control
);
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
if
(
todc_info
->
rtc_type
==
TODC_TYPE_MC146818
)
{
ppc_md
.
nvram_write_val
(
todc_info
->
RTC_FREQ_SELECT
,
todc_write_val
(
todc_info
->
RTC_FREQ_SELECT
,
save_freq_select
);
save_freq_select
);
}
}
spin_unlock
(
&
rtc_lock
);
return
0
;
return
0
;
}
}
...
@@ -367,30 +429,28 @@ static unsigned char __init todc_read_timereg(int addr)
...
@@ -367,30 +429,28 @@ static unsigned char __init todc_read_timereg(int addr)
switch
(
todc_info
->
rtc_type
)
{
switch
(
todc_info
->
rtc_type
)
{
case
TODC_TYPE_DS1557
:
case
TODC_TYPE_DS1557
:
case
TODC_TYPE_DS1743
:
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS17285
:
case
TODC_TYPE_MC146818
:
case
TODC_TYPE_MC146818
:
break
;
break
;
default:
default:
save_control
=
save_control
=
todc_read_val
(
todc_info
->
control_a
);
ppc_md
.
nvram_read_val
(
todc_info
->
control_a
);
todc_write_val
(
todc_info
->
control_a
,
ppc_md
.
nvram_write_val
(
todc_info
->
control_a
,
(
save_control
|
todc_info
->
enable_read
));
(
save_control
|
todc_info
->
enable_read
));
}
}
val
=
ppc_md
.
nvram
_read_val
(
addr
);
val
=
todc
_read_val
(
addr
);
switch
(
todc_info
->
rtc_type
)
{
switch
(
todc_info
->
rtc_type
)
{
case
TODC_TYPE_DS1557
:
case
TODC_TYPE_DS1557
:
case
TODC_TYPE_DS1743
:
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1746
:
/* XXXX BAD HACK -> FIX */
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS1747
:
case
TODC_TYPE_DS17285
:
case
TODC_TYPE_MC146818
:
case
TODC_TYPE_MC146818
:
break
;
break
;
default:
default:
save_control
&=
~
(
todc_info
->
enable_read
);
save_control
&=
~
(
todc_info
->
enable_read
);
ppc_md
.
nvram_write_val
(
todc_info
->
control_a
,
todc_write_val
(
todc_info
->
control_a
,
save_control
);
save_control
);
}
}
return
val
;
return
val
;
...
@@ -412,7 +472,7 @@ todc_calibrate_decr(void)
...
@@ -412,7 +472,7 @@ todc_calibrate_decr(void)
/*
/*
* Actually this is bad for precision, we should have a loop in
* Actually this is bad for precision, we should have a loop in
* which we only read the seconds counter.
nvram
_read_val writes
* which we only read the seconds counter.
todc
_read_val writes
* the address bytes on every call and this takes a lot of time.
* the address bytes on every call and this takes a lot of time.
* Perhaps an nvram_wait_change method returning a time
* Perhaps an nvram_wait_change method returning a time
* stamp with a loop count as parameter would be the solution.
* stamp with a loop count as parameter would be the solution.
...
...
include/asm-ppc/todc.h
View file @
2130835d
...
@@ -46,6 +46,9 @@ typedef struct {
...
@@ -46,6 +46,9 @@ typedef struct {
*/
*/
int
as0_bits
;
int
as0_bits
;
int
nvram_size
;
/* Size of NVRAM on chip */
int
sw_flags
;
/* Software control flags */
/* Following are the register offsets for the particular chip */
/* Following are the register offsets for the particular chip */
int
year
;
int
year
;
int
month
;
int
month
;
...
@@ -64,6 +67,14 @@ typedef struct {
...
@@ -64,6 +67,14 @@ typedef struct {
int
alarm_seconds
;
int
alarm_seconds
;
int
century
;
int
century
;
int
flags
;
int
flags
;
/*
* Some RTC chips have their NVRAM buried behind a addr/data pair of
* regs on the first level/clock registers. The following fields
* are the addresses for those addr/data regs.
*/
int
nvram_addr_reg
;
int
nvram_data_reg
;
}
todc_info_t
;
}
todc_info_t
;
/*
/*
...
@@ -86,7 +97,8 @@ typedef struct {
...
@@ -86,7 +97,8 @@ typedef struct {
#define TODC_TYPE_DS1643 9
/* Dallas DS1643 RTC */
#define TODC_TYPE_DS1643 9
/* Dallas DS1643 RTC */
#define TODC_TYPE_PC97307 10
/* PC97307 internal RTC */
#define TODC_TYPE_PC97307 10
/* PC97307 internal RTC */
#define TODC_TYPE_DS1557 11
/* Dallas DS1557 RTC */
#define TODC_TYPE_DS1557 11
/* Dallas DS1557 RTC */
#define TODC_TYPE_MC146818 100
/* Leave room for more m48txx's */
#define TODC_TYPE_DS17285 12
/* Dallas DS17285 RTC */
#define TODC_TYPE_MC146818 100
/* Leave room for m48txx's */
/*
/*
* Bit to clear/set to enable reads/writes to the chip
* Bit to clear/set to enable reads/writes to the chip
...
@@ -97,10 +109,19 @@ typedef struct {
...
@@ -97,10 +109,19 @@ typedef struct {
#define TODC_DS1501_CNTL_B_TE 0x80
#define TODC_DS1501_CNTL_B_TE 0x80
/*
* Define flag bits used by todc routines.
*/
#define TODC_FLAG_2_LEVEL_NVRAM 0x00000001
/*
/*
* Define the values for the various RTC's that should to into the todc_info
* Define the values for the various RTC's that should to into the todc_info
* table.
* table.
* Note: The XXX_NVRAM_SIZE, XXX_NVRAM_ADDR_REG, and XXX_NVRAM_DATA_REG only
* matter if XXX_SW_FLAGS has TODC_FLAG_2_LEVEL_NVRAM set.
*/
*/
#define TODC_TYPE_MK48T35_NVRAM_SIZE 0x7ff8
#define TODC_TYPE_MK48T35_SW_FLAGS 0
#define TODC_TYPE_MK48T35_YEAR 0x7fff
#define TODC_TYPE_MK48T35_YEAR 0x7fff
#define TODC_TYPE_MK48T35_MONTH 0x7ffe
#define TODC_TYPE_MK48T35_MONTH 0x7ffe
#define TODC_TYPE_MK48T35_DOM 0x7ffd
/* Day of Month */
#define TODC_TYPE_MK48T35_DOM 0x7ffd
/* Day of Month */
...
@@ -118,7 +139,11 @@ typedef struct {
...
@@ -118,7 +139,11 @@ typedef struct {
#define TODC_TYPE_MK48T35_ALARM_SECONDS 0x0000
#define TODC_TYPE_MK48T35_ALARM_SECONDS 0x0000
#define TODC_TYPE_MK48T35_CENTURY 0x0000
#define TODC_TYPE_MK48T35_CENTURY 0x0000
#define TODC_TYPE_MK48T35_FLAGS 0x0000
#define TODC_TYPE_MK48T35_FLAGS 0x0000
#define TODC_TYPE_MK48T35_NVRAM_ADDR_REG 0
#define TODC_TYPE_MK48T35_NVRAM_DATA_REG 0
#define TODC_TYPE_MK48T37_NVRAM_SIZE 0x7ff0
#define TODC_TYPE_MK48T37_SW_FLAGS 0
#define TODC_TYPE_MK48T37_YEAR 0x7fff
#define TODC_TYPE_MK48T37_YEAR 0x7fff
#define TODC_TYPE_MK48T37_MONTH 0x7ffe
#define TODC_TYPE_MK48T37_MONTH 0x7ffe
#define TODC_TYPE_MK48T37_DOM 0x7ffd
/* Day of Month */
#define TODC_TYPE_MK48T37_DOM 0x7ffd
/* Day of Month */
...
@@ -136,7 +161,11 @@ typedef struct {
...
@@ -136,7 +161,11 @@ typedef struct {
#define TODC_TYPE_MK48T37_ALARM_SECONDS 0x7ff2
#define TODC_TYPE_MK48T37_ALARM_SECONDS 0x7ff2
#define TODC_TYPE_MK48T37_CENTURY 0x7ff1
#define TODC_TYPE_MK48T37_CENTURY 0x7ff1
#define TODC_TYPE_MK48T37_FLAGS 0x7ff0
#define TODC_TYPE_MK48T37_FLAGS 0x7ff0
#define TODC_TYPE_MK48T37_NVRAM_ADDR_REG 0
#define TODC_TYPE_MK48T37_NVRAM_DATA_REG 0
#define TODC_TYPE_MK48T59_NVRAM_SIZE 0x1ff0
#define TODC_TYPE_MK48T59_SW_FLAGS 0
#define TODC_TYPE_MK48T59_YEAR 0x1fff
#define TODC_TYPE_MK48T59_YEAR 0x1fff
#define TODC_TYPE_MK48T59_MONTH 0x1ffe
#define TODC_TYPE_MK48T59_MONTH 0x1ffe
#define TODC_TYPE_MK48T59_DOM 0x1ffd
/* Day of Month */
#define TODC_TYPE_MK48T59_DOM 0x1ffd
/* Day of Month */
...
@@ -154,25 +183,33 @@ typedef struct {
...
@@ -154,25 +183,33 @@ typedef struct {
#define TODC_TYPE_MK48T59_ALARM_SECONDS 0x1fff
#define TODC_TYPE_MK48T59_ALARM_SECONDS 0x1fff
#define TODC_TYPE_MK48T59_CENTURY 0x1fff
#define TODC_TYPE_MK48T59_CENTURY 0x1fff
#define TODC_TYPE_MK48T59_FLAGS 0x1fff
#define TODC_TYPE_MK48T59_FLAGS 0x1fff
#define TODC_TYPE_MK48T59_NVRAM_ADDR_REG 0
#define TODC_TYPE_MK48T59_NVRAM_DATA_REG 0
#define TODC_TYPE_DS1501_YEAR 0x06
#define TODC_TYPE_DS1501_NVRAM_SIZE 0x100
#define TODC_TYPE_DS1501_MONTH 0x05
#define TODC_TYPE_DS1501_SW_FLAGS TODC_FLAG_2_LEVEL_NVRAM
#define TODC_TYPE_DS1501_DOM 0x04
/* Day of Month */
#define TODC_TYPE_DS1501_YEAR (TODC_TYPE_DS1501_NVRAM_SIZE + 0x06)
#define TODC_TYPE_DS1501_DOW 0x03
/* Day of Week */
#define TODC_TYPE_DS1501_MONTH (TODC_TYPE_DS1501_NVRAM_SIZE + 0x05)
#define TODC_TYPE_DS1501_HOURS 0x02
#define TODC_TYPE_DS1501_DOM (TODC_TYPE_DS1501_NVRAM_SIZE + 0x04)
#define TODC_TYPE_DS1501_MINUTES 0x01
#define TODC_TYPE_DS1501_DOW (TODC_TYPE_DS1501_NVRAM_SIZE + 0x03)
#define TODC_TYPE_DS1501_SECONDS 0x00
#define TODC_TYPE_DS1501_HOURS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x02)
#define TODC_TYPE_DS1501_CNTL_B 0x0f
#define TODC_TYPE_DS1501_MINUTES (TODC_TYPE_DS1501_NVRAM_SIZE + 0x01)
#define TODC_TYPE_DS1501_CNTL_A 0x0f
#define TODC_TYPE_DS1501_SECONDS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x00)
#define TODC_TYPE_DS1501_WATCHDOG 0xff
#define TODC_TYPE_DS1501_CNTL_B (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f)
#define TODC_TYPE_DS1501_INTERRUPTS 0xff
#define TODC_TYPE_DS1501_CNTL_A (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f)
#define TODC_TYPE_DS1501_ALARM_DATE 0x0b
#define TODC_TYPE_DS1501_WATCHDOG (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
#define TODC_TYPE_DS1501_ALARM_HOUR 0x0a
#define TODC_TYPE_DS1501_INTERRUPTS (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
#define TODC_TYPE_DS1501_ALARM_MINUTES 0x09
#define TODC_TYPE_DS1501_ALARM_DATE (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0b)
#define TODC_TYPE_DS1501_ALARM_SECONDS 0x08
#define TODC_TYPE_DS1501_ALARM_HOUR (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0a)
#define TODC_TYPE_DS1501_CENTURY 0x07
#define TODC_TYPE_DS1501_ALARM_MINUTES (TODC_TYPE_DS1501_NVRAM_SIZE + 0x09)
#define TODC_TYPE_DS1501_FLAGS 0xff
#define TODC_TYPE_DS1501_ALARM_SECONDS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x08)
#define TODC_TYPE_DS1501_CENTURY (TODC_TYPE_DS1501_NVRAM_SIZE + 0x07)
#define TODC_TYPE_DS1501_FLAGS (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
#define TODC_TYPE_DS1501_NVRAM_ADDR_REG 0x10
#define TODC_TYPE_DS1501_NVRAM_DATA_REG 0x13
#define TODC_TYPE_DS1557_NVRAM_SIZE 0x7fff0
#define TODC_TYPE_DS1557_SW_FLAGS 0
#define TODC_TYPE_DS1557_YEAR 0x7ffff
#define TODC_TYPE_DS1557_YEAR 0x7ffff
#define TODC_TYPE_DS1557_MONTH 0x7fffe
#define TODC_TYPE_DS1557_MONTH 0x7fffe
#define TODC_TYPE_DS1557_DOM 0x7fffd
/* Day of Month */
#define TODC_TYPE_DS1557_DOM 0x7fffd
/* Day of Month */
...
@@ -190,7 +227,11 @@ typedef struct {
...
@@ -190,7 +227,11 @@ typedef struct {
#define TODC_TYPE_DS1557_ALARM_SECONDS 0x7fff2
#define TODC_TYPE_DS1557_ALARM_SECONDS 0x7fff2
#define TODC_TYPE_DS1557_CENTURY 0x7fff8
#define TODC_TYPE_DS1557_CENTURY 0x7fff8
#define TODC_TYPE_DS1557_FLAGS 0x7fff0
#define TODC_TYPE_DS1557_FLAGS 0x7fff0
#define TODC_TYPE_DS1557_NVRAM_ADDR_REG 0
#define TODC_TYPE_DS1557_NVRAM_DATA_REG 0
#define TODC_TYPE_DS1643_NVRAM_SIZE 0x1ff8
#define TODC_TYPE_DS1643_SW_FLAGS 0
#define TODC_TYPE_DS1643_YEAR 0x1fff
#define TODC_TYPE_DS1643_YEAR 0x1fff
#define TODC_TYPE_DS1643_MONTH 0x1ffe
#define TODC_TYPE_DS1643_MONTH 0x1ffe
#define TODC_TYPE_DS1643_DOM 0x1ffd
/* Day of Month */
#define TODC_TYPE_DS1643_DOM 0x1ffd
/* Day of Month */
...
@@ -208,7 +249,11 @@ typedef struct {
...
@@ -208,7 +249,11 @@ typedef struct {
#define TODC_TYPE_DS1643_ALARM_SECONDS 0x1fff
#define TODC_TYPE_DS1643_ALARM_SECONDS 0x1fff
#define TODC_TYPE_DS1643_CENTURY 0x1ff8
#define TODC_TYPE_DS1643_CENTURY 0x1ff8
#define TODC_TYPE_DS1643_FLAGS 0x1fff
#define TODC_TYPE_DS1643_FLAGS 0x1fff
#define TODC_TYPE_DS1643_NVRAM_ADDR_REG 0
#define TODC_TYPE_DS1643_NVRAM_DATA_REG 0
#define TODC_TYPE_DS1693_NVRAM_SIZE 0
/* Not handled yet */
#define TODC_TYPE_DS1693_SW_FLAGS 0
#define TODC_TYPE_DS1693_YEAR 0x09
#define TODC_TYPE_DS1693_YEAR 0x09
#define TODC_TYPE_DS1693_MONTH 0x08
#define TODC_TYPE_DS1693_MONTH 0x08
#define TODC_TYPE_DS1693_DOM 0x07
/* Day of Month */
#define TODC_TYPE_DS1693_DOM 0x07
/* Day of Month */
...
@@ -226,7 +271,11 @@ typedef struct {
...
@@ -226,7 +271,11 @@ typedef struct {
#define TODC_TYPE_DS1693_ALARM_SECONDS 0x01
#define TODC_TYPE_DS1693_ALARM_SECONDS 0x01
#define TODC_TYPE_DS1693_CENTURY 0x48
#define TODC_TYPE_DS1693_CENTURY 0x48
#define TODC_TYPE_DS1693_FLAGS 0xff
#define TODC_TYPE_DS1693_FLAGS 0xff
#define TODC_TYPE_DS1693_NVRAM_ADDR_REG 0
#define TODC_TYPE_DS1693_NVRAM_DATA_REG 0
#define TODC_TYPE_DS1743_NVRAM_SIZE 0x1ff8
#define TODC_TYPE_DS1743_SW_FLAGS 0
#define TODC_TYPE_DS1743_YEAR 0x1fff
#define TODC_TYPE_DS1743_YEAR 0x1fff
#define TODC_TYPE_DS1743_MONTH 0x1ffe
#define TODC_TYPE_DS1743_MONTH 0x1ffe
#define TODC_TYPE_DS1743_DOM 0x1ffd
/* Day of Month */
#define TODC_TYPE_DS1743_DOM 0x1ffd
/* Day of Month */
...
@@ -244,7 +293,11 @@ typedef struct {
...
@@ -244,7 +293,11 @@ typedef struct {
#define TODC_TYPE_DS1743_ALARM_SECONDS 0x1fff
#define TODC_TYPE_DS1743_ALARM_SECONDS 0x1fff
#define TODC_TYPE_DS1743_CENTURY 0x1ff8
#define TODC_TYPE_DS1743_CENTURY 0x1ff8
#define TODC_TYPE_DS1743_FLAGS 0x1fff
#define TODC_TYPE_DS1743_FLAGS 0x1fff
#define TODC_TYPE_DS1743_NVRAM_ADDR_REG 0
#define TODC_TYPE_DS1743_NVRAM_DATA_REG 0
#define TODC_TYPE_DS1746_NVRAM_SIZE 0x1fff8
#define TODC_TYPE_DS1746_SW_FLAGS 0
#define TODC_TYPE_DS1746_YEAR 0x1ffff
#define TODC_TYPE_DS1746_YEAR 0x1ffff
#define TODC_TYPE_DS1746_MONTH 0x1fffe
#define TODC_TYPE_DS1746_MONTH 0x1fffe
#define TODC_TYPE_DS1746_DOM 0x1fffd
/* Day of Month */
#define TODC_TYPE_DS1746_DOM 0x1fffd
/* Day of Month */
...
@@ -262,16 +315,20 @@ typedef struct {
...
@@ -262,16 +315,20 @@ typedef struct {
#define TODC_TYPE_DS1746_ALARM_SECONDS 0x00000
#define TODC_TYPE_DS1746_ALARM_SECONDS 0x00000
#define TODC_TYPE_DS1746_CENTURY 0x00000
#define TODC_TYPE_DS1746_CENTURY 0x00000
#define TODC_TYPE_DS1746_FLAGS 0x00000
#define TODC_TYPE_DS1746_FLAGS 0x00000
#define TODC_TYPE_DS1746_NVRAM_ADDR_REG 0
#define TODC_TYPE_DS1746_NVRAM_DATA_REG 0
#define TODC_TYPE_DS1747_YEAR 0x1ffff
#define TODC_TYPE_DS1747_NVRAM_SIZE 0x7fff8
#define TODC_TYPE_DS1747_MONTH 0x1fffe
#define TODC_TYPE_DS1747_SW_FLAGS 0
#define TODC_TYPE_DS1747_DOM 0x1fffd
/* Day of Month */
#define TODC_TYPE_DS1747_YEAR 0x7ffff
#define TODC_TYPE_DS1747_DOW 0x1fffc
/* Day of Week */
#define TODC_TYPE_DS1747_MONTH 0x7fffe
#define TODC_TYPE_DS1747_HOURS 0x1fffb
#define TODC_TYPE_DS1747_DOM 0x7fffd
/* Day of Month */
#define TODC_TYPE_DS1747_MINUTES 0x1fffa
#define TODC_TYPE_DS1747_DOW 0x7fffc
/* Day of Week */
#define TODC_TYPE_DS1747_SECONDS 0x1fff9
#define TODC_TYPE_DS1747_HOURS 0x7fffb
#define TODC_TYPE_DS1747_CNTL_B 0x1fff9
#define TODC_TYPE_DS1747_MINUTES 0x7fffa
#define TODC_TYPE_DS1747_CNTL_A 0x1fff8
/* control_a R/W regs */
#define TODC_TYPE_DS1747_SECONDS 0x7fff9
#define TODC_TYPE_DS1747_CNTL_B 0x7fff9
#define TODC_TYPE_DS1747_CNTL_A 0x7fff8
/* control_a R/W regs */
#define TODC_TYPE_DS1747_WATCHDOG 0x00000
#define TODC_TYPE_DS1747_WATCHDOG 0x00000
#define TODC_TYPE_DS1747_INTERRUPTS 0x00000
#define TODC_TYPE_DS1747_INTERRUPTS 0x00000
#define TODC_TYPE_DS1747_ALARM_DATE 0x00000
#define TODC_TYPE_DS1747_ALARM_DATE 0x00000
...
@@ -280,7 +337,35 @@ typedef struct {
...
@@ -280,7 +337,35 @@ typedef struct {
#define TODC_TYPE_DS1747_ALARM_SECONDS 0x00000
#define TODC_TYPE_DS1747_ALARM_SECONDS 0x00000
#define TODC_TYPE_DS1747_CENTURY 0x00000
#define TODC_TYPE_DS1747_CENTURY 0x00000
#define TODC_TYPE_DS1747_FLAGS 0x00000
#define TODC_TYPE_DS1747_FLAGS 0x00000
#define TODC_TYPE_DS1747_NVRAM_ADDR_REG 0
#define TODC_TYPE_DS1747_NVRAM_DATA_REG 0
#define TODC_TYPE_DS17285_NVRAM_SIZE (0x1000-0x80)
/* 4Kx8 NVRAM (minus RTC regs) */
#define TODC_TYPE_DS17285_SW_FLAGS TODC_FLAG_2_LEVEL_NVRAM
#define TODC_TYPE_DS17285_SECONDS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x00)
#define TODC_TYPE_DS17285_ALARM_SECONDS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x01)
#define TODC_TYPE_DS17285_MINUTES (TODC_TYPE_DS17285_NVRAM_SIZE + 0x02)
#define TODC_TYPE_DS17285_ALARM_MINUTES (TODC_TYPE_DS17285_NVRAM_SIZE + 0x03)
#define TODC_TYPE_DS17285_HOURS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x04)
#define TODC_TYPE_DS17285_ALARM_HOUR (TODC_TYPE_DS17285_NVRAM_SIZE + 0x05)
#define TODC_TYPE_DS17285_DOW (TODC_TYPE_DS17285_NVRAM_SIZE + 0x06)
#define TODC_TYPE_DS17285_DOM (TODC_TYPE_DS17285_NVRAM_SIZE + 0x07)
#define TODC_TYPE_DS17285_MONTH (TODC_TYPE_DS17285_NVRAM_SIZE + 0x08)
#define TODC_TYPE_DS17285_YEAR (TODC_TYPE_DS17285_NVRAM_SIZE + 0x09)
#define TODC_TYPE_DS17285_CNTL_A (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0A)
#define TODC_TYPE_DS17285_CNTL_B (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0B)
#define TODC_TYPE_DS17285_CNTL_C (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0C)
#define TODC_TYPE_DS17285_CNTL_D (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0D)
#define TODC_TYPE_DS17285_WATCHDOG 0
#define TODC_TYPE_DS17285_INTERRUPTS 0
#define TODC_TYPE_DS17285_ALARM_DATE 0
#define TODC_TYPE_DS17285_CENTURY 0
#define TODC_TYPE_DS17285_FLAGS 0
#define TODC_TYPE_DS17285_NVRAM_ADDR_REG 0x50
#define TODC_TYPE_DS17285_NVRAM_DATA_REG 0x53
#define TODC_TYPE_MC146818_NVRAM_SIZE 0
/* XXXX */
#define TODC_TYPE_MC146818_SW_FLAGS 0
#define TODC_TYPE_MC146818_YEAR 0x09
#define TODC_TYPE_MC146818_YEAR 0x09
#define TODC_TYPE_MC146818_MONTH 0x08
#define TODC_TYPE_MC146818_MONTH 0x08
#define TODC_TYPE_MC146818_DOM 0x07
/* Day of Month */
#define TODC_TYPE_MC146818_DOM 0x07
/* Day of Month */
...
@@ -298,7 +383,11 @@ typedef struct {
...
@@ -298,7 +383,11 @@ typedef struct {
#define TODC_TYPE_MC146818_ALARM_SECONDS 0x01
#define TODC_TYPE_MC146818_ALARM_SECONDS 0x01
#define TODC_TYPE_MC146818_CENTURY 0xff
#define TODC_TYPE_MC146818_CENTURY 0xff
#define TODC_TYPE_MC146818_FLAGS 0xff
#define TODC_TYPE_MC146818_FLAGS 0xff
#define TODC_TYPE_MC146818_NVRAM_ADDR_REG 0
#define TODC_TYPE_MC146818_NVRAM_DATA_REG 0
#define TODC_TYPE_PC97307_NVRAM_SIZE 0
/* No NVRAM? */
#define TODC_TYPE_PC97307_SW_FLAGS 0
#define TODC_TYPE_PC97307_YEAR 0x09
#define TODC_TYPE_PC97307_YEAR 0x09
#define TODC_TYPE_PC97307_MONTH 0x08
#define TODC_TYPE_PC97307_MONTH 0x08
#define TODC_TYPE_PC97307_DOM 0x07
/* Day of Month */
#define TODC_TYPE_PC97307_DOM 0x07
/* Day of Month */
...
@@ -316,6 +405,8 @@ typedef struct {
...
@@ -316,6 +405,8 @@ typedef struct {
#define TODC_TYPE_PC97307_ALARM_SECONDS 0x01
#define TODC_TYPE_PC97307_ALARM_SECONDS 0x01
#define TODC_TYPE_PC97307_CENTURY 0xff
#define TODC_TYPE_PC97307_CENTURY 0xff
#define TODC_TYPE_PC97307_FLAGS 0xff
#define TODC_TYPE_PC97307_FLAGS 0xff
#define TODC_TYPE_PC97307_NVRAM_ADDR_REG 0
#define TODC_TYPE_PC97307_NVRAM_DATA_REG 0
/*
/*
* Define macros to allocate and init the todc_info_t table that will
* Define macros to allocate and init the todc_info_t table that will
...
@@ -334,23 +425,29 @@ typedef struct {
...
@@ -334,23 +425,29 @@ typedef struct {
\
\
todc_info->as0_bits = (bits); \
todc_info->as0_bits = (bits); \
\
\
todc_info->year = clock_type ##_YEAR; \
todc_info->nvram_size = clock_type ##_NVRAM_SIZE; \
todc_info->month = clock_type ##_MONTH; \
todc_info->sw_flags = clock_type ##_SW_FLAGS; \
todc_info->day_of_month = clock_type ##_DOM; \
\
todc_info->day_of_week = clock_type ##_DOW; \
todc_info->year = clock_type ##_YEAR; \
todc_info->hours = clock_type ##_HOURS; \
todc_info->month = clock_type ##_MONTH; \
todc_info->minutes = clock_type ##_MINUTES; \
todc_info->day_of_month = clock_type ##_DOM; \
todc_info->seconds = clock_type ##_SECONDS; \
todc_info->day_of_week = clock_type ##_DOW; \
todc_info->control_b = clock_type ##_CNTL_B; \
todc_info->hours = clock_type ##_HOURS; \
todc_info->control_a = clock_type ##_CNTL_A; \
todc_info->minutes = clock_type ##_MINUTES; \
todc_info->watchdog = clock_type ##_WATCHDOG; \
todc_info->seconds = clock_type ##_SECONDS; \
todc_info->interrupts = clock_type ##_INTERRUPTS; \
todc_info->control_b = clock_type ##_CNTL_B; \
todc_info->alarm_date = clock_type ##_ALARM_DATE; \
todc_info->control_a = clock_type ##_CNTL_A; \
todc_info->alarm_hour = clock_type ##_ALARM_HOUR; \
todc_info->watchdog = clock_type ##_WATCHDOG; \
todc_info->alarm_minutes = clock_type ##_ALARM_MINUTES; \
todc_info->interrupts = clock_type ##_INTERRUPTS; \
todc_info->alarm_seconds = clock_type ##_ALARM_SECONDS; \
todc_info->alarm_date = clock_type ##_ALARM_DATE; \
todc_info->century = clock_type ##_CENTURY; \
todc_info->alarm_hour = clock_type ##_ALARM_HOUR; \
todc_info->flags = clock_type ##_FLAGS; \
todc_info->alarm_minutes = clock_type ##_ALARM_MINUTES; \
todc_info->alarm_seconds = clock_type ##_ALARM_SECONDS; \
todc_info->century = clock_type ##_CENTURY; \
todc_info->flags = clock_type ##_FLAGS; \
\
todc_info->nvram_addr_reg = clock_type ##_NVRAM_ADDR_REG; \
todc_info->nvram_data_reg = clock_type ##_NVRAM_DATA_REG; \
}
}
extern
todc_info_t
*
todc_info
;
extern
todc_info_t
*
todc_info
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment