Commit 3c87b351 authored by Andrej Picej's avatar Andrej Picej Committed by Alexandre Belloni

rtc: rv3028: Add support for "aux-voltage-chargeable" property

Property "trickle-resistor-ohms" allows us to set trickle charger
resistor. However there is no possibility to disable it afterwards.

Add support for "aux-voltage-chargeable" property which can be used to
enable/disable the trickle charger circuit explicitly. The default
behavior of the code is kept as it is!

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: default avatarAndrej Picej <andrej.picej@norik.com>
Link: https://lore.kernel.org/r/20230623081533.76334-1-andrej.picej@norik.comSigned-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 766c3f8a
...@@ -855,11 +855,68 @@ static const struct regmap_config regmap_config = { ...@@ -855,11 +855,68 @@ static const struct regmap_config regmap_config = {
.max_register = 0x37, .max_register = 0x37,
}; };
static u8 rv3028_set_trickle_charger(struct rv3028_data *rv3028,
struct i2c_client *client)
{
int ret, val_old, val;
u32 ohms, chargeable;
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);
val = val_old;
/* setup trickle charger */
if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms",
&ohms)) {
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");
}
}
if (!device_property_read_u32(&client->dev, "aux-voltage-chargeable",
&chargeable)) {
switch (chargeable) {
case 0:
val &= ~RV3028_BACKUP_TCE;
break;
case 1:
val |= RV3028_BACKUP_TCE;
break;
default:
dev_warn(&client->dev,
"unsupported aux-voltage-chargeable value\n");
break;
}
}
/* 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;
}
return ret;
}
static int rv3028_probe(struct i2c_client *client) static int rv3028_probe(struct i2c_client *client)
{ {
struct rv3028_data *rv3028; struct rv3028_data *rv3028;
int ret, status; int ret, status;
u32 ohms;
struct nvmem_config nvmem_cfg = { struct nvmem_config nvmem_cfg = {
.name = "rv3028_nvram", .name = "rv3028_nvram",
.word_size = 1, .word_size = 1,
...@@ -937,24 +994,9 @@ static int rv3028_probe(struct i2c_client *client) ...@@ -937,24 +994,9 @@ static int rv3028_probe(struct i2c_client *client)
if (ret) if (ret)
return ret; return ret;
/* setup trickle charger */ ret = rv3028_set_trickle_charger(rv3028, client);
if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", if (ret)
&ohms)) { return ret;
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)) {
ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i);
if (ret)
return ret;
} else {
dev_warn(&client->dev, "invalid trickle resistor value\n");
}
}
ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment