[PATCH v4 4/6] rtc: s35390a: force 24-hour mode
Markus Probst <[email protected]>
| Newsgroups | org.kernel.vger.linux-rtc,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-gpio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Instead of trying to remember the current 12/24-hour mode, which could result in time corruption if out of sync, we force the use of the 24-hour mode. Set to 24-hour mode if in 12-hour mode on startup and assume 24-hour mode. The 24-hour mode is already forced on reset. Signed-off-by: Markus Probst <[email protected]> --- drivers/rtc/rtc-s35390a.c | 47 +++++++++++------------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 575bb256eb25..4d7fecfbe38e 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -64,7 +64,6 @@ MODULE_DEVICE_TABLE(of, s35390a_of_match); struct s35390a { struct i2c_client *client[8]; - int twentyfourhour; }; static int s35390a_set_reg(struct s35390a *s35390a, int reg, u8 *buf, int len) @@ -181,31 +180,6 @@ static int s35390a_disable_test_mode(struct s35390a *s35390a) return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)); } -static char s35390a_hr2reg(struct s35390a *s35390a, int hour) -{ - if (s35390a->twentyfourhour) - return bin2bcd(hour); - - if (hour < 12) - return bin2bcd(hour); - - return 0x40 | bin2bcd(hour - 12); -} - -static int s35390a_reg2hr(struct s35390a *s35390a, char reg) -{ - unsigned hour; - - if (s35390a->twentyfourhour) - return bcd2bin(reg & 0x3f); - - hour = bcd2bin(reg & 0x3f); - if (reg & 0x40) - hour += 12; - - return hour; -} - static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct i2c_client *client = to_i2c_client(dev); @@ -225,7 +199,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) buf[S35390A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1); buf[S35390A_BYTE_DAY] = bin2bcd(tm->tm_mday); buf[S35390A_BYTE_WDAY] = bin2bcd(tm->tm_wday); - buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour); + buf[S35390A_BYTE_HOURS] = bin2bcd(tm->tm_hour); buf[S35390A_BYTE_MINS] = bin2bcd(tm->tm_min); buf[S35390A_BYTE_SECS] = bin2bcd(tm->tm_sec); @@ -256,7 +230,7 @@ static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_sec = bcd2bin(buf[S35390A_BYTE_SECS]); tm->tm_min = bcd2bin(buf[S35390A_BYTE_MINS]); - tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]); + tm->tm_hour = bcd2bin(buf[S35390A_BYTE_HOURS] & 0x3f); tm->tm_wday = bcd2bin(buf[S35390A_BYTE_WDAY]); tm->tm_mday = bcd2bin(buf[S35390A_BYTE_DAY]); tm->tm_mon = bcd2bin(buf[S35390A_BYTE_MONTH]) - 1; @@ -325,8 +299,7 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) else buf[S35390A_ALRM_BYTE_WDAY] = 0; - buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, - alm->time.tm_hour) | 0x80; + buf[S35390A_ALRM_BYTE_HOURS] = bin2bcd(alm->time.tm_hour) | 0x80; buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80; if (alm->time.tm_hour >= 12) @@ -381,8 +354,7 @@ static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) if (buf[S35390A_ALRM_BYTE_HOURS] & 0x80) alm->time.tm_hour = - s35390a_reg2hr(s35390a, - buf[S35390A_ALRM_BYTE_HOURS] & ~0x80); + bcd2bin(buf[S35390A_ALRM_BYTE_HOURS] & 0x3f); if (buf[S35390A_ALRM_BYTE_MINS] & 0x80) alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS] & ~0x80); @@ -503,10 +475,13 @@ static int s35390a_probe(struct i2c_client *client) return err_read; } - if (status1 & S35390A_FLAG_24H) - s35390a->twentyfourhour = 1; - else - s35390a->twentyfourhour = 0; + if (!(status1 & S35390A_FLAG_24H)) { + status1 |= S35390A_FLAG_24H; + + err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &status1, sizeof(status1)); + if (err < 0) + return dev_err_probe(dev, err, "setting 24-hour mode failed\n"); + } if (status1 & S35390A_FLAG_INT2) { /* disable alarm (and maybe test mode) */ -- 2.54.0