Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 03 May 2026 19:11:56 +0000
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: d22051b18e9b - main - iicbus/rtc: Add driver for the Ricoh rs5c372 RTC
Message-ID:  <69f79dfc.3ce8c.5b950eca@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by jhibbits:

URL: https://cgit.FreeBSD.org/src/commit/?id=d22051b18e9b7512c5cf033d7b6eee2df03c985b

commit d22051b18e9b7512c5cf033d7b6eee2df03c985b
Author:     Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2026-04-22 02:15:02 +0000
Commit:     Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2026-05-03 19:09:28 +0000

    iicbus/rtc: Add driver for the Ricoh rs5c372 RTC
    
    This RTC chip supports 2 alarm timers in addition to RTC functionality,
    but this driver only supports the RTC at this time.
---
 sys/conf/files                    |   1 +
 sys/dev/iicbus/rtc/rs5c372a.c     | 182 ++++++++++++++++++++++++++++++++++++++
 sys/modules/i2c/Makefile          |   1 +
 sys/modules/i2c/rs5c372a/Makefile |  14 +++
 4 files changed, 198 insertions(+)

diff --git a/sys/conf/files b/sys/conf/files
index 2b4a453ca556..6804c9c81c69 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1858,6 +1858,7 @@ dev/iicbus/rtc/hym8563.c	optional hym8563 iicbus fdt
 dev/iicbus/rtc/isl12xx.c	optional isl12xx
 dev/iicbus/rtc/nxprtc.c		optional nxprtc | pcf8563
 dev/iicbus/rtc/pcf85063.c	optional pcf85063 iicbus fdt
+dev/iicbus/rtc/rs5c372a.c	optional rs5c372a iicbus fdt
 dev/iicbus/rtc/rtc8583.c	optional rtc8583
 dev/iicbus/rtc/rv3032.c		optional rv3032 iicbus fdt
 dev/iicbus/rtc/rx8803.c		optional rx8803 iicbus fdt
