Property "trickle-resistor-ohms" allows us to set trickle charger resistor. However there is no possibility to disable it afterwards. >From now on, disable trickle charger circuit in case device-tree property "trickle-resistor-ohms" is not present. RV3029 RTC driver uses the same trickle charger disable logic. Additionally, lets make sure we only update internal EEPROM in case of a change. This prevents wear due to excessive EEPROM writes on each probe. Signed-off-by: Andrej Picej <andrej.picej@xxxxxxxxx> --- drivers/rtc/rtc-rv3028.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index ec5d7a614e2d..190507bf97d0 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -860,6 +860,7 @@ static int rv3028_probe(struct i2c_client *client) struct rv3028_data *rv3028; int ret, status; u32 ohms; + int val_old, val; struct nvmem_config nvmem_cfg = { .name = "rv3028_nvram", .word_size = 1, @@ -937,9 +938,18 @@ static int rv3028_probe(struct i2c_client *client) if (ret) return ret; + ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &val_old); + if (ret < 0) + return ret; + + /* mask out only trickle charger bits */ + val_old = val_old & (RV3028_BACKUP_TCE | RV3028_BACKUP_TCR_MASK); + /* setup trickle charger */ - if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", - &ohms)) { + if (device_property_read_u32(&client->dev, "trickle-resistor-ohms", &ohms)) { + /* disable the trickle charger */ + val = 0; + } else { int i; for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) @@ -947,15 +957,21 @@ static int rv3028_probe(struct i2c_client *client) break; if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { - ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE | - RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i); - if (ret) - return ret; + /* enable the trickle charger and setup its resistor accordingly */ + val = RV3028_BACKUP_TCE | i; } else { dev_warn(&client->dev, "invalid trickle resistor value\n"); } } + /* only update EEPROM if changes are necessary */ + if (val_old != val) { + ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE | + RV3028_BACKUP_TCR_MASK, val); + if (ret) + return ret; + } + ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); if (ret) return ret; -- 2.25.1