Hi,

some arm64 that I'd like to use as replacement server for the one that's
crashing all the time (probably HW-related) has a Microcrystal RV4162
RTC.  As it turns out, this is about the same as the ST M41T8x series.

For that one we already have mfokclock(4), but only for loongson.  After
talking to kettenis@, we think that first of all sys/arch/loongson/dev/
m41t8xclock.c should be moved to sys/dev/i2c/m41t8x.c so that the file
can be re-used by multiple architectures.  And usually we don't have the
type of device in the filename, so I removed that as well.

Usually we reserve clock for clock control subsystems, while we call
RTCs as they are.  That's why I renamed mfokclock(4) to mfokrtc(4),
and also renamed the code accordingly.

Instead of matching on the driver's name, let's match on st,m41t83, as
when the driver was imported that specific chip was the reason for the
driver.  This also means changing the iic controller to pass a different
string.

Can someone make sure this still works on their loongson devices?  Are
there any objections to this?

Thank you,
Patrick

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 4a3df6b33b1..8ba306f41ed 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -47,8 +47,8 @@ MAN=  aac.4 abcrtc.4 abl.4 ac97.4 acphy.4 acrtc.4 \
        kate.4 kcov.4 km.4 ksmn.4 ksyms.4 kubsan.4 kue.4 lc.4 lge.4 lii.4 \
        lisa.4 lm.4 lmenv.4 lmn.4 lmtemp.4 lo.4 lpt.4 lxtphy.4 luphy.4 \
        maestro.4 mainbus.4 malo.4 maxds.4 maxrtc.4 maxtmp.4 mbg.4 \
-       mcprtc.4 mcx.4 midi.4 mii.4 mfi.4 \
-       mfii.4 mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 \
+       mcprtc.4 mcx.4 midi.4 mii.4 mfi.4 mfii.4 mfokrtc.4 \
+       mlphy.4 moscom.4 mos.4 mpe.4 mpath.4 mpi.4 mpii.4 \
        mpip.4 mpu.4 msk.4 mpw.4 msts.4 mtd.4 mtdphy.4 mtio.4 mue.4 \
        multicast.4 mvclock.4 mvdog.4 mvgicp.4 mvgpio.4 mvicu.4 mviic.4 \
        mvneta.4 mvpinctrl.4 mvpp.4 mvrng.4 mvrtc.4 mvspi.4 mvtemp.4 mvuart.4 \
diff --git a/share/man/man4/man4.loongson/Makefile 
b/share/man/man4/man4.loongson/Makefile
index 6e133c04f62..b3d5b061c84 100644
--- a/share/man/man4/man4.loongson/Makefile
+++ b/share/man/man4/man4.loongson/Makefile
@@ -1,7 +1,7 @@
 #      $OpenBSD: Makefile,v 1.10 2016/11/17 15:06:16 visa Exp $
 
 MAN=   apm.4 autoconf.4 bonito.4 gdiumiic.4 glxclk.4 glxpcib.4 htb.4 intro.4 \
-       leioc.4 mem.4 mfokclock.4 sisfb.4 smfb.4 stsec.4 voyager.4 ykbec.4
+       leioc.4 mem.4 sisfb.4 smfb.4 stsec.4 voyager.4 ykbec.4
 MANSUBDIR=loongson
 
 .include <bsd.prog.mk>
