[PATCH] squash! drivers: rtc: add max313xx series rtc driver

From: Chris Packham
Date: Sun Apr 23 2023 - 20:10:40 EST


This is intended to be squashed into [1] for the next round. It deals
with reporting that there has been an oscillator fail and releasing the
SWRST on chips that require it.

I'm not sure what the requirements are for patches like this so I've
included my sign-off in case it's needed but feel free to drop it if
it's not needed.

Signed-off-by: Chris Packham <chris.packham@xxxxxxxxxxxxxxxxxxx>

[1] - https://lore.kernel.org/all/20230403154342.3108-2-Ibrahim.Tilki@xxxxxxxxxx/
---
drivers/rtc/rtc-max313xx.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)

diff --git a/drivers/rtc/rtc-max313xx.c b/drivers/rtc/rtc-max313xx.c
index 043528d7d3e0..a7028b901358 100644
--- a/drivers/rtc/rtc-max313xx.c
+++ b/drivers/rtc/rtc-max313xx.c
@@ -81,6 +81,7 @@ struct chip_desc {

u8 int_en_reg;
u8 int_status_reg;
+ u8 osf_bit;

u8 ram_reg;
u8 ram_size;
@@ -88,6 +89,9 @@ struct chip_desc {
u8 temp_reg;

u8 trickle_reg;
+
+ u8 rst_reg;
+ u8 rst_bit;
};

#define clk_hw_to_max313xx(_hw) container_of(_hw, struct max313xx, clkout)
@@ -156,6 +160,7 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
[ID_MAX31328] = {
.int_en_reg = 0x0E,
.int_status_reg = 0x0F,
+ .osf_bit = BIT(7),
.sec_reg = 0x00,
.alarm1_sec_reg = 0x07,
.temp_reg = 0x11,
@@ -165,6 +170,7 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
[ID_MAX31329] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
+ .osf_bit = BIT(6),
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.ram_reg = 0x22,
@@ -172,10 +178,13 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
.trickle_reg = 0x19,
.clkout = &max31329_clkout,
.clkout_name = "max31329-clkout",
+ .rst_reg = 0x02,
+ .rst_bit = BIT(0),
},
[ID_MAX31331] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
+ .osf_bit = BIT(6),
.sec_reg = 0x08,
.alarm1_sec_reg = 0x0F,
.ram_reg = 0x20,
@@ -183,10 +192,13 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
.trickle_reg = 0x1B,
.clkout = &max3133x_clkout,
.clkout_name = "max31331-clkout",
+ .rst_reg = 0x02,
+ .rst_bit = BIT(0),
},
[ID_MAX31334] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
+ .osf_bit = BIT(6),
.sec_reg = 0x09,
.alarm1_sec_reg = 0x10,
.ram_reg = 0x30,
@@ -194,10 +206,13 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
.trickle_reg = 0x1E,
.clkout = &max3133x_clkout,
.clkout_name = "max31334-clkout",
+ .rst_reg = 0x02,
+ .rst_bit = BIT(0),
},
[ID_MAX31341] = {
.int_en_reg = 0x04,
.int_status_reg = 0x05,
+ .osf_bit = BIT(6),
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.ram_reg = 0x16,
@@ -205,18 +220,24 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
.trickle_reg = 0x57,
.clkout = &max31341_42_clkout,
.clkout_name = "max31341-clkout",
+ .rst_reg = 0x00,
+ .rst_bit = BIT(0),
},
[ID_MAX31342] = {
.int_en_reg = 0x04,
.int_status_reg = 0x05,
+ .osf_bit = BIT(6),
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.clkout = &max31341_42_clkout,
.clkout_name = "max31342-clkout",
+ .rst_reg = 0x00,
+ .rst_bit = BIT(0),
},
[ID_MAX31343] = {
.int_en_reg = 0x01,
.int_status_reg = 0x00,
+ .osf_bit = BIT(6),
.sec_reg = 0x06,
.alarm1_sec_reg = 0x0D,
.ram_reg = 0x22,
@@ -225,6 +246,8 @@ static const struct chip_desc chip[MAX313XX_ID_NR] = {
.trickle_reg = 0x19,
.clkout = &max31343_clkout,
.clkout_name = "max31343-clko",
+ .rst_reg = 0x02,
+ .rst_bit = BIT(0),
},
};

@@ -279,6 +302,14 @@ static int max313xx_read_time(struct device *dev, struct rtc_time *t)
struct max313xx *rtc = dev_get_drvdata(dev);
u8 regs[7];
int ret;
+ unsigned int status;
+
+ ret = regmap_read(rtc->regmap, rtc->chip->int_status_reg, &status);
+ if (ret)
+ return ret;
+
+ if (status & rtc->chip->osf_bit)
+ return -EINVAL;

ret = regmap_bulk_read(rtc->regmap, rtc->chip->sec_reg, regs, 7);
if (ret)
@@ -368,6 +399,12 @@ static int max313xx_set_time(struct device *dev, struct rtc_time *t)
if (ret)
return ret;

+ if (rtc->chip->rst_bit) {
+ ret = regmap_clear_bits(rtc->regmap, rtc->chip->rst_reg, rtc->chip->rst_bit);
+ if (ret)
+ return ret;
+ }
+
ret = regmap_bulk_write(rtc->regmap, rtc->chip->sec_reg, regs, 7);
if (ret)
return ret;
--
2.40.0