Annotation of sys/dev/ic/mk48txx.c, Revision 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