diff --git a/share/man/man4/man4.loongson/mfokclock.4 
b/share/man/man4/man4.loongson/mfokclock.4
deleted file mode 100644
index 69d122dfdf2..00000000000
--- a/share/man/man4/man4.loongson/mfokclock.4
+++ /dev/null
@@ -1,31 +0,0 @@
-.\"    $OpenBSD: mfokclock.4,v 1.2 2018/06/18 06:06:52 jmc Exp $
-.\"
-.\" Copyright (c) 2010 Miodrag Vallat.
-.\"
-.\" Permission to use, copy, modify, and distribute this software for any
-.\" purpose with or without fee is hereby granted, provided that the above
-.\" copyright notice and this permission notice appear in all copies.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-.\"
-.Dd $Mdocdate: June 18 2018 $
-.Dt MFOKCLOCK 4 loongson
-.Os
-.Sh NAME
-.Nm mfokclock
-.Nd M41T8x real-time clock
-.Sh SYNOPSIS
-.Cd "mfokclock* at iic? addr 0x68"
-.Sh DESCRIPTION
-The
-.Nm
-driver supports two-wire real-time clock chips of the M41T8x family.
-.Sh SEE ALSO
-.Xr iic 4 ,
-.Xr intro 4
diff --git a/share/man/man4/mfokrtc.4 b/share/man/man4/mfokrtc.4
new file mode 100644
index 00000000000..487591817ec
--- /dev/null
+++ b/share/man/man4/mfokrtc.4
@@ -0,0 +1,31 @@
+.\"    $OpenBSD: mfokclock.4,v 1.2 2018/06/18 06:06:52 jmc Exp $
+.\"
+.\" Copyright (c) 2010 Miodrag Vallat.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: June 18 2018 $
+.Dt MFOKRTC 4
+.Os
+.Sh NAME
+.Nm mfokrtc
+.Nd M41T8x real-time clock
+.Sh SYNOPSIS
+.Cd "mfokrtc* at iic? addr 0x68"
+.Sh DESCRIPTION
+The
+.Nm
+driver supports two-wire real-time clock chips of the M41T8x family.
+.Sh SEE ALSO
+.Xr iic 4 ,
+.Xr intro 4
diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC
index 00ddc2591b0..6bd97176c70 100644
--- a/sys/arch/arm64/conf/GENERIC
+++ b/sys/arch/arm64/conf/GENERIC
@@ -439,6 +439,7 @@ ipmi*               at iic?                 # IPMI (SIIF)
 islrtc*                at iic?                 # ISL1208 RTC
 maxrtc*                at iic?                 # DS1307 RTC
 mcprtc*                at iic?                 # MCP794XX RTC
+mfokrtc*       at iic?                 # M41T8X RTC
 pcamux*                at iic?                 # PCA9548 multiplexer
 iic*           at pcamux?
 pcfrtc*                at iic?                 # PCF8523 RTC
diff --git a/sys/arch/arm64/conf/RAMDISK b/sys/arch/arm64/conf/RAMDISK
index 56f024f7962..4ea762f406a 100644
--- a/sys/arch/arm64/conf/RAMDISK
+++ b/sys/arch/arm64/conf/RAMDISK
@@ -313,6 +313,7 @@ fusbtc*             at iic?                 # USB Type-C 
controller
 islrtc*                at iic?                 # ISL1208 RTC
 maxrtc*                at iic?                 # DS1307 RTC
 mcprtc*                at iic?                 # MCP794XX RTC
+mfokrtc*       at iic?                 # M41T8X RTC
 pcfrtc*                at iic?                 # PCF8523 RTC
 pcxrtc*                at iic?                 # PCF8563 RTC
 rkpmic*                at iic?                 # RK808 PMIC
diff --git a/sys/arch/loongson/conf/GENERIC b/sys/arch/loongson/conf/GENERIC
index 32f10728769..79db9b97861 100644
--- a/sys/arch/loongson/conf/GENERIC
+++ b/sys/arch/loongson/conf/GENERIC
@@ -74,7 +74,7 @@ gdiumiic0     at gpio0 offset 46 mask 0x03    # pins 46 and 47
 iic0           at gdiumiic0
 stsec0         at iic0                         # ST7 Embedded Controller
 lmtemp0                at iic0                         # National 
Semiconductor LM75
-mfokclock0     at iic0                         # M41T8x todclock
+mfokrtc0       at iic0                         # M41T8x RTC
 #iic*          at voyager?
 ohci*          at voyager?
 smfb*          at voyager?
diff --git a/sys/arch/loongson/conf/RAMDISK b/sys/arch/loongson/conf/RAMDISK
index 31514141754..90c9c0538ef 100644
--- a/sys/arch/loongson/conf/RAMDISK
+++ b/sys/arch/loongson/conf/RAMDISK
@@ -61,7 +61,7 @@ gpio0         at voyager?
 gdiumiic0      at gpio0 offset 6 mask 0x81     # pins 6 and 13
 gdiumiic0      at gpio0 offset 46 mask 0x03    # pins 46 and 47
 iic0           at gdiumiic0
-mfokclock0     at iic0                         # M41T8x todclock
+mfokrtc0       at iic0                         # M41T8x RTC
 ohci*          at voyager?
 smfb*          at voyager?
 wsdisplay*     at smfb?
diff --git a/sys/arch/loongson/conf/files.loongson 
b/sys/arch/loongson/conf/files.loongson
index c28f4b5b5c3..2ed7d21e2c0 100644
--- a/sys/arch/loongson/conf/files.loongson
+++ b/sys/arch/loongson/conf/files.loongson
@@ -102,11 +102,6 @@ device     stsec
 attach stsec at i2c
 file   arch/loongson/dev/stsec.c                       stsec
 
