diff options
Diffstat (limited to 'sys/arch/octeon/dev/octrtc.c')
-rw-r--r-- | sys/arch/octeon/dev/octrtc.c | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/sys/arch/octeon/dev/octrtc.c b/sys/arch/octeon/dev/octrtc.c index 22eb499a952..129f83726c3 100644 --- a/sys/arch/octeon/dev/octrtc.c +++ b/sys/arch/octeon/dev/octrtc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: octrtc.c,v 1.11 2017/11/20 15:20:03 visa Exp $ */ +/* $OpenBSD: octrtc.c,v 1.12 2020/06/30 14:47:16 visa Exp $ */ /* * Copyright (c) 2013, 2014 Paul Irofti. @@ -21,7 +21,7 @@ #include <sys/device.h> #include <sys/proc.h> -#include <mips64/dev/clockvar.h> +#include <dev/clock_subr.h> #include <machine/bus.h> #include <machine/autoconf.h> @@ -37,6 +37,11 @@ #define MIO_TWS_SW_TWSI_EXT 0x0001180000001018ULL #define OCTRTC_REG 0x68 +struct octrtc_softc { + struct device sc_dev; + struct todr_chip_handle sc_todr; +}; + struct cfdriver octrtc_cd = { NULL, "octrtc", DV_DULL }; @@ -44,15 +49,15 @@ struct cfdriver octrtc_cd = { int octrtc_match(struct device *, void *, void *); void octrtc_attach(struct device *, struct device *, void *); -void octrtc_gettime(void *, time_t, struct tod_time *); +int octrtc_gettime(struct todr_chip_handle *, struct timeval *); int octrtc_read(uint8_t *, char); -void octrtc_settime(void *, struct tod_time *); +int octrtc_settime(struct todr_chip_handle *, struct timeval *); int octrtc_write(uint8_t); struct cfattach octrtc_ca = { - sizeof(struct device), octrtc_match, octrtc_attach, + sizeof(struct octrtc_softc), octrtc_match, octrtc_attach, }; @@ -105,16 +110,18 @@ octrtc_attach(struct device *parent, struct device *self, void *aux) { struct octrtc_softc *sc = (struct octrtc_softc *)self; - sys_tod.tod_cookie = sc; - sys_tod.tod_get = octrtc_gettime; - sys_tod.tod_set = octrtc_settime; + sc->sc_todr.cookie = sc; + sc->sc_todr.todr_gettime = octrtc_gettime; + sc->sc_todr.todr_settime = octrtc_settime; + todr_attach(&sc->sc_todr); printf(": DS1337\n"); } -void -octrtc_gettime(void *cookie, time_t unused, struct tod_time *tt) +int +octrtc_gettime(struct todr_chip_handle *handle, struct timeval *tv) { + struct clock_ymdhms dt; uint8_t tod[8]; uint8_t check; int i, rc; @@ -126,14 +133,14 @@ octrtc_gettime(void *cookie, time_t unused, struct tod_time *tt) rc = octrtc_read(&tod[0], 1); /* ia read */ if (rc) { DPRINTF(("octrtc_read(0) failed %d", rc)); - return; + return EIO; } for (i = 1; i < 8; i++) { rc = octrtc_read(&tod[i], 0); /* current address */ if (rc) { DPRINTF(("octrtc_read(%d) failed %d", i, rc)); - return; + return EIO; } DPRINTF(("%#X ", tod[i])); } @@ -141,8 +148,8 @@ octrtc_gettime(void *cookie, time_t unused, struct tod_time *tt) /* Check against time-wrap */ rc = octrtc_read(&check, 1); /* ia read */ if (rc) { - DPRINTF(("octrtc_read(check) failed %d", i, rc)); - return; + DPRINTF(("octrtc_read(check) failed %d", rc)); + return EIO; } if ((check & 0xf) == (tod[0] & 0xf)) break; @@ -158,15 +165,24 @@ octrtc_gettime(void *cookie, time_t unused, struct tod_time *tt) FROMBCD(tod[1] & 0x7f), /* minute */ FROMBCD(tod[0] & 0x7f))); /* second */ - tt->year = ((tod[5] & 0x80) ? 100 : 0) + FROMBCD(tod[6]); - tt->mon = FROMBCD(tod[5] & 0x1f); - tt->day = FROMBCD(tod[4] & 0x3f); - tt->dow = (tod[3] & 0x7); - tt->hour = FROMBCD(tod[2] & 0x3f); + dt.dt_year = ((tod[5] & 0x80) ? 2000 : 1900) + FROMBCD(tod[6]); + dt.dt_mon = FROMBCD(tod[5] & 0x1f); + dt.dt_day = FROMBCD(tod[4] & 0x3f); + dt.dt_hour = FROMBCD(tod[2] & 0x3f); if ((tod[2] & 0x40) && (tod[2] & 0x20)) /* adjust AM/PM format */ - tt->hour = (tt->hour + 12) % 24; - tt->min = FROMBCD(tod[1] & 0x7f); - tt->sec = FROMBCD(tod[0] & 0x7f); + dt.dt_hour = (dt.dt_hour + 12) % 24; + dt.dt_min = FROMBCD(tod[1] & 0x7f); + dt.dt_sec = FROMBCD(tod[0] & 0x7f); + + if (dt.dt_sec > 59 || dt.dt_min > 59 || dt.dt_hour > 23 || + dt.dt_day > 31 || dt.dt_day == 0 || + dt.dt_mon > 12 || dt.dt_mon == 0 || + dt.dt_year < POSIX_BASE_YEAR) + return EINVAL; + + tv->tv_sec = clock_ymdhms_to_secs(&dt); + tv->tv_usec = 0; + return 0; } int @@ -217,46 +233,51 @@ again: return 0; } -void -octrtc_settime(void *cookie, struct tod_time *tt) +int +octrtc_settime(struct todr_chip_handle *handle, struct timeval *tv) { + struct clock_ymdhms dt; int nretries = 2; int rc, i; uint8_t tod[8]; uint8_t check; + clock_secs_to_ymdhms(tv->tv_sec, &dt); + DPRINTF(("settime: %d %d %d (%d) %02d:%02d:%02d\n", - tt->year, tt->mon, tt->day, tt->dow, - tt->hour, tt->min, tt->sec)); - - tod[0] = TOBCD(tt->sec); - tod[1] = TOBCD(tt->min); - tod[2] = TOBCD(tt->hour); - tod[3] = TOBCD(tt->dow); - tod[4] = TOBCD(tt->day); - tod[5] = TOBCD(tt->mon); - if (tt->year >= 100) + dt.dt_year, dt.dt_mon, dt.dt_day, dt.dt_wday, + dt.dt_hour, dt.dt_min, dt.dt_sec)); + + tod[0] = TOBCD(dt.dt_sec); + tod[1] = TOBCD(dt.dt_min); + tod[2] = TOBCD(dt.dt_hour); + tod[3] = TOBCD(dt.dt_wday + 1); + tod[4] = TOBCD(dt.dt_day); + tod[5] = TOBCD(dt.dt_mon); + if (dt.dt_year >= 2000) tod[5] |= 0x80; - tod[6] = TOBCD(tt->year % 100); + tod[6] = TOBCD(dt.dt_year % 100); while (nretries--) { for (i = 0; i < 7; i++) { rc = octrtc_write(tod[i]); if (rc) { DPRINTF(("octrtc_write(%d) failed %d", i, rc)); - return; + return EIO; } } rc = octrtc_read(&check, 1); if (rc) { DPRINTF(("octrtc_read(check) failed %d", rc)); - return; + return EIO; } if ((check & 0xf) == (tod[0] & 0xf)) break; } + + return 0; } int |