... | ... | ||
---|---|---|---|
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 |