-# Gdium M41T8x RTC
-device mfokclock
-attach mfokclock at i2c
-file   arch/loongson/dev/m41t8xclock.c                 mfokclock
-
 # SM502 OHCI
 attach ohci at voyager with ohci_voyager
 file   arch/loongson/dev/ohci_voyager.c                ohci_voyager
diff --git a/sys/arch/loongson/dev/gdiumiic.c b/sys/arch/loongson/dev/gdiumiic.c
index eca4599b8f8..bc56389d175 100644
--- a/sys/arch/loongson/dev/gdiumiic.c
+++ b/sys/arch/loongson/dev/gdiumiic.c
@@ -374,6 +374,6 @@ gdiumiic_sensors_scan(struct device *iicdev, struct 
i2cbus_attach_args *iba,
        ia.ia_tag = iba->iba_tag;
        ia.ia_addr = 0x68;
        ia.ia_size = 1;
-       ia.ia_name = "mfokclock";
+       ia.ia_name = "st,m41t83";
        config_found(iicdev, &ia, iic_print);
 }
diff --git a/sys/arch/loongson/dev/m41t8xclock.c 
b/sys/arch/loongson/dev/m41t8xclock.c
deleted file mode 100644
index c0f4fb01690..00000000000
--- a/sys/arch/loongson/dev/m41t8xclock.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*     $OpenBSD: m41t8xclock.c,v 1.4 2020/05/25 13:15:37 visa Exp $    */
-
-/*
- * Copyright (c) 2010 Miodrag Vallat.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * M41T8x clock connected to an I2C bus
- */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-
-#include <dev/clock_subr.h>
-#include <dev/i2c/i2cvar.h>
-#include <dev/ic/m41t8xreg.h>
-
-struct m41t8xclock_softc {
-       struct device           sc_dev;
-       struct todr_chip_handle sc_todr;
-       i2c_tag_t               sc_tag;
-       i2c_addr_t              sc_addr;
-};
-
-int    m41t8xclock_match(struct device *, void *, void *);
-void   m41t8xclock_attach(struct device *, struct device *, void *);
-
-const struct cfattach mfokclock_ca = {
-       sizeof(struct m41t8xclock_softc),
-       m41t8xclock_match, m41t8xclock_attach
-};
-
-struct cfdriver mfokclock_cd = {
-       NULL, "mfokclock", DV_DULL
-};
-
-int    m41t8xclock_gettime(struct todr_chip_handle *, struct timeval *);
-int    m41t8xclock_settime(struct todr_chip_handle *, struct timeval *);
-
-int
-m41t8xclock_match(struct device *parent, void *vcf, void *aux)
-{
-       struct i2c_attach_args *ia = (struct i2c_attach_args *)aux;
-       struct cfdata *cf = (struct cfdata *)vcf;
-
-       return strcmp(ia->ia_name, cf->cf_driver->cd_name) == 0;
-}
-
-void
-m41t8xclock_attach(struct device *parent, struct device *self, void *aux)
-{
-       struct m41t8xclock_softc *sc = (struct m41t8xclock_softc *)self;
-       struct i2c_attach_args *ia = (struct i2c_attach_args *)aux;
-
-       sc->sc_tag = ia->ia_tag;
-       sc->sc_addr = ia->ia_addr;
-
-       sc->sc_todr.cookie = sc;
-       sc->sc_todr.todr_gettime = m41t8xclock_gettime;
-       sc->sc_todr.todr_settime = m41t8xclock_settime;
-       todr_attach(&sc->sc_todr);
-
-       printf("\n");
-}
-
-int
-m41t8xclock_gettime(struct todr_chip_handle *handle, struct timeval *tv)
-{
-       struct clock_ymdhms dt;
-       struct m41t8xclock_softc *sc = handle->cookie;
-       uint8_t regno, data[M41T8X_TOD_LENGTH];
-       int s;
-
-       iic_acquire_bus(sc->sc_tag, 0);
-       s = splclock();
-       for (regno = M41T8X_TOD_START;
-           regno < M41T8X_TOD_START + M41T8X_TOD_LENGTH; regno++)
-               iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
-                   &regno, sizeof regno, data + regno - M41T8X_TOD_START,
-                   sizeof data[0], 0);
-       splx(s);
-       iic_release_bus(sc->sc_tag, 0);
-
-       dt.dt_sec = FROMBCD(data[M41T8X_SEC] & ~M41T8X_STOP);
-       dt.dt_min = FROMBCD(data[M41T8X_MIN]);
-       dt.dt_hour = FROMBCD(data[M41T8X_HR] & ~(M41T8X_CEB | M41T8X_CB));
-       dt.dt_day = FROMBCD(data[M41T8X_DAY]);
-       dt.dt_mon = FROMBCD(data[M41T8X_MON]);
-       dt.dt_year = FROMBCD(data[M41T8X_YEAR]) + 2000;
-       if (data[M41T8X_HR] & M41T8X_CB)
-               dt.dt_year += 100;
-
-       tv->tv_sec = clock_ymdhms_to_secs(&dt);
-       tv->tv_usec = 0;
-       return 0;
-}
-
-int
-m41t8xclock_settime(struct todr_chip_handle *handle, struct timeval *tv)
-{
-       struct clock_ymdhms dt;
-       struct m41t8xclock_softc *sc = handle->cookie;
-       uint8_t regno, data[M41T8X_TOD_LENGTH];
-       int s;
-
-       clock_secs_to_ymdhms(tv->tv_sec, &dt);
-
-       iic_acquire_bus(sc->sc_tag, 0);
-       s = splclock();
-       /* read current state */
-       for (regno = M41T8X_TOD_START;
-           regno < M41T8X_TOD_START + M41T8X_TOD_LENGTH; regno++)
-               iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
-                   &regno, sizeof regno, data + regno - M41T8X_TOD_START,
-                   sizeof data[0], 0);
-       /* compute new state */
-       data[M41T8X_HSEC] = 0;
-       data[M41T8X_SEC] = TOBCD(dt.dt_sec);
-       data[M41T8X_MIN] = TOBCD(dt.dt_min);
-       data[M41T8X_HR] &= M41T8X_CEB;
-       if (dt.dt_year >= 2100)
-               data[M41T8X_HR] |= M41T8X_CB;
-       data[M41T8X_HR] |= TOBCD(dt.dt_hour);
-       data[M41T8X_DOW] = TOBCD(dt.dt_wday + 1);
-       data[M41T8X_DAY] = TOBCD(dt.dt_day);
-       data[M41T8X_MON] = TOBCD(dt.dt_mon);
-       data[M41T8X_YEAR] = TOBCD(dt.dt_year % 100);
-       /* write new state */
-       for (regno = M41T8X_TOD_START;
-           regno < M41T8X_TOD_START + M41T8X_TOD_LENGTH; regno++)
-               iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
-                   &regno, sizeof regno, data + regno, sizeof data[0], 0);
-       splx(s);
-       iic_release_bus(sc->sc_tag, 0);
-
-       return 0;
-}
diff --git a/sys/dev/i2c/files.i2c b/sys/dev/i2c/files.i2c
index 2b6f0b0d027..5c43b182276 100644
--- a/sys/dev/i2c/files.i2c
+++ b/sys/dev/i2c/files.i2c
@@ -248,3 +248,8 @@ file dev/i2c/ipmi_i2c.c                             ipmi_i2c
 device mcprtc
 attach mcprtc at i2c
 file dev/i2c/mcp794xx.c                                mcprtc
