In the PCF2131 power management the battery switch-over function is disabled by default. After a power cycle the rtc clock is wrong because of that. Add a device-tree property to configure the power management function and enable battery switch-over. Signed-off-by: Markus Burri <markus.burri@xxxxxx> --- .../devicetree/bindings/rtc/nxp,pcf2127.yaml | 3 +++ drivers/rtc/rtc-pcf2127.c | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml b/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml index 2d9fe5a75b06..5ce0ca6dcedc 100644 --- a/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml +++ b/Documentation/devicetree/bindings/rtc/nxp,pcf2127.yaml @@ -30,6 +30,9 @@ properties: reset-source: true + pwrmng-function: + description: Set power management function for PCF2131 + required: - compatible - reg diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 9c04c4e1a49c..30d56538c11e 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -48,6 +48,7 @@ #define PCF2127_BIT_CTRL3_BLF BIT(2) #define PCF2127_BIT_CTRL3_BF BIT(3) #define PCF2127_BIT_CTRL3_BTSE BIT(4) +#define PCF2131_BIT_CTRL3_PWRMNG_MASK GENMASK(7, 5) /* Time and date registers */ #define PCF2127_REG_TIME_BASE 0x03 #define PCF2127_BIT_SC_OSF BIT(7) @@ -187,6 +188,7 @@ struct pcf21xx_config { unsigned int has_bit_wd_ctl_cd0:1; unsigned int wd_val_reg_readable:1; /* If watchdog value register can be read. */ unsigned int has_int_a_b:1; /* PCF2131 supports two interrupt outputs. */ + unsigned int has_pwrmng:1; /* PCF2131 supports power management. */ u8 reg_time_base; /* Time/date base register. */ u8 regs_alarm_base; /* Alarm function base registers. */ u8 reg_wd_ctl; /* Watchdog control register. */ @@ -926,6 +928,7 @@ static struct pcf21xx_config pcf21xx_cfg[] = { .has_bit_wd_ctl_cd0 = 1, .wd_val_reg_readable = 1, .has_int_a_b = 0, + .has_pwrmng = 0, .reg_time_base = PCF2127_REG_TIME_BASE, .regs_alarm_base = PCF2127_REG_ALARM_BASE, .reg_wd_ctl = PCF2127_REG_WD_CTL, @@ -954,6 +957,7 @@ static struct pcf21xx_config pcf21xx_cfg[] = { .has_bit_wd_ctl_cd0 = 0, .wd_val_reg_readable = 1, .has_int_a_b = 0, + .has_pwrmng = 0, .reg_time_base = PCF2127_REG_TIME_BASE, .regs_alarm_base = PCF2127_REG_ALARM_BASE, .reg_wd_ctl = PCF2127_REG_WD_CTL, @@ -982,6 +986,7 @@ static struct pcf21xx_config pcf21xx_cfg[] = { .has_bit_wd_ctl_cd0 = 0, .wd_val_reg_readable = 0, .has_int_a_b = 1, + .has_pwrmng = 1, .reg_time_base = PCF2131_REG_TIME_BASE, .regs_alarm_base = PCF2131_REG_ALARM_BASE, .reg_wd_ctl = PCF2131_REG_WD_CTL, @@ -1241,6 +1246,23 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, return ret; } + if (pcf2127->cfg->has_pwrmng) { + uint32_t pwrmng; + if (!device_property_read_u32(dev, "pwrmng-function", &pwrmng)) { + if (!FIELD_FIT(PCF2131_BIT_CTRL3_PWRMNG_MASK, pwrmng)) { + dev_err(dev, "invalid power management function\n"); + return ret; + } + ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3, + PCF2131_BIT_CTRL3_PWRMNG_MASK, + FIELD_PREP(PCF2131_BIT_CTRL3_PWRMNG_MASK, pwrmng)); + if (ret) { + dev_err(dev, "%s: pwrmng (ctrl3) failed\n", __func__); + return ret; + } + } + } + /* * Enable timestamp functions 1 to 4. */ -- 2.39.2