FreeBSD/sys/dev/mk48txx/mk48txx.c
/*
 * Set the time-of-day clock based on the value of the `struct timespec' arg.
 * Return 0 on success; an error number otherwise.
 */
Set the time-of-day clock based on the value of the `struct timespec' arg.
Return 0 on success; an error number otherwise.
Set the time - of - day clock based on the value of the ` struct timespec ' arg . Return 0 on success ; an error number otherwise .
int
mk48txx_settime(device_t dev, struct timespec *ts)
{
	struct mk48txx_softc *sc;
	bus_size_t clkoff;
	struct clocktime ct;
	uint8_t csr;
	int cent, year;
	sc = device_get_softc(dev);
	clkoff = sc->sc_clkoffset;
	if (ts->tv_nsec >= 500000000)
		ts->tv_sec++;
	ts->tv_nsec = 0;
	clock_ts_to_ct(ts, &ct);
	mtx_lock(&sc->sc_mtx);
	csr = (*sc->sc_nvrd)(dev, clkoff + MK48TXX_ICSR);
	csr |= MK48TXX_CSR_WRITE;
	(*sc->sc_nvwr)(dev, clkoff + MK48TXX_ICSR, csr);
#define	TOREG(reg, mask, val)						\
	((*sc->sc_nvwr)(dev, clkoff + (reg),				\
	((*sc->sc_nvrd)(dev, clkoff + (reg)) & ~(mask)) |		\
	((val) & (mask))))
	TOREG(MK48TXX_ISEC, MK48TXX_SEC_MASK, TOBCD(ct.sec));
	TOREG(MK48TXX_IMIN, MK48TXX_MIN_MASK, TOBCD(ct.min));
	TOREG(MK48TXX_IHOUR, MK48TXX_HOUR_MASK, TOBCD(ct.hour));
	TOREG(MK48TXX_IWDAY, MK48TXX_WDAY_MASK, ct.dow + 1);
	TOREG(MK48TXX_IDAY, MK48TXX_DAY_MASK, TOBCD(ct.day));
	TOREG(MK48TXX_IMON, MK48TXX_MON_MASK, TOBCD(ct.mon));
	year = ct.year - sc->sc_year0;
	if (sc->sc_flag & MK48TXX_NO_CENT_ADJUST) {
		cent = year / 100;
		TOREG(MK48TXX_IWDAY, MK48TXX_WDAY_CB,
		    cent << MK48TXX_WDAY_CB_SHIFT);
		year -= cent * 100;
	} else if (year > 99)
		year -= 100;
	TOREG(MK48TXX_IYEAR, MK48TXX_YEAR_MASK, TOBCD(year));
#undef TOREG
	csr = (*sc->sc_nvrd)(dev, clkoff + MK48TXX_ICSR);
	csr &= ~MK48TXX_CSR_WRITE;
	(*sc->sc_nvwr)(dev, clkoff + MK48TXX_ICSR, csr);
	mtx_unlock(&sc->sc_mtx);
	return (0);
}
int mk48txx_settime ( device_t dev , struct timespec * ts ) { struct mk48txx_softc * sc ; bus_size_t clkoff ; struct clocktime ct ; uint8_t csr ; int cent , year ; sc = device_get_softc ( dev ) ; clkoff = sc -> sc_clkoffset ; if ( ts -> tv_nsec >= 500000000 ) ts -> tv_sec ++ ; ts -> tv_nsec = 0 ; clock_ts_to_ct ( ts , & ct ) ; mtx_lock ( & sc -> sc_mtx ) ; csr = ( * sc -> sc_nvrd ) ( dev , clkoff + MK48TXX_ICSR ) ; csr |= MK48TXX_CSR_WRITE ; ( * sc -> sc_nvwr ) ( dev , clkoff + MK48TXX_ICSR , csr ) ; #define TOREG ( reg , mask , val ) 						\
	((*sc->sc_nvwr)(dev, clkoff + (reg),				\
	((*sc->sc_nvrd)(dev, clkoff + (reg)) & ~(mask)) |		\
	((val) & (mask)))) TOREG ( MK48TXX_ISEC , MK48TXX_SEC_MASK , TOBCD ( ct . sec ) ) ; TOREG ( MK48TXX_IMIN , MK48TXX_MIN_MASK , TOBCD ( ct . min ) ) ; TOREG ( MK48TXX_IHOUR , MK48TXX_HOUR_MASK , TOBCD ( ct . hour ) ) ; TOREG ( MK48TXX_IWDAY , MK48TXX_WDAY_MASK , ct . dow + 1 ) ; TOREG ( MK48TXX_IDAY , MK48TXX_DAY_MASK , TOBCD ( ct . day ) ) ; TOREG ( MK48TXX_IMON , MK48TXX_MON_MASK , TOBCD ( ct . mon ) ) ; year = ct . year - sc -> sc_year0 ; if ( sc -> sc_flag & MK48TXX_NO_CENT_ADJUST ) { cent = year / 100 ; TOREG ( MK48TXX_IWDAY , MK48TXX_WDAY_CB , cent << MK48TXX_WDAY_CB_SHIFT ) ; year -= cent * 100 ; } else if ( year > 99 ) year -= 100 ; TOREG ( MK48TXX_IYEAR , MK48TXX_YEAR_MASK , TOBCD ( year ) ) ; #undef  TOREG csr = ( * sc -> sc_nvrd ) ( dev , clkoff + MK48TXX_ICSR ) ; csr &= ~ MK48TXX_CSR_WRITE ; ( * sc -> sc_nvwr ) ( dev , clkoff + MK48TXX_ICSR , csr ) ; mtx_unlock ( & sc -> sc_mtx ) ; return ( 0 ) ; }
Set the time-of-day clock based on the value of the `struct timespec' arg.
Set the time - of - day clock based on the value of the ` struct timespec ' arg .
/* Accuracy is only one second. */ /* enable write */ /* Map dow from 0 - 6 to 1 - 7; TOBCD() isn't necessary here. */ /* load them up */