Commit 71af9156 authored by Mathew McBride's avatar Mathew McBride Committed by Alexandre Belloni

rtc: rx8025: fix 12/24 hour mode detection on RX-8035

The 12/24hr flag in the RX-8035 can be found in the hour register,
instead of the CTRL1 on the RX-8025. This was overlooked when
support for the RX-8035 was added, and was causing read errors when
the hour register 'overflowed'.

To deal with the relevant register not always being visible in
the relevant functions, determine the 12/24 mode at startup and
store it in the driver state.
Signed-off-by: default avatarMathew McBride <matt@traverse.com.au>
Fixes: f120e2e3 ("rtc: rx8025: implement RX-8035 support")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20220706074236.24011-1-matt@traverse.com.au
parent 5c9f4144
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#define RX8025_BIT_CTRL2_XST BIT(5) #define RX8025_BIT_CTRL2_XST BIT(5)
#define RX8025_BIT_CTRL2_VDET BIT(6) #define RX8025_BIT_CTRL2_VDET BIT(6)
#define RX8035_BIT_HOUR_1224 BIT(7)
/* Clock precision adjustment */ /* Clock precision adjustment */
#define RX8025_ADJ_RESOLUTION 3050 /* in ppb */ #define RX8025_ADJ_RESOLUTION 3050 /* in ppb */
#define RX8025_ADJ_DATA_MAX 62 #define RX8025_ADJ_DATA_MAX 62
...@@ -78,6 +80,7 @@ struct rx8025_data { ...@@ -78,6 +80,7 @@ struct rx8025_data {
struct rtc_device *rtc; struct rtc_device *rtc;
enum rx_model model; enum rx_model model;
u8 ctrl1; u8 ctrl1;
int is_24;
}; };
static s32 rx8025_read_reg(const struct i2c_client *client, u8 number) static s32 rx8025_read_reg(const struct i2c_client *client, u8 number)
...@@ -226,7 +229,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt) ...@@ -226,7 +229,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f); dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f);
dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f); dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f);
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) if (rx8025->is_24)
dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f); dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f);
else else
dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x1f) % 12 dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x1f) % 12
...@@ -254,7 +257,7 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt) ...@@ -254,7 +257,7 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
*/ */
date[RX8025_REG_SEC] = bin2bcd(dt->tm_sec); date[RX8025_REG_SEC] = bin2bcd(dt->tm_sec);
date[RX8025_REG_MIN] = bin2bcd(dt->tm_min); date[RX8025_REG_MIN] = bin2bcd(dt->tm_min);
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) if (rx8025->is_24)
date[RX8025_REG_HOUR] = bin2bcd(dt->tm_hour); date[RX8025_REG_HOUR] = bin2bcd(dt->tm_hour);
else else
date[RX8025_REG_HOUR] = (dt->tm_hour >= 12 ? 0x20 : 0) date[RX8025_REG_HOUR] = (dt->tm_hour >= 12 ? 0x20 : 0)
...@@ -279,6 +282,7 @@ static int rx8025_init_client(struct i2c_client *client) ...@@ -279,6 +282,7 @@ static int rx8025_init_client(struct i2c_client *client)
struct rx8025_data *rx8025 = i2c_get_clientdata(client); struct rx8025_data *rx8025 = i2c_get_clientdata(client);
u8 ctrl[2], ctrl2; u8 ctrl[2], ctrl2;
int need_clear = 0; int need_clear = 0;
int hour_reg;
int err; int err;
err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl); err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl);
...@@ -303,6 +307,16 @@ static int rx8025_init_client(struct i2c_client *client) ...@@ -303,6 +307,16 @@ static int rx8025_init_client(struct i2c_client *client)
err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2); err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);
} }
if (rx8025->model == model_rx_8035) {
/* In RX-8035, 12/24 flag is in the hour register */
hour_reg = rx8025_read_reg(client, RX8025_REG_HOUR);
if (hour_reg < 0)
return hour_reg;
rx8025->is_24 = (hour_reg & RX8035_BIT_HOUR_1224);
} else {
rx8025->is_24 = (ctrl[1] & RX8025_BIT_CTRL1_1224);
}
out: out:
return err; return err;
} }
...@@ -329,7 +343,7 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -329,7 +343,7 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
/* Hardware alarms precision is 1 minute! */ /* Hardware alarms precision is 1 minute! */
t->time.tm_sec = 0; t->time.tm_sec = 0;
t->time.tm_min = bcd2bin(ald[0] & 0x7f); t->time.tm_min = bcd2bin(ald[0] & 0x7f);
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) if (rx8025->is_24)
t->time.tm_hour = bcd2bin(ald[1] & 0x3f); t->time.tm_hour = bcd2bin(ald[1] & 0x3f);
else else
t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12
...@@ -350,7 +364,7 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -350,7 +364,7 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
int err; int err;
ald[0] = bin2bcd(t->time.tm_min); ald[0] = bin2bcd(t->time.tm_min);
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) if (rx8025->is_24)
ald[1] = bin2bcd(t->time.tm_hour); ald[1] = bin2bcd(t->time.tm_hour);
else else
ald[1] = (t->time.tm_hour >= 12 ? 0x20 : 0) ald[1] = (t->time.tm_hour >= 12 ? 0x20 : 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment