[DM][REGULATOR] Support operator delay

Signed-off-by: GuEe-GUI <2991707448@qq.com>
This commit is contained in:
GuEe-GUI
2025-12-02 16:17:38 +08:00
committed by R b b666
parent 7ebc10a688
commit 33d9c50efb
3 changed files with 81 additions and 2 deletions

View File

@@ -30,6 +30,9 @@ struct rt_regulator_param
int ramp_delay; /* In uV/usec */
int enable_delay; /* In usec */
int off_on_delay; /* In usec */
int settling_time;
int settling_time_up;
int settling_time_down;
rt_uint32_t enable_active_high:1;
rt_uint32_t boot_on:1; /* Is enabled on boot */
@@ -37,6 +40,7 @@ struct rt_regulator_param
rt_uint32_t soft_start:1; /* Ramp voltage slowly */
rt_uint32_t pull_down:1; /* Pull down resistor when regulator off */
rt_uint32_t over_current_protection:1; /* Auto disable on over current */
rt_uint32_t ramp_disable:1; /* Disable ramp delay */
};
struct rt_regulator_ops;

View File

@@ -31,6 +31,7 @@ static rt_err_t regulator_disable(struct rt_regulator_node *reg_np);
rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np)
{
rt_err_t err;
const struct rt_regulator_param *param;
if (!reg_np || !reg_np->dev || !reg_np->param || !reg_np->ops)
@@ -48,6 +49,16 @@ rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np)
reg_np->parent = RT_NULL;
if ((param->ramp_delay || param->ramp_disable) &&
reg_np->ops->set_ramp_delay)
{
if ((err = reg_np->ops->set_ramp_delay(reg_np, param->ramp_delay)))
{
LOG_E("Set ramp error = %s\n", rt_strerror(err));
return err;
}
}
#ifdef RT_USING_OFW
if (reg_np->dev->ofw_node)
{
@@ -184,6 +195,40 @@ static rt_uint32_t regulator_get_enable_time(struct rt_regulator_node *reg_np)
return 0;
}
static rt_uint32_t regulator_set_voltage_time(struct rt_regulator_node *reg_np,
int old_uvolt, int new_uvolt)
{
unsigned int ramp_delay = 0;
if (reg_np->param->ramp_delay)
{
ramp_delay = reg_np->param->ramp_delay;
}
else if (reg_np->param->ramp_delay)
{
ramp_delay = reg_np->param->ramp_delay;
}
else if (reg_np->param->settling_time)
{
return reg_np->param->settling_time;
}
else if (reg_np->param->settling_time_up && new_uvolt > old_uvolt)
{
return reg_np->param->settling_time_up;
}
else if (reg_np->param->settling_time_down && new_uvolt < old_uvolt)
{
return reg_np->param->settling_time_down;
}
if (ramp_delay == 0)
{
return 0;
}
return RT_DIV_ROUND_UP(rt_abs(new_uvolt - old_uvolt), ramp_delay);
}
static void regulator_delay(rt_uint32_t delay)
{
rt_uint32_t ms = delay / 1000;
@@ -227,7 +272,6 @@ static void regulator_delay(rt_uint32_t delay)
static rt_err_t regulator_enable(struct rt_regulator_node *reg_np)
{
rt_err_t err = RT_EOK;
rt_uint32_t enable_delay = regulator_get_enable_time(reg_np);
if (reg_np->ops->enable)
{
@@ -235,6 +279,8 @@ static rt_err_t regulator_enable(struct rt_regulator_node *reg_np)
if (!err)
{
rt_uint32_t enable_delay = regulator_get_enable_time(reg_np);
if (enable_delay)
{
regulator_delay(enable_delay);
@@ -369,7 +415,17 @@ static rt_err_t regulator_set_voltage(struct rt_regulator_node *reg_np, int min_
err = reg_np->ops->set_voltage(reg_np, min_uvolt, max_uvolt);
}
if (err)
if (!err)
{
rt_uint32_t delay = regulator_set_voltage_time(reg_np,
args.old_uvolt, reg_np->ops->get_voltage(reg_np));
if (delay)
{
regulator_delay(delay);
}
}
else
{
regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR,
(void *)(rt_base_t)args.old_uvolt);

View File

@@ -41,12 +41,31 @@ rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *
{
param->ramp_delay = pval;
}
else
{
param->ramp_disable = RT_TRUE;
}
if (!rt_ofw_prop_read_u32(np, "regulator-enable-ramp-delay", &pval))
{
param->enable_delay = pval;
}
if (!rt_ofw_prop_read_u32(np, "regulator-settling-time-us", &pval))
{
param->settling_time = pval;
}
if (!rt_ofw_prop_read_u32(np, "regulator-settling-time-up-us", &pval))
{
param->settling_time_up = pval;
}
if (!rt_ofw_prop_read_u32(np, "regulator-settling-time-down-us", &pval))
{
param->settling_time_down = pval;
}
param->enable_active_high = rt_ofw_prop_read_bool(np, "enable-active-high");
param->boot_on = rt_ofw_prop_read_bool(np, "regulator-boot-on");
param->always_on = rt_ofw_prop_read_bool(np, "regulator-always-on");