🐈

PetalinuxでRX-8025SAを組み合わせたときの話

2025/02/04に公開

petalinuxでリアルタイムクロックのRX-8025SAを使用しようとしたところlinuxのdriverの挙動がおかしく

JSTの9時から21時の間に起動すると正常に動作するけどそれ以外の時間だと時間が意図しない値になるのが分かりました

RX-8025SAは時間を12時で表記するか24時で表記するかを選択できるのですが、現行のdriverでは12時モードで動作するようですが、12時表記の場合にまともに動かないコードになっていました
(詳しく調べたら、12時/24時のどちらで動いているかを示すフラグの取得位置もおかしいかったのですが)

とりあえず12時/24時のどちらで動いているかを示すフラグの取得位置を修正と、24時表記で動作するように変更しました

パッチファイルはこんな感じ

diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index aabe62c283a1..403b789100ba 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -238,7 +238,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
 
 	dt->tm_mday = bcd2bin(date[RX8025_REG_MDAY] & 0x3f);
 	dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1;
-	dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100;
+	dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100 + ( (date[RX8025_REG_MONTH] & 0x80) ? 100 : 0);
 
 	dev_dbg(dev, "%s: date %ptRr\n", __func__, dt);
 
@@ -250,8 +250,25 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct rx8025_data *rx8025 = dev_get_drvdata(dev);
 	u8 date[7];
+	u8 ctrl[2], ctrl1;
 	int ret;
+	int err;
 
+	if( rx8025->is_24 == 0)
+	{
+		dev_warn(&client->dev, "CTRL1_1224 set to 1\n");
+		err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl);
+		if (err)
+			return err;
+		/* Keep test bit zero ! */
+		rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST;
+		ctrl1 |= RX8025_BIT_CTRL1_1224; // set 24-hour mode
+		err = rx8025_write_reg(client, RX8025_REG_CTRL1, ctrl1);
+		if (err)
+			return err;
+		rx8025->is_24 = 1;
+		rx8025->ctrl1 = ctrl1;
+	}
 	/*
 	 * Here the read-only bits are written as "0".  I'm not sure if that
 	 * is sound.
@@ -316,8 +333,9 @@ static int rx8025_init_client(struct i2c_client *client)
 			return hour_reg;
 		rx8025->is_24 = (hour_reg & RX8035_BIT_HOUR_1224);
 	} else {
-		rx8025->is_24 = (ctrl[1] & RX8025_BIT_CTRL1_1224);
+		rx8025->is_24 = (ctrl[0] & RX8025_BIT_CTRL1_1224);
 	}
+	dev_warn(&client->dev, "CTRL1_1224:%d\n", rx8025->is_24);
 out:
 	return err;
 }

Discussion