Annotation of sys/dev/ic/mk48txx.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mk48txx.c,v 1.4 2002/06/09 00:07:10 nordin Exp $ */
2: /* $NetBSD: mk48txx.c,v 1.7 2001/04/08 17:05:10 tsutsui Exp $ */
3: /*-
4: * Copyright (c) 2000 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Paul Kranenburg.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: /*
40: * Mostek MK48T02, MK48T08, MK48T59 time-of-day chip subroutines.
41: */
42:
43: #include <sys/param.h>
44: #include <sys/malloc.h>
45: #include <sys/systm.h>
46: #include <sys/errno.h>
47:
48: #include <machine/bus.h>
49: #include <dev/clock_subr.h>
50: #include <dev/ic/mk48txxreg.h>
51:
52:
53: struct mk48txx {
54: bus_space_tag_t mk_bt; /* bus tag & handle */
55: bus_space_handle_t mk_bh; /* */
56: bus_size_t mk_nvramsz; /* Size of NVRAM on the chip */
57: bus_size_t mk_clkoffset; /* Offset in NVRAM to clock bits */
58: u_int mk_year0; /* What year is represented on the system
59: by the chip's year counter at 0 */
60: };
61:
62: int mk48txx_gettime(todr_chip_handle_t, struct timeval *);
63: int mk48txx_settime(todr_chip_handle_t, struct timeval *);
64: int mk48txx_getcal(todr_chip_handle_t, int *);
65: int mk48txx_setcal(todr_chip_handle_t, int);
66:
67: int mk48txx_auto_century_adjust = 1;
68:
69: struct {
70: const char *name;
71: bus_size_t nvramsz;
72: bus_size_t clkoff;
73: int flags;
74: #define MK48TXX_EXT_REGISTERS 1 /* Has extended register set */
75: } mk48txx_models[] = {
76: { "mk48t02", MK48T02_CLKSZ, MK48T02_CLKOFF, 0 },
77: { "mk48t08", MK48T08_CLKSZ, MK48T08_CLKOFF, 0 },
78: { "mk48t18", MK48T18_CLKSZ, MK48T18_CLKOFF, 0 },
79: { "mk48t59", MK48T59_CLKSZ, MK48T59_CLKOFF, MK48TXX_EXT_REGISTERS },
80: };
81:
82: todr_chip_handle_t
83: mk48txx_attach(bt, bh, model, year0)
84: bus_space_tag_t bt;
85: bus_space_handle_t bh;
86: const char *model;
87: int year0;
88: {
89: todr_chip_handle_t handle;
90: struct mk48txx *mk;
91: bus_size_t nvramsz, clkoff;
92: int sz;
93: int i;
94:
95: printf(": %s", model);
96:
97: i = sizeof(mk48txx_models)/sizeof(mk48txx_models[0]);
98: while (--i >= 0) {
99: if (strcmp(model, mk48txx_models[i].name) == 0) {
100: nvramsz = mk48txx_models[i].nvramsz;
101: clkoff = mk48txx_models[i].clkoff;
102: break;
103: }
104: }
105: if (i < 0) {
106: printf(": unsupported model");
107: return (NULL);
108: }
109:
110: sz = ALIGN(sizeof(struct todr_chip_handle)) + sizeof(struct mk48txx);
111: handle = malloc(sz, M_DEVBUF, M_NOWAIT);
112: if (handle == NULL) {
113: printf(": failed to allocate memory");
114: return NULL;
115: }
116: mk = (struct mk48txx *)((u_long)handle +
117: ALIGN(sizeof(struct todr_chip_handle)));
118: handle->cookie = mk;
119: handle->todr_gettime = mk48txx_gettime;
120: handle->todr_settime = mk48txx_settime;
121: handle->todr_getcal = mk48txx_getcal;
122: handle->todr_setcal = mk48txx_setcal;
123: handle->todr_setwen = NULL;
124: mk->mk_bt = bt;
125: mk->mk_bh = bh;
126: mk->mk_nvramsz = nvramsz;
127: mk->mk_clkoffset = clkoff;
128: mk->mk_year0 = year0;
129:
130: return (handle);
131: }
132:
133: /*
134: * Get time-of-day and convert to a `struct timeval'
135: * Return 0 on success; an error number otherwise.
136: */
137: int
138: mk48txx_gettime(handle, tv)
139: todr_chip_handle_t handle;
140: struct timeval *tv;
141: {
142: struct mk48txx *mk = handle->cookie;
143: bus_space_tag_t bt = mk->mk_bt;
144: bus_space_handle_t bh = mk->mk_bh;
145: bus_size_t clkoff = mk->mk_clkoffset;
146: struct clock_ymdhms dt;
147: int year;
148: u_int8_t csr;
149:
150: todr_wenable(handle, 1);
151:
152: /* enable read (stop time) */
153: csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
154: csr |= MK48TXX_CSR_READ;
155: bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
156:
157: dt.dt_sec = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_ISEC));
158: dt.dt_min = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IMIN));
159: dt.dt_hour = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IHOUR));
160: dt.dt_day = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IDAY));
161: dt.dt_wday = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IWDAY));
162: dt.dt_mon = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IMON));
163: year = FROMBCD(bus_space_read_1(bt, bh, clkoff + MK48TXX_IYEAR));
164:
165: year += mk->mk_year0;
166: if (year < POSIX_BASE_YEAR && mk48txx_auto_century_adjust != 0)
167: year += 100;
168:
169: dt.dt_year = year;
170:
171: /* time wears on */
172: csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
173: csr &= ~MK48TXX_CSR_READ;
174: bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
175: todr_wenable(handle, 0);
176:
177: /* simple sanity checks */
178: if (dt.dt_mon > 12 || dt.dt_day > 31 ||
179: dt.dt_hour >= 24 || dt.dt_min >= 60 || dt.dt_sec >= 60)
180: return (1);
181:
182: tv->tv_sec = clock_ymdhms_to_secs(&dt);
183: tv->tv_usec = 0;
184: return (0);
185: }
186:
187: /*
188: * Set the time-of-day clock based on the value of the `struct timeval' arg.
189: * Return 0 on success; an error number otherwise.
190: */
191: int
192: mk48txx_settime(handle, tv)
193: todr_chip_handle_t handle;
194: struct timeval *tv;
195: {
196: struct mk48txx *mk = handle->cookie;
197: bus_space_tag_t bt = mk->mk_bt;
198: bus_space_handle_t bh = mk->mk_bh;
199: bus_size_t clkoff = mk->mk_clkoffset;
200: struct clock_ymdhms dt;
201: u_int8_t csr;
202: int year;
203:
204: /* Note: we ignore `tv_usec' */
205: clock_secs_to_ymdhms(tv->tv_sec, &dt);
206:
207: year = dt.dt_year - mk->mk_year0;
208: if (year > 99 && mk48txx_auto_century_adjust != 0)
209: year -= 100;
210:
211: todr_wenable(handle, 1);
212: /* enable write */
213: csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
214: csr |= MK48TXX_CSR_WRITE;
215: bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
216:
217: bus_space_write_1(bt, bh, clkoff + MK48TXX_ISEC, TOBCD(dt.dt_sec));
218: bus_space_write_1(bt, bh, clkoff + MK48TXX_IMIN, TOBCD(dt.dt_min));
219: bus_space_write_1(bt, bh, clkoff + MK48TXX_IHOUR, TOBCD(dt.dt_hour));
220: bus_space_write_1(bt, bh, clkoff + MK48TXX_IWDAY, TOBCD(dt.dt_wday));
221: bus_space_write_1(bt, bh, clkoff + MK48TXX_IDAY, TOBCD(dt.dt_day));
222: bus_space_write_1(bt, bh, clkoff + MK48TXX_IMON, TOBCD(dt.dt_mon));
223: bus_space_write_1(bt, bh, clkoff + MK48TXX_IYEAR, TOBCD(year));
224:
225: /* load them up */
226: csr = bus_space_read_1(bt, bh, clkoff + MK48TXX_ICSR);
227: csr &= ~MK48TXX_CSR_WRITE;
228: bus_space_write_1(bt, bh, clkoff + MK48TXX_ICSR, csr);
229: todr_wenable(handle, 0);
230: return (0);
231: }
232:
233: int
234: mk48txx_getcal(handle, vp)
235: todr_chip_handle_t handle;
236: int *vp;
237: {
238: return (EOPNOTSUPP);
239: }
240:
241: int
242: mk48txx_setcal(handle, v)
243: todr_chip_handle_t handle;
244: int v;
245: {
246: return (EOPNOTSUPP);
247: }
248:
249: int
250: mk48txx_get_nvram_size(handle, vp)
251: todr_chip_handle_t handle;
252: bus_size_t *vp;
253: {
254: struct mk48txx *mk = handle->cookie;
255: *vp = mk->mk_nvramsz;
256: return (0);
257: }
CVSweb