rtc: rv3028: add protective setup by using goldcap with higher voltage

Due to the circuit conditions, the following precautions must be taken:
- trickle charger disabled,
- backup mode set to level sensitive.

Signed-off-by: Peter Galka <peter.galka@wago.com>
This commit is contained in:
Peter Galka
2023-06-02 16:29:53 +02:00
committed by Oleg Karfich
parent 3efc1d2736
commit 66396281e5
+75
View File
@@ -913,6 +913,66 @@ static u8 rv3028_set_trickle_charger(struct rv3028_data *rv3028,
return ret;
}
static int config_rtc_backup_mode(struct i2c_client *client, u32 mode)
{
int ret;
struct rtc_param rtc = {
.param = RTC_PARAM_BACKUP_SWITCH_MODE,
.uvalue = 0
};
char msg[] = "unique setup of backup mode";
ret = rv3028_param_get(&client->dev, &rtc);
if (ret)
goto out;
if (rtc.uvalue == mode)
goto out;
rtc.uvalue = mode;
ret = rv3028_param_set(&client->dev, &rtc);
if (ret)
goto out;
dev_warn(&client->dev, "%s done", msg);
out:
if (ret)
dev_err(&client->dev, "%s failed with %i", msg, ret);
return 0;
}
static int disable_trickle_charger(struct i2c_client *client, struct rv3028_data *rv3028)
{
int ret;
u32 val;
bool enabled = false;
ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &val);
if (ret < 0)
goto out;
if (val & (RV3028_BACKUP_TCE)) {
enabled = true;
ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE, 0);
if (ret)
goto out;
}
out:
if (enabled)
dev_warn(&client->dev, "unexpected enabled trickle charger detected %s",
ret? "" : "and disabled");
if (ret)
dev_err(&client->dev, "disabling trickle charger failed with %i", ret);
return ret;
}
static int rv3028_probe(struct i2c_client *client)
{
struct rv3028_data *rv3028;
@@ -1018,6 +1078,21 @@ static int rv3028_probe(struct i2c_client *client)
rv3028->rtc->max_user_freq = 1;
// If a goldcap is used as backup and it's supplied with higher voltage
// then the RTC itself, a special setup is required to avoid hardware failure.
if (device_property_present(&client->dev, "use-goldcap-with-higher-voltage")) {
ret = disable_trickle_charger(client, rv3028);
if (ret)
return ret;
ret = config_rtc_backup_mode(client, RTC_BSM_LEVEL);
if (ret)
return ret;
} else {
dev_crit(&client->dev,
"goldcap setup skipped, hardware failure possibly");
}
#ifdef CONFIG_COMMON_CLK
rv3028_clkout_register_clk(rv3028, client);
#endif