1/*- 2 * Copyright (c) 2003 Izumi Tsutsui. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 13 unchanged lines hidden (view full) --- 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * from: NetBSD: mc146818.c,v 1.4 2003/11/24 06:20:40 tsutsui Exp 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/mc146818/mc146818.c 146982 2005-06-04 23:24:50Z marius $"); |
31 32/* 33 * mc146818 and compatible time of day chip subroutines 34 */ 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/bus.h> --- 36 unchanged lines hidden (view full) --- 75 * the century has to be stored in NVRAM somewhere. 76 */ 77 if (sc->sc_getcent == NULL) 78 sc->sc_getcent = mc146818_def_getcent; 79 if (sc->sc_setcent == NULL) 80 sc->sc_setcent = mc146818_def_setcent; 81 } 82 |
83 mtx_lock_spin(&sc->sc_mtx); |
84 if (!(*sc->sc_mcread)(dev, MC_REGD) & MC_REGD_VRT) { |
85 mtx_unlock_spin(&sc->sc_mtx); |
86 device_printf(dev, "%s: battery low\n", __func__); 87 return (ENXIO); 88 } 89 90 sc->sc_rega = MC_BASE_32_KHz; 91 (*sc->sc_mcwrite)(dev, MC_REGA, sc->sc_rega); 92 93 sc->sc_regb = 0; 94 sc->sc_regb |= (sc->sc_flag & MC146818_BCD) ? 0 : MC_REGB_BINARY; 95 sc->sc_regb |= (sc->sc_flag & MC146818_12HR) ? 0 : MC_REGB_24HR; 96 (*sc->sc_mcwrite)(dev, MC_REGB, sc->sc_regb); |
97 mtx_unlock_spin(&sc->sc_mtx); |
98 99 clock_register(dev, 1000000); /* 1 second resolution. */ 100 101 return (0); 102} 103 104/* 105 * Get time of day and convert it to a struct timespec. --- 5 unchanged lines hidden (view full) --- 111 struct mc146818_softc *sc; 112 struct clocktime ct; 113 int timeout, cent, year; 114 115 sc = device_get_softc(dev); 116 117 timeout = 1000000; /* XXX how long should we wait? */ 118 |
119 /* 120 * If MC_REGA_UIP is 0 we have at least 244us before the next 121 * update. If it's 1 an update is imminent. 122 */ 123 for (;;) { |
124 mtx_lock_spin(&sc->sc_mtx); |
125 if (!((*sc->sc_mcread)(dev, MC_REGA) & MC_REGA_UIP)) 126 break; |
127 mtx_unlock_spin(&sc->sc_mtx); |
128 if (--timeout < 0) { |
129 device_printf(dev, "%s: timeout\n", __func__); 130 return (EBUSY); 131 } 132 } 133 134#define FROMREG(x) ((sc->sc_flag & MC146818_BCD) ? FROMBCD(x) : (x)) 135 136 ct.nsec = 0; --- 6 unchanged lines hidden (view full) --- 143 ct.mon = FROMREG((*sc->sc_mcread)(dev, MC_MONTH)); 144 year = FROMREG((*sc->sc_mcread)(dev, MC_YEAR)); 145 year += sc->sc_year0; 146 if (sc->sc_flag & MC146818_NO_CENT_ADJUST) { 147 cent = (*sc->sc_getcent)(dev); 148 year += cent * 100; 149 } else if (year < POSIX_BASE_YEAR) 150 year += 100; |
151 mtx_unlock_spin(&sc->sc_mtx); |
152 153 ct.year = year; 154 155 return (clock_ct_to_ts(&ct, ts)); 156} 157 158#ifdef notyet 159int 160mc146818_getsecs(device_t dev, int *secp) 161{ 162 struct mc146818_softc *sc; 163 int sec, timeout; 164 165 sc = device_get_softc(dev); 166 167 timeout = 1000000; /* XXX how long should we wait? */ 168 |
169 for (;;) { |
170 mtx_lock_spin(&sc->sc_mtx); |
171 if (!((*sc->sc_mcread)(dev, MC_REGA) & MC_REGA_UIP)) { 172 sec = FROMREG((*sc->sc_mcread)(dev, MC_SEC)); |
173 mtx_unlock_spin(&sc->sc_mtx); |
174 break; 175 } |
176 mtx_unlock_spin(&sc->sc_mtx); |
177 if (--timeout == 0) { |
178 device_printf(dev, "%s: timeout\n", __func__); 179 return (EBUSY); 180 } 181 } |
182 183#undef FROMREG 184 185 *secp = sec; 186 return (0); 187} 188#endif 189 --- 11 unchanged lines hidden (view full) --- 201 sc = device_get_softc(dev); 202 203 /* Accuracy is only one second. */ 204 if (ts->tv_nsec >= 500000000) 205 ts->tv_sec++; 206 ts->tv_nsec = 0; 207 clock_ts_to_ct(ts, &ct); 208 |
209 mtx_lock_spin(&sc->sc_mtx); |
210 /* Disable RTC updates and interrupts (if enabled). */ 211 (*sc->sc_mcwrite)(dev, MC_REGB, 212 ((sc->sc_regb & (MC_REGB_BINARY | MC_REGB_24HR)) | MC_REGB_SET)); 213 214#define TOREG(x) ((sc->sc_flag & MC146818_BCD) ? TOBCD(x) : (x)) 215 216 (*sc->sc_mcwrite)(dev, MC_SEC, TOREG(ct.sec)); 217 (*sc->sc_mcwrite)(dev, MC_MIN, TOREG(ct.min)); --- 9 unchanged lines hidden (view full) --- 227 (*sc->sc_setcent)(dev, cent); 228 year -= cent * 100; 229 } else if (year > 99) 230 year -= 100; 231 (*sc->sc_mcwrite)(dev, MC_YEAR, TOREG(year)); 232 233 /* Reenable RTC updates and interrupts. */ 234 (*sc->sc_mcwrite)(dev, MC_REGB, sc->sc_regb); |
235 mtx_unlock_spin(&sc->sc_mtx); |
236 237#undef TOREG 238 239 return (0); 240} 241 242#define MC_ADDR 0 243#define MC_DATA 1 --- 44 unchanged lines hidden --- |