1 /* $NetBSD: mk48txx.c,v 1.24 2008/01/10 15:31:27 tsutsui Exp $ */
3 * Copyright (c) 2000 The NetBSD Foundation, Inc.
6 * This code is derived from software contributed to The NetBSD Foundation
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
32 * Mostek MK48T02, MK48T08, MK48T59 time-of-day chip subroutines.
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: mk48txx.c,v 1.24 2008/01/10 15:31:27 tsutsui Exp $");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
41 #include <sys/errno.h>
44 #include <dev/clock_subr.h>
45 #include <dev/ic/mk48txxreg.h>
46 #include <dev/ic/mk48txxvar.h>
48 int mk48txx_gettime_ymdhms(todr_chip_handle_t
, struct clock_ymdhms
*);
49 int mk48txx_settime_ymdhms(todr_chip_handle_t
, struct clock_ymdhms
*);
50 uint8_t mk48txx_def_nvrd(struct mk48txx_softc
*, int);
51 void mk48txx_def_nvwr(struct mk48txx_softc
*, int, uint8_t);
58 #define MK48TXX_EXT_REGISTERS 1 /* Has extended register set */
59 } mk48txx_models
[] = {
60 { "mk48t02", MK48T02_CLKSZ
, MK48T02_CLKOFF
, 0 },
61 { "mk48t08", MK48T08_CLKSZ
, MK48T08_CLKOFF
, 0 },
62 { "mk48t18", MK48T18_CLKSZ
, MK48T18_CLKOFF
, 0 },
63 { "mk48t59", MK48T59_CLKSZ
, MK48T59_CLKOFF
, MK48TXX_EXT_REGISTERS
},
67 mk48txx_attach(struct mk48txx_softc
*sc
)
69 todr_chip_handle_t handle
;
72 aprint_normal(": %s", sc
->sc_model
);
74 i
= __arraycount(mk48txx_models
);
76 if (strcmp(sc
->sc_model
, mk48txx_models
[i
].name
) == 0)
80 panic("%s: unsupported model", __func__
);
82 sc
->sc_nvramsz
= mk48txx_models
[i
].nvramsz
;
83 sc
->sc_clkoffset
= mk48txx_models
[i
].clkoff
;
85 handle
= &sc
->sc_handle
;
87 handle
->todr_gettime
= NULL
;
88 handle
->todr_settime
= NULL
;
89 handle
->todr_gettime_ymdhms
= mk48txx_gettime_ymdhms
;
90 handle
->todr_settime_ymdhms
= mk48txx_settime_ymdhms
;
92 if (sc
->sc_nvrd
== NULL
)
93 sc
->sc_nvrd
= mk48txx_def_nvrd
;
94 if (sc
->sc_nvwr
== NULL
)
95 sc
->sc_nvwr
= mk48txx_def_nvwr
;
101 * Get time-of-day and convert to a `struct timeval'
102 * Return 0 on success; an error number otherwise.
105 mk48txx_gettime_ymdhms(todr_chip_handle_t handle
, struct clock_ymdhms
*dt
)
107 struct mk48txx_softc
*sc
;
113 clkoff
= sc
->sc_clkoffset
;
115 todr_wenable(handle
, 1);
117 /* enable read (stop time) */
118 csr
= (*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_ICSR
);
119 csr
|= MK48TXX_CSR_READ
;
120 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_ICSR
, csr
);
122 dt
->dt_sec
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_ISEC
));
123 dt
->dt_min
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_IMIN
));
124 dt
->dt_hour
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_IHOUR
));
125 dt
->dt_day
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_IDAY
));
126 dt
->dt_wday
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_IWDAY
));
127 dt
->dt_mon
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_IMON
));
128 year
= FROMBCD((*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_IYEAR
));
130 year
+= sc
->sc_year0
;
131 if (year
< POSIX_BASE_YEAR
&&
132 (sc
->sc_flag
& MK48TXX_NO_CENT_ADJUST
) == 0)
138 csr
= (*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_ICSR
);
139 csr
&= ~MK48TXX_CSR_READ
;
140 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_ICSR
, csr
);
141 todr_wenable(handle
, 0);
147 * Set the time-of-day clock based on the value of the `struct timeval' arg.
148 * Return 0 on success; an error number otherwise.
151 mk48txx_settime_ymdhms(todr_chip_handle_t handle
, struct clock_ymdhms
*dt
)
153 struct mk48txx_softc
*sc
;
159 clkoff
= sc
->sc_clkoffset
;
161 year
= dt
->dt_year
- sc
->sc_year0
;
163 (sc
->sc_flag
& MK48TXX_NO_CENT_ADJUST
) == 0)
166 todr_wenable(handle
, 1);
168 csr
= (*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_ICSR
);
169 csr
|= MK48TXX_CSR_WRITE
;
170 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_ICSR
, csr
);
172 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_ISEC
, TOBCD(dt
->dt_sec
));
173 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_IMIN
, TOBCD(dt
->dt_min
));
174 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_IHOUR
, TOBCD(dt
->dt_hour
));
175 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_IWDAY
, TOBCD(dt
->dt_wday
));
176 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_IDAY
, TOBCD(dt
->dt_day
));
177 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_IMON
, TOBCD(dt
->dt_mon
));
178 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_IYEAR
, TOBCD(year
));
181 csr
= (*sc
->sc_nvrd
)(sc
, clkoff
+ MK48TXX_ICSR
);
182 csr
&= ~MK48TXX_CSR_WRITE
;
183 (*sc
->sc_nvwr
)(sc
, clkoff
+ MK48TXX_ICSR
, csr
);
184 todr_wenable(handle
, 0);
189 mk48txx_get_nvram_size(todr_chip_handle_t handle
, bus_size_t
*vp
)
191 struct mk48txx_softc
*sc
;
194 *vp
= sc
->sc_nvramsz
;
199 mk48txx_def_nvrd(struct mk48txx_softc
*sc
, int off
)
202 return bus_space_read_1(sc
->sc_bst
, sc
->sc_bsh
, off
);
206 mk48txx_def_nvwr(struct mk48txx_softc
*sc
, int off
, uint8_t v
)
209 bus_space_write_1(sc
->sc_bst
, sc
->sc_bsh
, off
, v
);