If the PCF2127/2129 loses power it needs some initialization to work correctly. A bootloader/firmware might do this. If not we should do this in the driver. Changes for v2: - make commit log and comments more clear - check if PORO was really disabled Philipp Rosenberger (2): rtc: pcf2127: Disable Power-On Reset Override rtc: pcf2127: Run a OTP refresh if not done before drivers/rtc/rtc-pcf2127.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) Interdiff against v1: diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index f012b989f2f2..ca56dba64e79 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -26,6 +26,7 @@ /* Control register 1 */ #define PCF2127_REG_CTRL1 0x00 +#define PCF2127_BIT_CTRL1_POR_OVRD BIT(3) #define PCF2127_BIT_CTRL1_TSF1 BIT(4) /* Control register 2 */ #define PCF2127_REG_CTRL2 0x01 @@ -616,18 +617,27 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, } /* - * Disable the Power-On Reset Override facility to start normal - * operation. If the operation should fail, just move on. The RTC should - * work fine, but functions like watchdog and alarm interrupts might - * not work. + * The "Power-On Reset Override" facility prevents the RTC to do a reset + * after power on. For normal operation the PORO must be disabled. */ - ret = regmap_clear_bits(pcf2127->regmap, PCF2127_REG_CTRL1, + regmap_clear_bits(pcf2127->regmap, PCF2127_REG_CTRL1, PCF2127_BIT_CTRL1_POR_OVRD); - if (ret) { + /* + * If the PORO can't be disabled, just move on. The RTC should + * work fine, but functions like watchdog and alarm interrupts might + * not work. There will be no interrupt generated on the interrupt pin. + */ + ret = regmap_test_bits(pcf2127->regmap, PCF2127_REG_CTRL1, PCF2127_BIT_CTRL1_POR_OVRD); + if (ret <= 0) { dev_err(dev, "%s: can't disable PORO (ctrl1).\n", __func__); dev_warn(dev, "Watchdog and alarm functions might not work properly\n"); } + /* + * Set the OTP refresh bit unconditionally. If an OTP refresh was + * already done the bit is already set and will not rerun the refresh + * operation. + */ ret = regmap_set_bits(pcf2127->regmap, PCF2127_REG_CLKOUT, PCF2127_BIT_CLKOUT_OTPR); if (ret < 0) { -- 2.29.2