Exemplo n.º 1
0
int
mc146818_getsecs(device_t dev, int *secp)
{
	struct mc146818_softc *sc;
	int sec, timeout;

	sc = device_get_softc(dev);

	timeout = 1000000;	/* XXX how long should we wait? */

	for (;;) {
		if (!((*sc->sc_mcread)(dev, MC_REGA) & MC_REGA_UIP)) {
			sec = FROMREG((*sc->sc_mcread)(dev, MC_SEC));
			break;
		}
		if (--timeout == 0) {
			device_printf(dev, "mc146818_getsecs: timeout\n");
			return (EBUSY);
		}
	}

#undef FROMREG

	*secp = sec;
	return (0);
}
Exemplo n.º 2
0
/*
 * Get time of day and convert it to a struct timespec.
 * Return 0 on success, an error number otherwise.
 */
int
mc146818_gettime(device_t dev, struct timespec *ts)
{
	struct mc146818_softc *sc;
	struct clocktime ct;
	int timeout, cent, year;

	sc = device_get_softc(dev);

	timeout = 1000000;	/* XXX how long should we wait? */

	/*
	 * XXX:	Use a spinlock to mutex register access and increase the
	 *	likelihood that all registers are read before an update
	 *	occurs.
	 */

	/*
	 * If MC_REGA_UIP is 0 we have at least 244us before the next
	 * update. If it's 1 an update is imminent.
	 */
	for (;;) {
		if (!((*sc->sc_mcread)(dev, MC_REGA) & MC_REGA_UIP))
			break;
		if (--timeout < 0) {
			device_printf(dev, "mc146818_gettime: timeout\n");
			return (EBUSY);
		}
	}

#define	FROMREG(x)	((sc->sc_flag & MC146818_BCD) ? FROMBCD(x) : (x))

	ct.nsec = 0;
	ct.sec = FROMREG((*sc->sc_mcread)(dev, MC_SEC));
	ct.min = FROMREG((*sc->sc_mcread)(dev, MC_MIN));
	ct.hour = FROMREG((*sc->sc_mcread)(dev, MC_HOUR));
	ct.dow = FROMREG((*sc->sc_mcread)(dev, MC_DOW)) - 1;
	ct.day = FROMREG((*sc->sc_mcread)(dev, MC_DOM));
	ct.mon = FROMREG((*sc->sc_mcread)(dev, MC_MONTH));
	year = FROMREG((*sc->sc_mcread)(dev, MC_YEAR));
	if (sc->sc_getcent) {
		cent = (*sc->sc_getcent)(dev);
		year += cent * 100;
	}

	year += sc->sc_year0;
	if (year < POSIX_BASE_YEAR && !(sc->sc_flag & MC146818_NO_CENT_ADJUST))
		year += 100;
	ct.year = year;

	return (clock_ct_to_ts(&ct, ts));
}
Exemplo n.º 3
0
/*
 * Get time of day and convert it to a struct timespec.
 * Return 0 on success, an error number otherwise.
 */
int
mc146818_gettime(device_t dev, struct timespec *ts)
{
	struct mc146818_softc *sc;
	struct clocktime ct;
	int timeout, cent, year;

	sc = device_get_softc(dev);

	timeout = 1000000;	/* XXX how long should we wait? */

	/*
	 * If MC_REGA_UIP is 0 we have at least 244us before the next
	 * update. If it's 1 an update is imminent.
	 */
	for (;;) {
		mtx_lock_spin(&sc->sc_mtx);
		if (!((*sc->sc_mcread)(dev, MC_REGA) & MC_REGA_UIP))
			break;
		mtx_unlock_spin(&sc->sc_mtx);
		if (--timeout < 0) {
			device_printf(dev, "%s: timeout\n", __func__);
			return (EBUSY);
		}
	}

#define	FROMREG(x)	((sc->sc_flag & MC146818_BCD) ? FROMBCD(x) : (x))

	ct.nsec = 0;
	ct.sec = FROMREG((*sc->sc_mcread)(dev, MC_SEC));
	ct.min = FROMREG((*sc->sc_mcread)(dev, MC_MIN));
	ct.hour = FROMREG((*sc->sc_mcread)(dev, MC_HOUR));
	/* Map dow from 1 - 7 to 0 - 6. */
	ct.dow = FROMREG((*sc->sc_mcread)(dev, MC_DOW)) - 1;
	ct.day = FROMREG((*sc->sc_mcread)(dev, MC_DOM));
	ct.mon = FROMREG((*sc->sc_mcread)(dev, MC_MONTH));
	year = FROMREG((*sc->sc_mcread)(dev, MC_YEAR));
	year += sc->sc_year0;
	if (sc->sc_flag & MC146818_NO_CENT_ADJUST) {
		cent = (*sc->sc_getcent)(dev);
		year += cent * 100;
	} else if (year < POSIX_BASE_YEAR)
		year += 100;
	mtx_unlock_spin(&sc->sc_mtx);

	ct.year = year;

	return (clock_ct_to_ts(&ct, ts));
}
Exemplo n.º 4
0
/*
 * Get time-of-day and convert to a `struct timespec'
 * Return 0 on success; an error number otherwise.
 */
int
mk48txx_gettime(device_t dev, struct timespec *ts)
{
	struct mk48txx_softc *sc;
	bus_size_t clkoff;
	struct clocktime ct;
	int year;
	uint8_t csr;

	sc = device_get_softc(dev);
	clkoff = sc->sc_clkoffset;

	mtx_lock(&sc->sc_mtx);
	/* enable read (stop time) */
	csr = (*sc->sc_nvrd)(dev, clkoff + MK48TXX_ICSR);
	csr |= MK48TXX_CSR_READ;
	(*sc->sc_nvwr)(dev, clkoff + MK48TXX_ICSR, csr);

#define	FROMREG(reg, mask)	((*sc->sc_nvrd)(dev, clkoff + (reg)) & (mask))

	ct.nsec = 0;
	ct.sec = FROMBCD(FROMREG(MK48TXX_ISEC, MK48TXX_SEC_MASK));
	ct.min = FROMBCD(FROMREG(MK48TXX_IMIN, MK48TXX_MIN_MASK));
	ct.hour = FROMBCD(FROMREG(MK48TXX_IHOUR, MK48TXX_HOUR_MASK));
	ct.day = FROMBCD(FROMREG(MK48TXX_IDAY, MK48TXX_DAY_MASK));
#if 0
	/* Map dow from 1 - 7 to 0 - 6; FROMBCD() isn't necessary here. */
	ct.dow = FROMREG(MK48TXX_IWDAY, MK48TXX_WDAY_MASK) - 1;
#else
	/*
	 * Set dow = -1 because some drivers (for example the NetBSD and
	 * OpenBSD mk48txx(4)) don't set it correctly.
	 */
	ct.dow = -1;
#endif
	ct.mon = FROMBCD(FROMREG(MK48TXX_IMON, MK48TXX_MON_MASK));
	year = FROMBCD(FROMREG(MK48TXX_IYEAR, MK48TXX_YEAR_MASK));
	year += sc->sc_year0;
	if (sc->sc_flag & MK48TXX_NO_CENT_ADJUST)
		year += (FROMREG(MK48TXX_IWDAY, MK48TXX_WDAY_CB) >>
		    MK48TXX_WDAY_CB_SHIFT) * 100;
	else if (year < POSIX_BASE_YEAR)