diff mbox series

squash! drivers: rtc: add max313xx series rtc driver

Message ID 20230424001021.687057-1-chris.packham@alliedtelesis.co.nz
State Not Applicable
Headers show
Series squash! drivers: rtc: add max313xx series rtc driver | expand

Commit Message

Chris Packham April 24, 2023, 12:10 a.m. UTC
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@alliedtelesis.co.nz>

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

Patch

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;