+
+# STMicroelectronics M41T8x RTC
+device mfokrtc
+attach mfokrtc at i2c
+file   dev/i2c/m41t8x.c                        mfokrtc
diff --git a/sys/dev/i2c/m41t8x.c b/sys/dev/i2c/m41t8x.c
new file mode 100644
index 00000000000..74f6c37d353
--- /dev/null
+++ b/sys/dev/i2c/m41t8x.c
@@ -0,0 +1,153 @@
+/*     $OpenBSD: m41t8xrtc.c,v 1.4 2020/05/25 13:15:37 visa Exp $      */
+
+/*
+ * Copyright (c) 2010 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * M41T8x clock connected to an I2C bus
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/clock_subr.h>
+#include <dev/i2c/i2cvar.h>
+#include <dev/ic/m41t8xreg.h>
+
+struct m41t8xrtc_softc {
+       struct device           sc_dev;
+       struct todr_chip_handle sc_todr;
+       i2c_tag_t               sc_tag;
+       i2c_addr_t              sc_addr;
+};
+
+int    m41t8xrtc_match(struct device *, void *, void *);
+void   m41t8xrtc_attach(struct device *, struct device *, void *);
+
+const struct cfattach mfokrtc_ca = {
+       sizeof(struct m41t8xrtc_softc),
+       m41t8xrtc_match, m41t8xrtc_attach
+};
+
+struct cfdriver mfokrtc_cd = {
+       NULL, "mfokrtc", DV_DULL
+};
+
+int    m41t8xrtc_gettime(struct todr_chip_handle *, struct timeval *);
+int    m41t8xrtc_settime(struct todr_chip_handle *, struct timeval *);
+
+int
+m41t8xrtc_match(struct device *parent, void *vcf, void *aux)
+{
+       struct i2c_attach_args *ia = (struct i2c_attach_args *)aux;
+
+       if (strcmp(ia->ia_name, "st,m41t83") == 0)
+               return (1);
+       return (0);
+
+}
+
+void
+m41t8xrtc_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct m41t8xrtc_softc *sc = (struct m41t8xrtc_softc *)self;
+       struct i2c_attach_args *ia = (struct i2c_attach_args *)aux;
+
+       sc->sc_tag = ia->ia_tag;
+       sc->sc_addr = ia->ia_addr;
+
+       sc->sc_todr.cookie = sc;
+       sc->sc_todr.todr_gettime = m41t8xrtc_gettime;
+       sc->sc_todr.todr_settime = m41t8xrtc_settime;
+       todr_attach(&sc->sc_todr);
+
+       printf("\n");
+}
+
+int
+m41t8xrtc_gettime(struct todr_chip_handle *handle, struct timeval *tv)
+{
+       struct clock_ymdhms dt;
+       struct m41t8xrtc_softc *sc = handle->cookie;
+       uint8_t regno, data[M41T8X_TOD_LENGTH];
+       int s;
+
+       iic_acquire_bus(sc->sc_tag, 0);
+       s = splclock();
+       for (regno = M41T8X_TOD_START;
+           regno < M41T8X_TOD_START + M41T8X_TOD_LENGTH; regno++)
+               iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
+                   &regno, sizeof regno, data + regno - M41T8X_TOD_START,
+                   sizeof data[0], 0);
+       splx(s);
+       iic_release_bus(sc->sc_tag, 0);
+
+       dt.dt_sec = FROMBCD(data[M41T8X_SEC] & ~M41T8X_STOP);
+       dt.dt_min = FROMBCD(data[M41T8X_MIN]);
+       dt.dt_hour = FROMBCD(data[M41T8X_HR] & ~(M41T8X_CEB | M41T8X_CB));
+       dt.dt_day = FROMBCD(data[M41T8X_DAY]);
+       dt.dt_mon = FROMBCD(data[M41T8X_MON]);
+       dt.dt_year = FROMBCD(data[M41T8X_YEAR]) + 2000;
+       if (data[M41T8X_HR] & M41T8X_CB)
+               dt.dt_year += 100;
+
+       tv->tv_sec = clock_ymdhms_to_secs(&dt);
+       tv->tv_usec = 0;
+       return 0;
+}
+
+int
+m41t8xrtc_settime(struct todr_chip_handle *handle, struct timeval *tv)
+{
+       struct clock_ymdhms dt;
+       struct m41t8xrtc_softc *sc = handle->cookie;
+       uint8_t regno, data[M41T8X_TOD_LENGTH];
+       int s;
+
+       clock_secs_to_ymdhms(tv->tv_sec, &dt);
+
+       iic_acquire_bus(sc->sc_tag, 0);
+       s = splclock();
+       /* read current state */
+       for (regno = M41T8X_TOD_START;
+           regno < M41T8X_TOD_START + M41T8X_TOD_LENGTH; regno++)
+               iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
+                   &regno, sizeof regno, data + regno - M41T8X_TOD_START,
+                   sizeof data[0], 0);
+       /* compute new state */
+       data[M41T8X_HSEC] = 0;
+       data[M41T8X_SEC] = TOBCD(dt.dt_sec);
+       data[M41T8X_MIN] = TOBCD(dt.dt_min);
+       data[M41T8X_HR] &= M41T8X_CEB;
+       if (dt.dt_year >= 2100)
+               data[M41T8X_HR] |= M41T8X_CB;
+       data[M41T8X_HR] |= TOBCD(dt.dt_hour);
+       data[M41T8X_DOW] = TOBCD(dt.dt_wday + 1);
+       data[M41T8X_DAY] = TOBCD(dt.dt_day);
+       data[M41T8X_MON] = TOBCD(dt.dt_mon);
+       data[M41T8X_YEAR] = TOBCD(dt.dt_year % 100);
+       /* write new state */
+       for (regno = M41T8X_TOD_START;
+           regno < M41T8X_TOD_START + M41T8X_TOD_LENGTH; regno++)
+               iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
+                   &regno, sizeof regno, data + regno, sizeof data[0], 0);
+       splx(s);
+       iic_release_bus(sc->sc_tag, 0);
+
+       return 0;
+}

Reply via email to