aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch92
1 files changed, 92 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch b/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch
new file mode 100644
index 0000000000..94e3038c8a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch
@@ -0,0 +1,92 @@
+From 010b506d6b215673f188ed5cdc4e35419e3ea715 Mon Sep 17 00:00:00 2001
+From: Einar Vading <einar.vading@rhimagnesita.com>
+Date: Fri, 14 Aug 2020 22:14:41 +0200
+Subject: [PATCH] rtc: rv3028: Refresh RAM on EEPROM write
+
+The active RV3028 settings are in RAM so after modifying the settings in
+EEPROM the RAM should be refreshed so that they take effect.
+
+Signed-off-by: Einar Vading <einar.vading@rhimagnesita.com>
+---
+ drivers/rtc/rtc-rv3028.c | 56 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/drivers/rtc/rtc-rv3028.c
++++ b/drivers/rtc/rtc-rv3028.c
+@@ -66,6 +66,7 @@
+
+ #define RV3028_EVT_CTRL_TSR BIT(2)
+
++#define RV3028_EEPROM_CMD_REFRESH 0x12
+ #define RV3028_EEPROM_CMD_WRITE 0x21
+ #define RV3028_EEPROM_CMD_READ 0x22
+
+@@ -583,6 +584,58 @@ restore_eerd:
+ return ret;
+ }
+
++static int rv3028_ram_refresh(void *priv)
++{
++ u32 status, ctrl1;
++ int ret, err;
++
++ ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
++ if (ret)
++ return ret;
++
++ if (!(ctrl1 & RV3028_CTRL1_EERD)) {
++ ret = regmap_update_bits(priv, RV3028_CTRL1,
++ RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
++ if (ret)
++ return ret;
++
++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
++ !(status & RV3028_STATUS_EEBUSY),
++ RV3028_EEBUSY_POLL,
++ RV3028_EEBUSY_TIMEOUT);
++ if (ret)
++ goto restore_eerd;
++ }
++
++ ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
++ if (ret)
++ goto restore_eerd;
++
++ ret = regmap_write(priv, RV3028_EEPROM_CMD,
++ RV3028_EEPROM_CMD_REFRESH);
++ if (ret)
++ goto restore_eerd;
++
++ usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
++
++ ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
++ !(status & RV3028_STATUS_EEBUSY),
++ RV3028_EEBUSY_POLL,
++ RV3028_EEBUSY_TIMEOUT);
++ if (ret)
++ goto restore_eerd;
++
++restore_eerd:
++ if (!(ctrl1 & RV3028_CTRL1_EERD)) {
++ err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
++ 0);
++ if (err && !ret)
++ ret = err;
++ }
++
++ return ret;
++}
++
+ static struct rtc_class_ops rv3028_rtc_ops = {
+ .read_time = rv3028_get_time,
+ .set_time = rv3028_set_time,
+@@ -723,6 +776,9 @@ static int rv3028_probe(struct i2c_clien
+ ret = rv3028_eeprom_write(
+ (void *)(rv3028->regmap),
+ RV3028_BACKUP, (void *)&backup, 1);
++
++ if (!ret)
++ ret = rv3028_ram_refresh((void *)(rv3028->regmap));
+ }
+ }
+