regulator:support lp mode and auto pm register

1.add new intf regulator_set_mode to manual set rehulator lower power mode;
2.when add auto lp desc,the regulator lp mode is controlled by  pm framework;

Signed-off-by: dulibo1 <dulibo1@xiaomi.com>
This commit is contained in:
dulibo1 2023-07-21 17:14:34 +08:00 committed by Xiang Xiao
parent 935359fa3f
commit 1456919e58
3 changed files with 155 additions and 2 deletions

View File

@ -455,6 +455,65 @@ out2:
return ret;
}
#ifdef CONFIG_PM
static void regulator_pm_notify(struct pm_callback_s *cb, int domain,
enum pm_state_e pmstate)
{
FAR struct regulator_dev_s *rdev = NULL;
FAR const struct regulator_state_s *state = NULL;
rdev = container_of(cb, struct regulator_dev_s, pm_cb);
if (rdev->desc->domain != domain)
{
return;
}
switch (pmstate)
{
case PM_RESTORE:
if (rdev->ops->resume)
{
rdev->ops->resume(rdev);
}
break;
case PM_NORMAL:
state = &rdev->desc->states[PM_NORMAL];
break;
case PM_IDLE:
state = &rdev->desc->states[PM_IDLE];
break;
case PM_STANDBY:
state = &rdev->desc->states[PM_STANDBY];
break;
case PM_SLEEP:
state = &rdev->desc->states[PM_SLEEP];
break;
default:
break;
}
if (state)
{
if (rdev->ops->set_suspend_voltage && state->uv > 0)
{
rdev->ops->set_suspend_voltage(rdev, state->uv);
}
if (rdev->ops->set_suspend_mode &&
state->mode != REGULATOR_MODE_INVALID)
{
rdev->ops->set_suspend_mode(rdev, state->mode);
}
}
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -803,6 +862,52 @@ int regulator_get_voltage(FAR struct regulator_s *regulator)
return ret;
}
/****************************************************************************
* Name: regulator_set_mode
*
* Description:
* Set regulator operating mode to increase regulator efficiency or improve
* regulation performance.
*
* Input parameters:
* regulator - The regulator consumer representative
* mode - operating mode - one of the REGULATOR_MODE constants
*
* Returned value:
* Positive on success or a negated errno value on failure.
*
****************************************************************************/
int regulator_set_mode(FAR struct regulator_s *regulator,
enum regulator_mode_e mode)
{
FAR struct regulator_dev_s *rdev = regulator->rdev;
unsigned int curr_mode;
int ret;
nxmutex_lock(&rdev->regulator_lock);
if (!rdev->ops->set_mode || mode == REGULATOR_MODE_INVALID)
{
ret = -EINVAL;
goto out;
}
if (rdev->ops->get_mode)
{
curr_mode = rdev->ops->get_mode(rdev);
if (curr_mode == mode)
{
ret = 0;
goto out;
}
}
ret = rdev->ops->set_mode(rdev, mode);
out:
nxmutex_unlock(&rdev->regulator_lock);
return ret;
}
/****************************************************************************
* Name: regulator_register
*
@ -901,6 +1006,15 @@ regulator_register(FAR const struct regulator_desc_s *regulator_desc,
_regulator_do_disable_pulldown(rdev);
}
#ifdef CONFIG_PM
if (rdev->desc->auto_lp)
{
rdev->pm_cb.prepare = NULL;
rdev->pm_cb.notify = regulator_pm_notify;
pm_register(&rdev->pm_cb);
}
#endif
nxmutex_lock(&g_reg_lock);
list_add_tail(&g_reg_list, &rdev->list);
nxmutex_unlock(&g_reg_lock);
@ -934,6 +1048,13 @@ void regulator_unregister(FAR struct regulator_dev_s *rdev)
list_delete(&rdev->list);
nxmutex_unlock(&g_reg_lock);
#ifdef CONFIG_PM
if (rdev->desc->auto_lp)
{
pm_unregister(&rdev->pm_cb);
}
#endif
if (rdev->supply)
{
regulator_put(rdev->supply);

View File

@ -67,6 +67,8 @@ int regulator_disable_deferred(FAR struct regulator_s *regulator, int ms);
int regulator_set_voltage(FAR struct regulator_s *regulator, int min_uv,
int max_uv);
int regulator_get_voltage(FAR struct regulator_s *regulator);
int regulator_set_mode(FAR struct regulator_s *regulator,
enum regulator_mode_e mode);
#undef EXTERN
#ifdef __cplusplus

View File

@ -33,6 +33,7 @@
#include <nuttx/list.h>
#include <nuttx/mutex.h>
#include <nuttx/wqueue.h>
#include <nuttx/power/pm.h>
/****************************************************************************
* Pre-processor Definitions
@ -42,6 +43,15 @@
* Public Types
****************************************************************************/
enum regulator_mode_e
{
REGULATOR_MODE_INVALID = 0,
REGULATOR_MODE_FAST,
REGULATOR_MODE_NORMAL,
REGULATOR_MODE_IDLE,
REGULATOR_MODE_STANDBY,
};
struct regulator_dev_s;
struct regulator_s
@ -50,7 +60,13 @@ struct regulator_s
int min_uv;
int max_uv;
struct list_node list;
struct regulator_dev_s *rdev;
FAR struct regulator_dev_s *rdev;
};
struct regulator_state_s
{
int uv;
enum regulator_mode_e mode;
};
struct regulator_ops_s
@ -68,6 +84,13 @@ struct regulator_ops_s
CODE int (*disable)(FAR struct regulator_dev_s *rdev);
CODE int (*enable_pulldown)(FAR struct regulator_dev_s *rdev);
CODE int (*disable_pulldown)(FAR struct regulator_dev_s *rdev);
CODE int (*set_mode)(FAR struct regulator_dev_s *rdev,
enum regulator_mode_e mode);
CODE enum regulator_mode_e (*get_mode)(FAR struct regulator_dev_s *rdev);
CODE int (*set_suspend_mode)(FAR struct regulator_dev_s *rdev,
enum regulator_mode_e mode);
CODE int (*set_suspend_voltage)(FAR struct regulator_dev_s *, int uv);
CODE int (*resume)(FAR struct regulator_dev_s *rdev);
};
/* This structure describes the regulators capabilities */
@ -100,6 +123,11 @@ struct regulator_desc_s
*/
unsigned int always_on;
FAR const char *supply_name;
#ifdef CONFIG_PM
unsigned int auto_lp;
unsigned int domain;
struct regulator_state_s states[PM_COUNT];
#endif
};
struct regulator_dev_s
@ -112,7 +140,9 @@ struct regulator_dev_s
struct list_node list;
struct list_node consumer_list;
FAR struct regulator_s *supply;
#ifdef CONFIG_PM
struct pm_callback_s pm_cb;
#endif
FAR void *priv;
};