...
...
7
is accurate. This is following the procedure described in section
7
is accurate. This is following the procedure described in section
8
3.11 of "https://www.st.com/resource/en/datasheet/m41t62.pdf"
8
3.11 of "https://www.st.com/resource/en/datasheet/m41t62.pdf"
9
9
10
Signed-off-by: A. Niyas Ahamed Mydeen <nmydeen@mvista.com>
10
Signed-off-by: A. Niyas Ahamed Mydeen <nmydeen@mvista.com>
11
Reviewed-by: Corey Minyard <cminyard@mvista.com>
11
Reviewed-by: Corey Minyard <cminyard@mvista.com>
12
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
12
---
13
---
13
drivers/rtc/rtc-m41t80.c | 70 ++++++++++++++++++++++++++++------------
14
drivers/rtc/rtc-m41t80.c | 68 ++++++++++++++++++++++++++++------------
14
1 file changed, 49 insertions(+), 21 deletions(-)
15
1 file changed, 48 insertions(+), 20 deletions(-)
15
16
16
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
17
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/drivers/rtc/rtc-m41t80.c
19
--- a/drivers/rtc/rtc-m41t80.c
19
+++ b/drivers/rtc/rtc-m41t80.c
20
+++ b/drivers/rtc/rtc-m41t80.c
...
...
50
51
51
+    flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
52
+    flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
52
+    if (flags < 0)
53
+    if (flags < 0)
53
+        return flags;
54
+        return flags;
54
+    if (flags & M41T80_FLAGS_OF) {
55
+    if (flags & M41T80_FLAGS_OF) {
55
+        /* OF cannot be immediately reset: oscillator has to be restarted. */
56
+        dev_warn(&client->dev, "OF bit is still set, kickstarting clock.\n");
57
+        err = i2c_smbus_write_byte_data(client, M41T80_REG_SEC, M41T80_SEC_ST);
58
+        if (err < 0) {
59
+            dev_err(&client->dev, "Can't set ST bit\n");
60
+            return err;
61
+        }
62
+        err = i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
63
+                         flags & ~M41T80_SEC_ST);
64
+        if (err < 0) {
65
+            dev_err(&client->dev, "Can't clear ST bit\n");
66
+            return err;
67
+        }
68
+        /* oscillator must run for 4sec before we attempt to reset OF bit */
69
+        msleep(4000);
70
+        /* Clear the OF bit of Flags Register */
71
+        err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
72
+                    flags & ~M41T80_FLAGS_OF);
73
+        if (err < 0) {
74
+            dev_err(&client->dev, "Unable to write flags register\n");
75
+            return err;
76
+        }
77
+        flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
78
+        if (flags < 0)
79
+            return flags;
80
+        else if (flags & M41T80_FLAGS_OF) {
81
+            dev_err(&client->dev, "Can't clear the OF bit check battery\n");
82
+            return err;
83
+        }
84
+        /* add 4sec of oscillator stablize time otherwise we are behind 4sec */
56
+        /* add 4sec of oscillator stablize time otherwise we are behind 4sec */
85
+        time = rtc_tm_to_time64(&tm);
57
+        time = rtc_tm_to_time64(&tm);
86
+        rtc_time64_to_tm(time+4, &tm);
58
+        rtc_time64_to_tm(time + 4, &tm);
87
+    }
59
+    }
88
    buf[M41T80_REG_SSEC] = 0;
60
    buf[M41T80_REG_SSEC] = 0;
89
-    buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec);
61
-    buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec);
90
-    buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min);
62
-    buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min);
91
-    buf[M41T80_REG_HOUR] = bin2bcd(tm->tm_hour);
63
-    buf[M41T80_REG_HOUR] = bin2bcd(tm->tm_hour);
...
...
102
+    buf[M41T80_REG_WDAY] = tm.tm_wday;
74
+    buf[M41T80_REG_WDAY] = tm.tm_wday;
103
75
104
    /* If the square wave output is controlled in the weekday register */
76
    /* If the square wave output is controlled in the weekday register */
105
    if (clientdata->features & M41T80_FEATURE_SQ_ALT) {
77
    if (clientdata->features & M41T80_FEATURE_SQ_ALT) {
106
@@ -XXX,XX +XXX,XX @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
78
@@ -XXX,XX +XXX,XX @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
79
        dev_err(&client->dev, "Unable to write to date registers\n");
107
        return err;
80
        return err;
108
    }
81
    }
109
82
-
110
-    /* Clear the OF bit of Flags Register */
83
-    /* Clear the OF bit of Flags Register */
111
-    flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
84
-    flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
112
-    if (flags < 0)
85
-    if (flags < 0)
113
-        return flags;
86
-        return flags;
114
-
87
-
115
-    err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
88
-    err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
116
-                    flags & ~M41T80_FLAGS_OF);
89
-                    flags & ~M41T80_FLAGS_OF);
117
-    if (err < 0) {
90
-    if (err < 0) {
118
-        dev_err(&client->dev, "Unable to write flags register\n");
91
-        dev_err(&client->dev, "Unable to write flags register\n");
119
-        return err;
92
-        return err;
120
-    }
93
+    if (flags & M41T80_FLAGS_OF) {
121
-
94
+        /* OF cannot be immediately reset: oscillator has to be restarted. */
95
+        dev_warn(&client->dev, "OF bit is still set, kickstarting clock.\n");
96
+        err = i2c_smbus_write_byte_data(client, M41T80_REG_SEC, M41T80_SEC_ST);
97
+        if (err < 0) {
98
+            dev_err(&client->dev, "Can't set ST bit\n");
99
+            return err;
100
+        }
101
+        err = i2c_smbus_write_byte_data(client, M41T80_REG_SEC, flags & ~M41T80_SEC_ST);
102
+        if (err < 0) {
103
+            dev_err(&client->dev, "Can't clear ST bit\n");
104
+            return err;
105
+        }
106
+        /* oscillator must run for 4sec before we attempt to reset OF bit */
107
+        msleep(4000);
108
+        /* Clear the OF bit of Flags Register */
109
+        err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, flags & ~M41T80_FLAGS_OF);
110
+        if (err < 0) {
111
+            dev_err(&client->dev, "Unable to write flags register\n");
112
+            return err;
113
+        }
114
+        flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
115
+        if (flags < 0) {
116
+            return flags;
117
+        } else if (flags & M41T80_FLAGS_OF) {
118
+            dev_err(&client->dev, "Can't clear the OF bit check battery\n");
119
+            return err;
120
+        }
121
    }
122
122
    return err;
123
    return err;
123
}
124
125
--
124
--
126
2.34.1
125
2.34.1
diff view generated by jsdifflib