git: 3662b8f1cf77 - main - pcf85063: Fix real time clock

From: Wojciech Macek <wma_at_FreeBSD.org>
Date: Fri, 10 Dec 2021 16:09:38 UTC
The branch main has been updated by wma:

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

commit 3662b8f1cf7729853f77125af7ad4c822c285eee
Author:     Hubert Mazur <hum@semihalf.com>
AuthorDate: 2021-12-10 15:07:25 +0000
Commit:     Wojciech Macek <wma@FreeBSD.org>
CommitDate: 2021-12-10 16:09:29 +0000

    pcf85063: Fix real time clock
    
    Previosuly real time clock driver always set time format to 12-hour
    mode. Fix this by choosing hour mode depending on HW register.
---
 sys/dev/iicbus/rtc/pcf85063.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/sys/dev/iicbus/rtc/pcf85063.c b/sys/dev/iicbus/rtc/pcf85063.c
index f3038ac32340..dad52239f061 100644
--- a/sys/dev/iicbus/rtc/pcf85063.c
+++ b/sys/dev/iicbus/rtc/pcf85063.c
@@ -147,14 +147,17 @@ pcf85063_get_time(device_t dev, struct timespec *ts)
 	bcd.nsec = 0;
 	bcd.sec = data.sec & 0x7F;
 	bcd.min = data.min & 0x7F;
-	bcd.ispm = data.hour & 0x20;
 
-	if (control_reg & PCF85063_CTRL1_TIME_FORMAT)
+	if (control_reg & PCF85063_CTRL1_TIME_FORMAT) {
 		/* 12 hour mode */
 		bcd.hour = data.hour & 0x1F;
-	 else
+		/* Check if hour is pm */
+		bcd.ispm = data.hour & 0x20;
+	} else {
 		/* 24 hour mode */
 		bcd.hour = data.hour & 0x3F;
+		bcd.ispm = false;
+	}
 
 	bcd.dow = (data.dow & 0x7) + 1;
 	bcd.day = data.day & 0x3F;
@@ -162,7 +165,8 @@ pcf85063_get_time(device_t dev, struct timespec *ts)
 	bcd.year = data.year;
 
 	clock_dbgprint_bcd(dev, CLOCK_DBG_READ, &bcd);
-	error = clock_bcd_to_ts(&bcd, ts, true);
+	error = clock_bcd_to_ts(&bcd, ts,
+	    control_reg & PCF85063_CTRL1_TIME_FORMAT);
 
 	return (error);
 }
@@ -175,8 +179,11 @@ pcf85063_set_time(device_t dev, struct timespec *ts)
 	struct bcd_clocktime bcd;
 	int error;
 
+	error = iicdev_readfrom(dev, PCF85063_TIME_REG, &ctrl_reg,
+	    sizeof(uint8_t), IIC_WAIT);
+
 	ts->tv_sec -= utc_offset();
-	clock_ts_to_bcd(ts, &bcd, true);
+	clock_ts_to_bcd(ts, &bcd, ctrl_reg & PCF85063_CTRL1_TIME_FORMAT);
 	clock_dbgprint_bcd(dev, CLOCK_DBG_WRITE, &bcd);
 
 	data.sec = bcd.sec;
@@ -187,6 +194,11 @@ pcf85063_set_time(device_t dev, struct timespec *ts)
 	data.mon = bcd.mon;
 	data.year = bcd.year;
 
+	/* Set this bit in case of 12-hour mode and pm hour. */
+	if (!(ctrl_reg & PCF85063_CTRL1_TIME_FORMAT))
+		if (bcd.ispm)
+			data.hour |= 0x20;
+
 	if (ts->tv_nsec > PCF85063_HALF_OF_SEC_NS)
 		data.sec++;