Sfoglia il codice sorgente

[DM][REGULATOR] Support operator delay

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GuEe-GUI 1 mese fa
parent
commit
33d9c50efb

+ 4 - 0
components/drivers/include/drivers/regulator.h

@@ -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;

+ 58 - 2
components/drivers/regulator/regulator.c

@@ -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);

+ 19 - 0
components/drivers/regulator/regulator_dm.c

@@ -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");