diff --git a/sys/dev/iicbus/rtc/rs5c372a.c b/sys/dev/iicbus/rtc/rs5c372a.c
new file mode 100644
index 000000000000..c5743e840d25
--- /dev/null
+++ b/sys/dev/iicbus/rtc/rs5c372a.c
@@ -0,0 +1,182 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2026 Justin Hibbits
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
+
+#include "clock_if.h"
+#include "iicbus_if.h"
+
+/*
+ * Driver for the Richo rs5c372a RTC.  The chip itself includes 2 alarm clocks
+ * in addition to the clock component, but this driver offers only the RTC
+ * component.
+ *
+ * Like many other RTCs, this reports the date and time in BCD.
+ *
+ * The `Hour' register uses bit 5 in a dual role:  In 24-hour time, it's a part
+ * of the first digit (0, 1, 2).  In 12-hour time it denotes PM, so 12PM is
+ * reported as 0x32, 1PM is 0x21, etc.
+ */
+#define	RS5C372_REG_SEC		0x0
+#define	RS5C372_REG_MIN		0x1
+#define	RS5C372_REG_HOUR	0x2
+#define	  HOUR_HR_M		  0x1f
+#define	  HOUR_PM		  0x20
+#define	RS5C372_REG_DOW		0x3
+#define	RS5C372_REG_DAY		0x4
+#define	RS5C372_REG_MON		0x5
+#define	RS5C372_REG_YEAR	0x6
+#define	RS5C372_REG_CTRL1	0xe
+#define	RS5C372_REG_CTRL2	0xf
+#define	  CTRL_PM		  0x20
+
+static struct ofw_compat_data compat_data[] = {
+	{ "ricoh,rs5c372a", 1 },
+	{ NULL, 0 }
+};
+
+static int
+rs5c372a_gettime(device_t dev, struct timespec *ts)
+{
+	struct bcd_clocktime ct = {};
+	uint8_t clock_regs[7];
+	int err;
+	uint8_t ctrl2;
+	bool is_12hr = true;
+
+	err = iicdev_readfrom(dev, RS5C372_REG_CTRL2, &ctrl2,
+	    sizeof(ctrl2), IIC_WAIT);
+	if (err != 0)
+		return (err);
+	err = iicdev_readfrom(dev, RS5C372_REG_SEC, clock_regs,
+	    sizeof(clock_regs), IIC_WAIT);
+	if (err != 0)
+		return (err);
+
+	if (ctrl2 & CTRL_PM)
+		is_12hr = false;
+	ct.sec = clock_regs[RS5C372_REG_SEC];
+	ct.min = clock_regs[RS5C372_REG_MIN];
+	ct.hour = clock_regs[RS5C372_REG_HOUR];
+	ct.dow = clock_regs[RS5C372_REG_DOW];
+	ct.day = clock_regs[RS5C372_REG_DAY];
+	ct.mon = clock_regs[RS5C372_REG_MON];
+	ct.year = clock_regs[RS5C372_REG_YEAR];
+
+	if (is_12hr) {
+		ct.ispm = ct.hour & HOUR_PM;
+		ct.hour &= HOUR_HR_M;
+	}
+	clock_bcd_to_ts(&ct, ts, ct.ispm);
+
+	return (0);
+}
+
+static int
+rs5c372a_settime(device_t dev, struct timespec *ts)
+{
+	struct bcd_clocktime ct;
+	uint8_t clock_regs[7];
+	uint8_t ctrl2;
+	int err;
+	bool is_12hr = true;
+
+	err = iicdev_readfrom(dev, RS5C372_REG_CTRL2, &ctrl2,
+	    sizeof(ctrl2), IIC_WAIT);
+	if (err != 0)
+		return (err);
+	if (ctrl2 & CTRL_PM)
+		is_12hr = false;
+	clock_ts_to_bcd(ts, &ct, is_12hr);
+	clock_regs[RS5C372_REG_SEC] = ct.sec;
+	clock_regs[RS5C372_REG_MIN] = ct.min;
+	clock_regs[RS5C372_REG_HOUR] = ct.hour;
+	clock_regs[RS5C372_REG_DAY] = ct.day;
+	clock_regs[RS5C372_REG_DOW] = ct.dow;
+	clock_regs[RS5C372_REG_MON] = ct.mon;
+	clock_regs[RS5C372_REG_YEAR] = ct.year & 0xff;
+
+	if (is_12hr) {
+		if (ct.ispm)
+			clock_regs[RS5C372_REG_HOUR] |= HOUR_PM;
+	}
+
+	err = iicdev_writeto(dev, RS5C372_REG_SEC, clock_regs,
+	    sizeof(clock_regs), IIC_WAIT);
+
+	return (err);
+}
+
+static int
+rs5c372a_probe(device_t dev)
+{
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+		return (ENXIO);
+
+	device_set_desc(dev, "Richo RS5C372A RTC");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+rs5c372a_attach(device_t dev)
+{
+
+	/* Register with 1s resolution */
+	clock_register(dev, 1000000);
+	clock_schedule(dev, 1);
+	return (0);
+}
+
+static device_method_t rs5c372a_methods[] = {
+	/* Device methods */
+	DEVMETHOD(device_probe,		rs5c372a_probe),
+	DEVMETHOD(device_attach,	rs5c372a_attach),
+
+	/* Clock methods */
+	DEVMETHOD(clock_gettime,	rs5c372a_gettime),
+	DEVMETHOD(clock_settime,	rs5c372a_settime),
+	DEVMETHOD_END
+};
+
+
+DEFINE_CLASS_0(rs5c372a, rs5c372a_driver, rs5c372a_methods, 0);
+DRIVER_MODULE(rs5c372a, iicbus, rs5c372a_driver, NULL, NULL);
+MODULE_VERSION(rs5c372a, 1);
+MODULE_DEPEND(rs5c372a, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
+IICBUS_FDT_PNP_INFO(compat_data);
diff --git a/sys/modules/i2c/Makefile b/sys/modules/i2c/Makefile
index 6561327abfca..ff4536694dfc 100644
--- a/sys/modules/i2c/Makefile
+++ b/sys/modules/i2c/Makefile
@@ -28,6 +28,7 @@ SUBDIR = \
 
 .if !empty(OPT_FDT)
 SUBDIR += hym8563 \
+	  rs5c372a \
 	  rv3032 \
 	  rx8803 \
 	  tca64xx \
diff --git a/sys/modules/i2c/rs5c372a/Makefile b/sys/modules/i2c/rs5c372a/Makefile
new file mode 100644
index 000000000000..3bd387115a8a
--- /dev/null
+++ b/sys/modules/i2c/rs5c372a/Makefile
@@ -0,0 +1,14 @@
+.PATH:	${SRCTOP}/sys/dev/iicbus/rtc/
+KMOD	= rs5c372a
+SRCS	= rs5c372a.c
+
+# Generated files...
+SRCS+=	\
+	bus_if.h \
+	clock_if.h \
+	device_if.h \
+	iicbus_if.h \
+	opt_platform.h \
+	ofw_bus_if.h \
+
+.include <bsd.kmod.mk>


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f79dfc.3ce8c.5b950eca>