1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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));
}
}
|