summaryrefslogtreecommitdiffstats
path: root/sys/arch/octeon/dev/octrtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/octeon/dev/octrtc.c')
-rw-r--r--sys/arch/octeon/dev/octrtc.c95
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