|
| 1 | +/* |
| 2 | + * Copyright (c) 2006-2023, RT-Thread Development Team |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + * |
| 6 | + * Change Logs: |
| 7 | + * Date Author Notes |
| 8 | + * 2023-09-23 GuEe-GUI first version |
| 9 | + */ |
| 10 | + |
| 11 | +#ifndef __REGULATOR_H__ |
| 12 | +#define __REGULATOR_H__ |
| 13 | + |
| 14 | +#include <ref.h> |
| 15 | +#include <rthw.h> |
| 16 | +#include <rtthread.h> |
| 17 | + |
| 18 | +#include <drivers/misc.h> |
| 19 | + |
| 20 | +#define RT_REGULATOR_UVOLT_INVALID (((int)(RT_UINT32_MAX >> 1))) |
| 21 | + |
| 22 | +struct rt_regulator_param |
| 23 | +{ |
| 24 | + const char *name; |
| 25 | + |
| 26 | + int min_uvolt; /* In uV */ |
| 27 | + int max_uvolt; /* In uV */ |
| 28 | + int min_uamp; /* In uA */ |
| 29 | + int max_uamp; /* In uA */ |
| 30 | + int ramp_delay; /* In uV/usec */ |
| 31 | + int enable_delay; /* In usec */ |
| 32 | + int off_on_delay; /* In usec */ |
| 33 | + |
| 34 | + rt_uint32_t enable_active_high:1; |
| 35 | + rt_uint32_t boot_on:1; /* Is enabled on boot */ |
| 36 | + rt_uint32_t always_on:1; /* Must be enabled */ |
| 37 | + rt_uint32_t soft_start:1; /* Ramp voltage slowly */ |
| 38 | + rt_uint32_t pull_down:1; /* Pull down resistor when regulator off */ |
| 39 | + rt_uint32_t over_current_protection:1; /* Auto disable on over current */ |
| 40 | +}; |
| 41 | + |
| 42 | +struct rt_regulator_ops; |
| 43 | + |
| 44 | +struct rt_regulator_node |
| 45 | +{ |
| 46 | + rt_list_t list; |
| 47 | + rt_list_t children_nodes; |
| 48 | + |
| 49 | + struct rt_device *dev; |
| 50 | + struct rt_regulator_node *parent; |
| 51 | + |
| 52 | + const char *supply_name; |
| 53 | + const struct rt_regulator_ops *ops; |
| 54 | + |
| 55 | + struct rt_ref ref; |
| 56 | + rt_atomic_t enabled_count; |
| 57 | + |
| 58 | + const struct rt_regulator_param *param; |
| 59 | + |
| 60 | + rt_list_t notifier_nodes; |
| 61 | + |
| 62 | + void *priv; |
| 63 | +}; |
| 64 | + |
| 65 | +/* |
| 66 | + * NOTE: Power regulator control is dangerous work. We don't want non-internal |
| 67 | + * consumer could access the power regulator tree without regulator's API. So |
| 68 | + * we defined the `rt_regulator` member in core instead of here. |
| 69 | + */ |
| 70 | +struct rt_regulator; |
| 71 | + |
| 72 | +#define RT_REGULATOR_MODE_INVALID 0 |
| 73 | +#define RT_REGULATOR_MODE_FAST RT_BIT(0) |
| 74 | +#define RT_REGULATOR_MODE_NORMAL RT_BIT(1) |
| 75 | +#define RT_REGULATOR_MODE_IDLE RT_BIT(2) |
| 76 | +#define RT_REGULATOR_MODE_STANDBY RT_BIT(3) |
| 77 | + |
| 78 | +struct rt_regulator_ops |
| 79 | +{ |
| 80 | + rt_err_t (*enable)(struct rt_regulator_node *reg); |
| 81 | + rt_err_t (*disable)(struct rt_regulator_node *reg); |
| 82 | + rt_bool_t (*is_enabled)(struct rt_regulator_node *reg); |
| 83 | + rt_err_t (*set_voltage)(struct rt_regulator_node *reg, int min_uvolt, int max_uvolt); |
| 84 | + int (*get_voltage)(struct rt_regulator_node *reg); |
| 85 | + rt_err_t (*set_mode)(struct rt_regulator_node *reg, rt_uint32_t mode); |
| 86 | + rt_int32_t (*get_mode)(struct rt_regulator_node *reg); |
| 87 | + rt_err_t (*set_ramp_delay)(struct rt_regulator_node *reg, int ramp); |
| 88 | + rt_uint32_t (*enable_time)(struct rt_regulator_node *reg); |
| 89 | +}; |
| 90 | + |
| 91 | +struct rt_regulator_notifier; |
| 92 | + |
| 93 | +#define RT_REGULATOR_MSG_ENABLE RT_BIT(0) |
| 94 | +#define RT_REGULATOR_MSG_DISABLE RT_BIT(1) |
| 95 | +#define RT_REGULATOR_MSG_VOLTAGE_CHANGE RT_BIT(2) |
| 96 | +#define RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR RT_BIT(3) |
| 97 | + |
| 98 | +union rt_regulator_notifier_args |
| 99 | +{ |
| 100 | + struct |
| 101 | + { |
| 102 | + int old_uvolt; |
| 103 | + int min_uvolt; |
| 104 | + int max_uvolt; |
| 105 | + }; |
| 106 | +}; |
| 107 | + |
| 108 | +typedef rt_err_t (*rt_regulator_notifier_callback)(struct rt_regulator_notifier *notifier, |
| 109 | + rt_ubase_t msg, void *data); |
| 110 | + |
| 111 | +struct rt_regulator_notifier |
| 112 | +{ |
| 113 | + rt_list_t list; |
| 114 | + |
| 115 | + struct rt_regulator *regulator; |
| 116 | + rt_regulator_notifier_callback callback; |
| 117 | + void *priv; |
| 118 | +}; |
| 119 | + |
| 120 | +rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np); |
| 121 | +rt_err_t rt_regulator_unregister(struct rt_regulator_node *reg_np); |
| 122 | + |
| 123 | +rt_err_t rt_regulator_notifier_register(struct rt_regulator *reg, |
| 124 | + struct rt_regulator_notifier *notifier); |
| 125 | +rt_err_t rt_regulator_notifier_unregister(struct rt_regulator *reg, |
| 126 | + struct rt_regulator_notifier *notifier); |
| 127 | + |
| 128 | +struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id); |
| 129 | +void rt_regulator_put(struct rt_regulator *reg); |
| 130 | + |
| 131 | +rt_err_t rt_regulator_enable(struct rt_regulator *reg); |
| 132 | +rt_err_t rt_regulator_disable(struct rt_regulator *reg); |
| 133 | +rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg); |
| 134 | + |
| 135 | +rt_bool_t rt_regulator_is_supported_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt); |
| 136 | +rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt); |
| 137 | +int rt_regulator_get_voltage(struct rt_regulator *reg); |
| 138 | + |
| 139 | +rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode); |
| 140 | +rt_int32_t rt_regulator_get_mode(struct rt_regulator *reg); |
| 141 | + |
| 142 | +rt_inline rt_err_t rt_regulator_set_voltage_triplet(struct rt_regulator *reg, |
| 143 | + int min_uvolt, int target_uvolt, int max_uvolt) |
| 144 | +{ |
| 145 | + if (!rt_regulator_set_voltage(reg, target_uvolt, max_uvolt)) |
| 146 | + { |
| 147 | + return RT_EOK; |
| 148 | + } |
| 149 | + |
| 150 | + return rt_regulator_set_voltage(reg, min_uvolt, max_uvolt); |
| 151 | +} |
| 152 | + |
| 153 | +#endif /* __REGULATOR_H__ */ |
0 commit comments