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; }
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; }