This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 1456919e584e363d0fd483420d9668bc1de6922c Author: dulibo1 <[email protected]> AuthorDate: Fri Jul 21 17:14:34 2023 +0800 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 <[email protected]> --- drivers/power/supply/regulator.c | 121 +++++++++++++++++++++++++++++++++++++++ include/nuttx/power/consumer.h | 2 + include/nuttx/power/regulator.h | 34 ++++++++++- 3 files changed, 155 insertions(+), 2 deletions(-) diff --git a/drivers/power/supply/regulator.c b/drivers/power/supply/regulator.c index 35f9b74ec2..a529e17f19 100644 --- a/drivers/power/supply/regulator.c +++ b/drivers/power/supply/regulator.c @@ -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); diff --git a/include/nuttx/power/consumer.h b/include/nuttx/power/consumer.h index 5c3c0d24a1..edfc750771 100644 --- a/include/nuttx/power/consumer.h +++ b/include/nuttx/power/consumer.h @@ -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 diff --git a/include/nuttx/power/regulator.h b/include/nuttx/power/regulator.h index 06f3a5c697..11a35f74d5 100644 --- a/include/nuttx/power/regulator.h +++ b/include/nuttx/power/regulator.h @@ -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; };
