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 set to -1. 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> --- Changes in v2: - disable trickle charger if device tree property trickle-resistor-ohms is set to -1. --- drivers/rtc/rtc-rv3028.c | 45 +++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-rv3028.c b/drivers/rtc/rtc-rv3028.c index ec5d7a614e2d..da2ae81fe7c8 100644 --- a/drivers/rtc/rtc-rv3028.c +++ b/drivers/rtc/rtc-rv3028.c @@ -859,7 +859,8 @@ static int rv3028_probe(struct i2c_client *client) { struct rv3028_data *rv3028; int ret, status; - u32 ohms; + s32 ohms; + int val_old, val; struct nvmem_config nvmem_cfg = { .name = "rv3028_nvram", .word_size = 1, @@ -937,22 +938,42 @@ static int rv3028_probe(struct i2c_client *client) if (ret) return ret; - /* setup trickle charger */ - if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", - &ohms)) { - int i; + 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); - for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) - if (ohms == rv3028_trickle_resistors[i]) - break; + /* setup trickle charger */ + if (!of_property_read_s32(client->dev.of_node, "trickle-resistor-ohms", + &ohms)) { + /* disable trickle charger if trickle-resistor-ohms = <(-1)>; */ + if (ohms == -1) { + val = val_old & ~RV3028_BACKUP_TCE; + } else { + int i; + + for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) + if (ohms == rv3028_trickle_resistors[i]) + break; + + if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { + /* enable trickle charger and its resistor */ + val = RV3028_BACKUP_TCE | i; + } else { + dev_warn(&client->dev, "invalid trickle resistor value\n"); + /* don't update the trickle charger regs */ + val = val_old; + } + } - if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { + /* 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, RV3028_BACKUP_TCE | i); + RV3028_BACKUP_TCR_MASK, val); if (ret) return ret; - } else { - dev_warn(&client->dev, "invalid trickle resistor value\n"); } } -- 2.25.1