bcm27xx: import latest patches from the RPi foundation
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0945-rtc-rv3028-Refresh-RAM-on-EEPROM-write.patch
1 From 010b506d6b215673f188ed5cdc4e35419e3ea715 Mon Sep 17 00:00:00 2001
2 From: Einar Vading <einar.vading@rhimagnesita.com>
3 Date: Fri, 14 Aug 2020 22:14:41 +0200
4 Subject: [PATCH] rtc: rv3028: Refresh RAM on EEPROM write
5
6 The active RV3028 settings are in RAM so after modifying the settings in
7 EEPROM the RAM should be refreshed so that they take effect.
8
9 Signed-off-by: Einar Vading <einar.vading@rhimagnesita.com>
10 ---
11 drivers/rtc/rtc-rv3028.c | 56 ++++++++++++++++++++++++++++++++++++++++
12 1 file changed, 56 insertions(+)
13
14 --- a/drivers/rtc/rtc-rv3028.c
15 +++ b/drivers/rtc/rtc-rv3028.c
16 @@ -66,6 +66,7 @@
17
18 #define RV3028_EVT_CTRL_TSR BIT(2)
19
20 +#define RV3028_EEPROM_CMD_REFRESH 0x12
21 #define RV3028_EEPROM_CMD_WRITE 0x21
22 #define RV3028_EEPROM_CMD_READ 0x22
23
24 @@ -583,6 +584,58 @@ restore_eerd:
25 return ret;
26 }
27
28 +static int rv3028_ram_refresh(void *priv)
29 +{
30 + u32 status, ctrl1;
31 + int ret, err;
32 +
33 + ret = regmap_read(priv, RV3028_CTRL1, &ctrl1);
34 + if (ret)
35 + return ret;
36 +
37 + if (!(ctrl1 & RV3028_CTRL1_EERD)) {
38 + ret = regmap_update_bits(priv, RV3028_CTRL1,
39 + RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
40 + if (ret)
41 + return ret;
42 +
43 + ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
44 + !(status & RV3028_STATUS_EEBUSY),
45 + RV3028_EEBUSY_POLL,
46 + RV3028_EEBUSY_TIMEOUT);
47 + if (ret)
48 + goto restore_eerd;
49 + }
50 +
51 + ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0);
52 + if (ret)
53 + goto restore_eerd;
54 +
55 + ret = regmap_write(priv, RV3028_EEPROM_CMD,
56 + RV3028_EEPROM_CMD_REFRESH);
57 + if (ret)
58 + goto restore_eerd;
59 +
60 + usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
61 +
62 + ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
63 + !(status & RV3028_STATUS_EEBUSY),
64 + RV3028_EEBUSY_POLL,
65 + RV3028_EEBUSY_TIMEOUT);
66 + if (ret)
67 + goto restore_eerd;
68 +
69 +restore_eerd:
70 + if (!(ctrl1 & RV3028_CTRL1_EERD)) {
71 + err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
72 + 0);
73 + if (err && !ret)
74 + ret = err;
75 + }
76 +
77 + return ret;
78 +}
79 +
80 static struct rtc_class_ops rv3028_rtc_ops = {
81 .read_time = rv3028_get_time,
82 .set_time = rv3028_set_time,
83 @@ -723,6 +776,9 @@ static int rv3028_probe(struct i2c_clien
84 ret = rv3028_eeprom_write(
85 (void *)(rv3028->regmap),
86 RV3028_BACKUP, (void *)&backup, 1);
87 +
88 + if (!ret)
89 + ret = rv3028_ram_refresh((void *)(rv3028->regmap));
90 }
91 }
92