From 56614a4cb94018a9dee257be4dfd9b69fd18cc46 Mon Sep 17 00:00:00 2001 From: GuEe-GUI <2991707448@qq.com> Date: Tue, 26 Nov 2024 13:32:30 +0800 Subject: [PATCH] [DM/FEATURE] Support regulator 1. Add the regulator driver framework. 2. Add the generic voltage and current regulator API support for drivers. Signed-off-by: GuEe-GUI <2991707448@qq.com> --- components/drivers/Kconfig | 1 + .../drivers/include/drivers/regulator.h | 153 +++++ components/drivers/include/rtdevice.h | 4 + components/drivers/regulator/Kconfig | 10 + components/drivers/regulator/SConscript | 15 + components/drivers/regulator/regulator.c | 629 ++++++++++++++++++ components/drivers/regulator/regulator_dm.c | 59 ++ components/drivers/regulator/regulator_dm.h | 26 + 8 files changed, 897 insertions(+) create mode 100644 components/drivers/include/drivers/regulator.h create mode 100644 components/drivers/regulator/Kconfig create mode 100755 components/drivers/regulator/SConscript create mode 100644 components/drivers/regulator/regulator.c create mode 100644 components/drivers/regulator/regulator_dm.c create mode 100644 components/drivers/regulator/regulator_dm.h diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index 5248fd0ff7..3c510250da 100755 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -27,6 +27,7 @@ rsource "ata/Kconfig" rsource "block/Kconfig" rsource "nvme/Kconfig" rsource "scsi/Kconfig" +rsource "regulator/Kconfig" rsource "reset/Kconfig" rsource "virtio/Kconfig" rsource "dma/Kconfig" diff --git a/components/drivers/include/drivers/regulator.h b/components/drivers/include/drivers/regulator.h new file mode 100644 index 0000000000..d74fc64277 --- /dev/null +++ b/components/drivers/include/drivers/regulator.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#ifndef __REGULATOR_H__ +#define __REGULATOR_H__ + +#include +#include +#include + +#include + +#define RT_REGULATOR_UVOLT_INVALID (((int)(RT_UINT32_MAX >> 1))) + +struct rt_regulator_param +{ + const char *name; + + int min_uvolt; /* In uV */ + int max_uvolt; /* In uV */ + int min_uamp; /* In uA */ + int max_uamp; /* In uA */ + int ramp_delay; /* In uV/usec */ + int enable_delay; /* In usec */ + int off_on_delay; /* In usec */ + + rt_uint32_t enable_active_high:1; + rt_uint32_t boot_on:1; /* Is enabled on boot */ + rt_uint32_t always_on:1; /* Must be enabled */ + 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 */ +}; + +struct rt_regulator_ops; + +struct rt_regulator_node +{ + rt_list_t list; + rt_list_t children_nodes; + + struct rt_device *dev; + struct rt_regulator_node *parent; + + const char *supply_name; + const struct rt_regulator_ops *ops; + + struct rt_ref ref; + rt_atomic_t enabled_count; + + const struct rt_regulator_param *param; + + rt_list_t notifier_nodes; + + void *priv; +}; + +/* + * NOTE: Power regulator control is dangerous work. We don't want non-internal + * consumer could access the power regulator tree without regulator's API. So + * we defined the `rt_regulator` member in core instead of here. + */ +struct rt_regulator; + +#define RT_REGULATOR_MODE_INVALID 0 +#define RT_REGULATOR_MODE_FAST RT_BIT(0) +#define RT_REGULATOR_MODE_NORMAL RT_BIT(1) +#define RT_REGULATOR_MODE_IDLE RT_BIT(2) +#define RT_REGULATOR_MODE_STANDBY RT_BIT(3) + +struct rt_regulator_ops +{ + rt_err_t (*enable)(struct rt_regulator_node *reg); + rt_err_t (*disable)(struct rt_regulator_node *reg); + rt_bool_t (*is_enabled)(struct rt_regulator_node *reg); + rt_err_t (*set_voltage)(struct rt_regulator_node *reg, int min_uvolt, int max_uvolt); + int (*get_voltage)(struct rt_regulator_node *reg); + rt_err_t (*set_mode)(struct rt_regulator_node *reg, rt_uint32_t mode); + rt_int32_t (*get_mode)(struct rt_regulator_node *reg); + rt_err_t (*set_ramp_delay)(struct rt_regulator_node *reg, int ramp); + rt_uint32_t (*enable_time)(struct rt_regulator_node *reg); +}; + +struct rt_regulator_notifier; + +#define RT_REGULATOR_MSG_ENABLE RT_BIT(0) +#define RT_REGULATOR_MSG_DISABLE RT_BIT(1) +#define RT_REGULATOR_MSG_VOLTAGE_CHANGE RT_BIT(2) +#define RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR RT_BIT(3) + +union rt_regulator_notifier_args +{ + struct + { + int old_uvolt; + int min_uvolt; + int max_uvolt; + }; +}; + +typedef rt_err_t (*rt_regulator_notifier_callback)(struct rt_regulator_notifier *notifier, + rt_ubase_t msg, void *data); + +struct rt_regulator_notifier +{ + rt_list_t list; + + struct rt_regulator *regulator; + rt_regulator_notifier_callback callback; + void *priv; +}; + +rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np); +rt_err_t rt_regulator_unregister(struct rt_regulator_node *reg_np); + +rt_err_t rt_regulator_notifier_register(struct rt_regulator *reg, + struct rt_regulator_notifier *notifier); +rt_err_t rt_regulator_notifier_unregister(struct rt_regulator *reg, + struct rt_regulator_notifier *notifier); + +struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id); +void rt_regulator_put(struct rt_regulator *reg); + +rt_err_t rt_regulator_enable(struct rt_regulator *reg); +rt_err_t rt_regulator_disable(struct rt_regulator *reg); +rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg); + +rt_bool_t rt_regulator_is_supported_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt); +rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt); +int rt_regulator_get_voltage(struct rt_regulator *reg); + +rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode); +rt_int32_t rt_regulator_get_mode(struct rt_regulator *reg); + +rt_inline rt_err_t rt_regulator_set_voltage_triplet(struct rt_regulator *reg, + int min_uvolt, int target_uvolt, int max_uvolt) +{ + if (!rt_regulator_set_voltage(reg, target_uvolt, max_uvolt)) + { + return RT_EOK; + } + + return rt_regulator_set_voltage(reg, min_uvolt, max_uvolt); +} + +#endif /* __REGULATOR_H__ */ diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h index ef395d3192..2e1860e00c 100644 --- a/components/drivers/include/rtdevice.h +++ b/components/drivers/include/rtdevice.h @@ -85,6 +85,10 @@ extern "C" { #include "drivers/pic.h" #endif /* RT_USING_PIC */ +#ifdef RT_USING_REGULATOR +#include "drivers/regulator.h" +#endif /* RT_USING_REGULATOR */ + #ifdef RT_USING_RESET #include "drivers/reset.h" #endif /* RT_USING_RESET */ diff --git a/components/drivers/regulator/Kconfig b/components/drivers/regulator/Kconfig new file mode 100644 index 0000000000..c81b4820a8 --- /dev/null +++ b/components/drivers/regulator/Kconfig @@ -0,0 +1,10 @@ +menuconfig RT_USING_REGULATOR + bool "Using Voltage and Current Regulator" + select RT_USING_ADT + select RT_USING_ADT_REF + depends on RT_USING_DM + default n + +if RT_USING_REGULATOR + osource "$(SOC_DM_REGULATOR_DIR)/Kconfig" +endif diff --git a/components/drivers/regulator/SConscript b/components/drivers/regulator/SConscript new file mode 100755 index 0000000000..b5ae8e9fdc --- /dev/null +++ b/components/drivers/regulator/SConscript @@ -0,0 +1,15 @@ +from building import * + +group = [] + +if not GetDepend(['RT_USING_REGULATOR']): + Return('group') + +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +src = ['regulator.c', 'regulator_dm.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/drivers/regulator/regulator.c b/components/drivers/regulator/regulator.c new file mode 100644 index 0000000000..29071e9dc0 --- /dev/null +++ b/components/drivers/regulator/regulator.c @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "rtdm.regulator" +#define DBG_LVL DBG_INFO +#include + +#include +#include +#include + +struct rt_regulator +{ + struct rt_regulator_node *reg_np; +}; + +static struct rt_spinlock _regulator_lock = { 0 }; + +static rt_err_t regulator_enable(struct rt_regulator_node *reg_np); +static rt_err_t regulator_disable(struct rt_regulator_node *reg_np); + +rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np) +{ + const struct rt_regulator_param *param; + + if (!reg_np || !reg_np->dev || !reg_np->param || !reg_np->ops) + { + return -RT_EINVAL; + } + + rt_list_init(®_np->list); + rt_list_init(®_np->children_nodes); + rt_list_init(®_np->notifier_nodes); + rt_ref_init(®_np->ref); + rt_atomic_store(®_np->enabled_count, 0); + + param = reg_np->param; + + reg_np->parent = RT_NULL; + +#ifdef RT_USING_OFW + if (reg_np->dev->ofw_node) + { + rt_ofw_data(reg_np->dev->ofw_node) = reg_np; + } +#endif /* RT_USING_OFW */ + + if (param->boot_on || param->always_on) + { + regulator_enable(reg_np); + } + + return RT_EOK; +} + +rt_err_t rt_regulator_unregister(struct rt_regulator_node *reg_np) +{ + rt_err_t err = RT_EOK; + + if (!reg_np) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + if (rt_atomic_load(®_np->enabled_count) != 0) + { + err = -RT_EBUSY; + + LOG_E("%s was enabled by consumer", reg_np->supply_name); + + goto _unlock; + } + + if (!(reg_np->param->boot_on || reg_np->param->always_on)) + { + regulator_disable(reg_np); + } + + if (!rt_list_isempty(®_np->children_nodes) || rt_ref_read(®_np->ref) > 1) + { + err = -RT_EBUSY; + + goto _unlock; + } + + reg_np->parent = RT_NULL; + rt_list_remove(®_np->list); + +_unlock: + rt_hw_spin_unlock(&_regulator_lock.lock); + + return err; +} + +rt_err_t rt_regulator_notifier_register(struct rt_regulator *reg, + struct rt_regulator_notifier *notifier) +{ + struct rt_regulator_node *reg_np; + + if (!reg || !notifier) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + reg_np = reg->reg_np; + notifier->regulator = reg; + + rt_list_init(¬ifier->list); + rt_list_insert_after(®_np->notifier_nodes, ¬ifier->list); + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return RT_EOK; +} + +rt_err_t rt_regulator_notifier_unregister(struct rt_regulator *reg, + struct rt_regulator_notifier *notifier) +{ + if (!reg || !notifier) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + rt_list_remove(¬ifier->list); + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return RT_EOK; +} + +static rt_err_t regulator_notifier_call_chain(struct rt_regulator_node *reg_np, + rt_ubase_t msg, void *data) +{ + rt_err_t err = RT_EOK; + struct rt_regulator_notifier *notifier; + rt_list_t *head = ®_np->notifier_nodes; + + if (rt_list_isempty(head)) + { + return err; + } + + rt_list_for_each_entry(notifier, head, list) + { + err = notifier->callback(notifier, msg, data); + + if (err == -RT_EIO) + { + break; + } + } + + return err; +} + +static rt_uint32_t regulator_get_enable_time(struct rt_regulator_node *reg_np) +{ + if (reg_np->param->enable_delay) + { + return reg_np->param->enable_delay; + } + + if (reg_np->ops->enable_time) + { + return reg_np->ops->enable_time(reg_np); + } + + return 0; +} + +static void regulator_delay(rt_uint32_t delay) +{ + rt_uint32_t ms = delay / 1000; + rt_uint32_t us = delay % 1000; + + if (ms > 0) + { + /* + * For small enough values, handle super-millisecond + * delays in the usleep_range() call below. + */ + if (ms < 20) + { + us += ms * 1000; + } + else if (rt_thread_self()) + { + rt_thread_mdelay(ms); + } + else + { + rt_hw_us_delay(ms * 1000); + } + } + + /* + * Give the scheduler some room to coalesce with any other + * wakeup sources. For delays shorter than 10 us, don't even + * bother setting up high-resolution timers and just busy-loop. + */ + if (us >= 10) + { + rt_hw_us_delay((us + 100) >> 1); + } + else + { + rt_hw_us_delay(us); + } +} + +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) + { + err = reg_np->ops->enable(reg_np); + + if (!err) + { + if (enable_delay) + { + regulator_delay(enable_delay); + } + + rt_atomic_add(®_np->enabled_count, 1); + err = regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_ENABLE, RT_NULL); + } + } + + if (!err && reg_np->parent) + { + err = regulator_enable(reg_np->parent); + } + + return err; +} + +rt_err_t rt_regulator_enable(struct rt_regulator *reg) +{ + rt_err_t err; + + if (!reg) + { + return -RT_EINVAL; + } + + if (rt_regulator_is_enabled(reg)) + { + return RT_EOK; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + err = regulator_enable(reg->reg_np); + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return err; +} + +static rt_err_t regulator_disable(struct rt_regulator_node *reg_np) +{ + rt_err_t err = RT_EOK; + + if (reg_np->ops->disable) + { + err = reg_np->ops->disable(reg_np); + + if (!err) + { + if (reg_np->param->off_on_delay) + { + regulator_delay(reg_np->param->off_on_delay); + } + + err = regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_DISABLE, RT_NULL); + } + } + + if (!err && reg_np->parent) + { + err = regulator_disable(reg_np->parent); + } + + return err; +} + +rt_err_t rt_regulator_disable(struct rt_regulator *reg) +{ + rt_err_t err; + + if (!reg) + { + return -RT_EINVAL; + } + + if (!rt_regulator_is_enabled(reg)) + { + return RT_EOK; + } + + if (rt_atomic_load(®->reg_np->enabled_count) != 0) + { + rt_atomic_sub(®->reg_np->enabled_count, 1); + + return RT_EOK; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + err = regulator_disable(reg->reg_np); + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return err; +} + +rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg) +{ + if (!reg) + { + return -RT_EINVAL; + } + + if (reg->reg_np->ops->is_enabled) + { + return reg->reg_np->ops->is_enabled(reg->reg_np); + } + + return rt_atomic_load(®->reg_np->enabled_count) > 0; +} + +static rt_err_t regulator_set_voltage(struct rt_regulator_node *reg_np, int min_uvolt, int max_uvolt) +{ + rt_err_t err = RT_EOK; + + if (reg_np->ops->set_voltage) + { + union rt_regulator_notifier_args args; + + RT_ASSERT(reg_np->ops->get_voltage != RT_NULL); + + args.old_uvolt = reg_np->ops->get_voltage(reg_np); + args.min_uvolt = min_uvolt; + args.max_uvolt = max_uvolt; + + err = regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_VOLTAGE_CHANGE, &args); + + if (!err) + { + err = reg_np->ops->set_voltage(reg_np, min_uvolt, max_uvolt); + } + + if (err) + { + regulator_notifier_call_chain(reg_np, RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR, + (void *)(rt_base_t)args.old_uvolt); + } + } + + if (!err && reg_np->parent) + { + err = regulator_set_voltage(reg_np->parent, min_uvolt, max_uvolt); + } + + return err; +} + +rt_bool_t rt_regulator_is_supported_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt) +{ + const struct rt_regulator_param *param; + + RT_ASSERT(reg != RT_NULL); + + param = reg->reg_np->param; + + if (!param) + { + return RT_FALSE; + } + + return param->min_uvolt <= min_uvolt && param->max_uvolt >= max_uvolt; +} + +rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt) +{ + rt_err_t err; + + if (!reg) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + err = regulator_set_voltage(reg->reg_np, min_uvolt, max_uvolt); + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return err; +} + +int rt_regulator_get_voltage(struct rt_regulator *reg) +{ + int uvolt = RT_REGULATOR_UVOLT_INVALID; + struct rt_regulator_node *reg_np; + + if (!reg) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + reg_np = reg->reg_np; + + if (reg_np->ops->get_voltage) + { + uvolt = reg_np->ops->get_voltage(reg->reg_np); + } + else + { + uvolt = -RT_ENOSYS; + } + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return uvolt; +} + +rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode) +{ + rt_err_t err; + struct rt_regulator_node *reg_np; + + if (!reg) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + reg_np = reg->reg_np; + + if (reg_np->ops->set_mode) + { + err = reg_np->ops->set_mode(reg_np, mode); + } + else + { + err = -RT_ENOSYS; + } + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return err; +} + +rt_int32_t rt_regulator_get_mode(struct rt_regulator *reg) +{ + rt_int32_t mode; + struct rt_regulator_node *reg_np; + + if (!reg) + { + return -RT_EINVAL; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + reg_np = reg->reg_np; + + if (reg_np->ops->get_mode) + { + mode = reg_np->ops->get_mode(reg_np); + } + else + { + mode = -RT_ENOSYS; + } + + rt_hw_spin_unlock(&_regulator_lock.lock); + + return mode; +} + +static void regulator_check_parent(struct rt_regulator_node *reg_np) +{ + if (reg_np->parent) + { + return; + } + else + { + #ifdef RT_USING_OFW + rt_phandle parent_phandle = 0; + struct rt_ofw_node *np = reg_np->dev->ofw_node; + + while (np) + { + if (rt_ofw_prop_read_u32(np, "vin-supply", &parent_phandle)) + { + break; + } + + if (!(np = rt_ofw_find_node_by_phandle(parent_phandle))) + { + break; + } + + if (!(reg_np->parent = rt_ofw_data(np))) + { + LOG_W("%s parent ofw node = %s not init", + reg_np->supply_name, rt_ofw_node_full_name(np)); + + rt_ofw_node_put(np); + break; + } + + rt_list_insert_after(®_np->parent->children_nodes, ®_np->list); + rt_ofw_node_put(np); + } + #endif + } +} + +struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id) +{ + struct rt_regulator *reg = RT_NULL; + struct rt_regulator_node *reg_np = RT_NULL; + + if (!dev || !id) + { + reg = rt_err_ptr(-RT_EINVAL); + goto _end; + } + +#ifdef RT_USING_OFW + if (dev->ofw_node) + { + rt_phandle supply_phandle; + struct rt_ofw_node *np = dev->ofw_node; + char supply_name[64]; + + rt_snprintf(supply_name, sizeof(supply_name), "%s-supply", id); + + if (rt_ofw_prop_read_u32(np, supply_name, &supply_phandle)) + { + goto _end; + } + + if (!(np = rt_ofw_find_node_by_phandle(supply_phandle))) + { + reg = rt_err_ptr(-RT_EIO); + goto _end; + } + + if (!rt_ofw_data(np)) + { + rt_platform_ofw_request(np); + } + + reg_np = rt_ofw_data(np); + rt_ofw_node_put(np); + } +#endif + + if (!reg_np) + { + reg = rt_err_ptr(-RT_ENOSYS); + goto _end; + } + + rt_hw_spin_lock(&_regulator_lock.lock); + + regulator_check_parent(reg_np); + + rt_hw_spin_unlock(&_regulator_lock.lock); + + reg = rt_calloc(1, sizeof(*reg)); + + if (!reg) + { + reg = rt_err_ptr(-RT_ENOMEM); + goto _end; + } + + reg->reg_np = reg_np; + rt_ref_get(®_np->ref); + +_end: + return reg; +} + +static void regulator_release(struct rt_ref *r) +{ + struct rt_regulator_node *reg_np = rt_container_of(r, struct rt_regulator_node, ref); + + rt_regulator_unregister(reg_np); +} + +void rt_regulator_put(struct rt_regulator *reg) +{ + if (!reg) + { + return; + } + + rt_ref_put(®->reg_np->ref, ®ulator_release); + rt_free(reg); +} diff --git a/components/drivers/regulator/regulator_dm.c b/components/drivers/regulator/regulator_dm.c new file mode 100644 index 0000000000..d8096c43d3 --- /dev/null +++ b/components/drivers/regulator/regulator_dm.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#include "regulator_dm.h" + +#ifdef RT_USING_OFW +rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *param) +{ + rt_uint32_t pval; + + param->name = rt_ofw_prop_read_raw(np, "regulator-name", RT_NULL); + + if (!rt_ofw_prop_read_u32(np, "regulator-min-microvolt", &pval)) + { + param->min_uvolt = pval; + } + + if (!rt_ofw_prop_read_u32(np, "regulator-max-microvolt", &pval)) + { + param->max_uvolt = pval; + } + + if (!rt_ofw_prop_read_u32(np, "regulator-min-microamp", &pval)) + { + param->min_uamp = pval; + } + + if (!rt_ofw_prop_read_u32(np, "regulator-max-microamp", &pval)) + { + param->max_uamp = pval; + } + + if (!rt_ofw_prop_read_u32(np, "regulator-ramp-delay", &pval)) + { + param->ramp_delay = pval; + } + + if (!rt_ofw_prop_read_u32(np, "regulator-enable-ramp-delay", &pval)) + { + param->enable_delay = 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"); + param->soft_start = rt_ofw_prop_read_bool(np, "regulator-soft-start"); + param->pull_down = rt_ofw_prop_read_bool(np, "regulator-pull-down"); + param->over_current_protection = rt_ofw_prop_read_bool(np, "regulator-over-current-protection"); + + return RT_EOK; +} +#endif /* RT_USING_OFW */ diff --git a/components/drivers/regulator/regulator_dm.h b/components/drivers/regulator/regulator_dm.h new file mode 100644 index 0000000000..207bb12794 --- /dev/null +++ b/components/drivers/regulator/regulator_dm.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#ifndef __REGULATOR_DM_H__ +#define __REGULATOR_DM_H__ + +#include +#include + +#ifdef RT_USING_OFW +rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *param); +#else +rt_inline rt_err_t regulator_ofw_parse(struct rt_ofw_node *np, struct rt_regulator_param *param); +{ + return RT_EOK; +} +#endif /* RT_USING_OFW */ + +#endif /* __REGULATOR_DM_H__ */