예제 #1
0
static int
rs5c313_todr_gettime_ymdhms(todr_chip_handle_t todr, struct clock_ymdhms *dt)
{
	struct rs5c313_softc *sc = todr->cookie;
	int retry;
	int s;

	/*
	 * If chip had invalid data on init, don't bother reading
	 * bogus values, let todr(9) cope.
	 */
	if (sc->sc_valid == 0)
		return EIO;

	s = splhigh();

	rtc_begin(sc);
	for (retry = 10; retry > 0; --retry) {
		rtc_ce(sc, 1);

		rs5c313_write_reg(sc, RS5C313_CTRL, sc->sc_ctrl[0]);
		if ((rs5c313_read_reg(sc, RS5C313_CTRL) & CTRL_BSY) == 0)
			break;

		rtc_ce(sc, 0);
		delay(1);
	}
	if (retry == 0) {
		splx(s);
		return EIO;
	}

#define RTCGET(x, y)							\
	do {								\
		int ones = rs5c313_read_reg(sc, RS5C313_ ## y ## 1);	\
		int tens = rs5c313_read_reg(sc, RS5C313_ ## y ## 10);	\
		dt->dt_ ## x = tens * 10 + ones;			\
	} while (/* CONSTCOND */0)

	RTCGET(sec, SEC);
	RTCGET(min, MIN);
	RTCGET(hour, HOUR);
	RTCGET(day, DAY);
	RTCGET(mon, MON);
	RTCGET(year, YEAR);
#undef	RTCGET
	dt->dt_wday = rs5c313_read_reg(sc, RS5C313_WDAY);

	rtc_ce(sc, 0);
	splx(s);

	dt->dt_year = (dt->dt_year % 100) + 1900;
	if (dt->dt_year < POSIX_BASE_YEAR) {
		dt->dt_year += 100;
	}

	return 0;
}
예제 #2
0
void
sh_rtc_get(void *cookie, time_t base, struct clock_ymdhms *dt)
{
	int retry = 8;

	/* disable carry interrupt */
	_reg_bclr_1(SH_(RCR1), SH_RCR1_CIE);

	do {
		uint8_t r = _reg_read_1(SH_(RCR1));
		r &= ~SH_RCR1_CF;
		r |= SH_RCR1_AF; /* don't clear alarm flag */
		_reg_write_1(SH_(RCR1), r);

		if (CPU_IS_SH3)
			dt->dt_year = FROMBCD(_reg_read_1(SH3_RYRCNT));
		else
			dt->dt_year = FROMBCD(_reg_read_2(SH4_RYRCNT) & 0x00ff);

		/* read counter */
#define	RTCGET(x, y)	dt->dt_ ## x = FROMBCD(_reg_read_1(SH_(R ## y ## CNT)))
		RTCGET(mon, MON);
		RTCGET(wday, WK);
		RTCGET(day, DAY);
		RTCGET(hour, HR);
		RTCGET(min, MIN);
		RTCGET(sec, SEC);
#undef RTCGET
	} while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0);

	if (retry == 0) {
		printf("rtc_gettime: couldn't read RTC register.\n");
		memset(dt, 0, sizeof(*dt));
		return;
	}

	dt->dt_year = (dt->dt_year % 100) + 1900;
	if (dt->dt_year < 1970)
		dt->dt_year += 100;
}