xref: /optee_os/core/include/drivers/regulator.h (revision 8c48c11ba37e0dce3a62d6f165a6543794b30e70)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2023, STMicroelectronics
4  */
5 #ifndef __DRIVERS_REGULATOR_H
6 #define __DRIVERS_REGULATOR_H
7 
8 #include <assert.h>
9 #include <bitstring.h>
10 #include <kernel/mutex_pm_aware.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <util.h>
16 
17 /* Regulator property flags: related to device tree binding properties */
18 
19 /* Regulator should never be disabled. DT property: regulator-always-on */
20 #define REGULATOR_ALWAYS_ON	BIT(0)
21 /* Enables pull down mode. DT property: regulator-pull-down */
22 #define REGULATOR_PULL_DOWN	BIT(1)
23 /*
24  * It's expected that this regulator was left on by the bootloader.
25  * The core shouldn't prevent it from being turned off later.
26  * DT property: regulator-boot-on
27  */
28 #define REGULATOR_BOOT_ON	BIT(2)
29 /*
30  * Enables over current protection.
31  * DT property: regulator-over-current-protection
32  */
33 #define REGULATOR_OVER_CURRENT	BIT(3)
34 
35 #define REGULATOR_FLAGS_MASK	(REGULATOR_ALWAYS_ON | REGULATOR_PULL_DOWN | \
36 				 REGULATOR_BOOT_ON | REGULATOR_OVER_CURRENT)
37 
38 struct regulator_ops;
39 
40 /*
41  * struct regu_dt_desc - Regulator description passed to regulator_dt_register()
42  * @priv: Regulator driver private data
43  * @name: Regulator string name for debug purpose
44  * @supply_name: Regulator supply name for node property *-supply or NULL
45  * @ops: Operation handlers for the regulator
46  * @regulator: Pointer to preallocated regulator or NULL if none
47  */
48 struct regu_dt_desc {
49 	void *priv;
50 	const char *name;
51 	const char *supply_name;
52 	const struct regulator_ops *ops;
53 	struct regulator *regulator;
54 };
55 
56 /*
57  * Defines the format of struct voltages::entries
58  *
59  * If regulator_voltages::type is VOLTAGE_TYPE_FULL_LIST, then
60  * regulator_voltages@entries stores regulator_voltages::num_levels cells,
61  * listing supported voltage levels in uV from lowest to highest value.
62  *
63  * If regulator_voltages::type is VOLTAGE_TYPE_INCREMENT, then
64  * regulator_voltages::entries stores 3 cells: min level, max level and
65  * level increment step, all in uV. When so, regulator_voltages::num_levels
66  * is meaningless.
67  */
68 enum voltage_type {
69 	VOLTAGE_TYPE_INVALID = 0,
70 	VOLTAGE_TYPE_FULL_LIST, /* extensive list in uV */
71 	VOLTAGE_TYPE_INCREMENT  /* min, max, increment (in uV) */
72 };
73 
74 /*
75  * struct regulator_voltages_desc - Voltage levels description
76  * @type: Type of level description
77  * @num_levels: Number of voltage levels when @type is VOLTAGE_TYPE_FULL_LIST
78  *
79  */
80 struct regulator_voltages_desc {
81 	enum voltage_type type;
82 	size_t num_levels;
83 };
84 
85 /*
86  * struct regulator - A regulator instance
87  * @ops: Operation handlers for the regulator
88  * @supply: Regulator supply reference or NULL if none
89  * @priv: Regulator driver private data
90  * @name: Regulator string name for debug purpose or NULL
91  * @min_uv: Min possible voltage level in microvolt (uV)
92  * @max_uv: Max possible voltage level in microvolt (uV)
93  * @ramp_delay_uv_per_us: Voltage level change delay in uV/s
94  * @flags: REGULATOR_* property flags
95  * @refcount: Regulator enable request reference counter
96  * @mutex: Concurrent access protection considering PM context sequences
97  * @voltages_fallback: Default supported voltage range description
98  * @link: Link in initialized regulator list
99  */
100 struct regulator {
101 	/* Fields initialized by caller of regulator_register() */
102 	const struct regulator_ops *ops;
103 	struct regulator *supply;
104 	void *priv;
105 	char *name;
106 	int min_uv;
107 	int max_uv;
108 	unsigned int ramp_delay_uv_per_us;
109 	/* Fields internal to regulator framework */
110 	unsigned int flags;
111 	unsigned int refcount;
112 	struct mutex_pm_aware mutex;
113 	struct voltages_fallback {
114 		struct regulator_voltages_desc desc;
115 		int levels[3];
116 	} voltages_fallback;
117 	size_t levels_count_fallback;
118 	SLIST_ENTRY(regulator) link;
119 };
120 
121 /*
122  * struct regulator_ops - Regulator operation handlers
123  *
124  * @set_state: Enable or disable a regulator
125  * @get_state: Get regulator effective state
126  * @set_voltage: Set voltage level in microvolt (uV)
127  * @get_voltage: Get current voltage in microvolt (uV)
128  * @supported_voltages: Get supported levels description
129  * @supplied_init: Optional, finalize initialization once supply is ready
130  */
131 struct regulator_ops {
132 	TEE_Result (*set_state)(struct regulator *r, bool enabled);
133 	TEE_Result (*get_state)(struct regulator *r, bool *enabled);
134 	TEE_Result (*set_voltage)(struct regulator *r, int level_uv);
135 	TEE_Result (*get_voltage)(struct regulator *r, int *level_uv);
136 	TEE_Result (*supported_voltages)(struct regulator *r,
137 					 struct regulator_voltages_desc **desc,
138 					 const int **levels);
139 	TEE_Result (*supplied_init)(struct regulator *r, const void *fdt,
140 				    int node);
141 };
142 
143 #ifdef CFG_DRIVERS_REGULATOR
144 /*
145  * regulator_enable() - Enable regulator
146  * @regulator: Regulator reference
147  */
148 TEE_Result regulator_enable(struct regulator *regulator);
149 
150 /*
151  * regulator_disable() - Disable regulator
152  * @regulator: Regulator reference
153  */
154 TEE_Result regulator_disable(struct regulator *regulator);
155 
156 /*
157  * regulator_is_enabled() - Return whether or not regulator is currently enabled
158  * despite its refcount value.
159  * @regulator: Regulator reference
160  */
161 bool regulator_is_enabled(struct regulator *regulator);
162 
163 /*
164  * regulator_set_voltage() - Set regulator to target level in microvolt
165  * @regulator: Regulator reference
166  * @level_uv: Level in microvolt
167  */
168 TEE_Result regulator_set_voltage(struct regulator *regulator, int level_uv);
169 
170 /*
171  * regulator_register() - Register and initialize a regulator
172  * @regulator: Regulator reference
173  */
174 TEE_Result regulator_register(struct regulator *regulator);
175 
176 /* Print registered regulators and their state to the output console */
177 void regulator_print_state(const char *message);
178 #else
179 static inline TEE_Result regulator_enable(struct regulator *regulator __unused)
180 {
181 	return TEE_ERROR_NOT_SUPPORTED;
182 }
183 
184 static inline TEE_Result regulator_disable(struct regulator *regulator __unused)
185 {
186 	return TEE_ERROR_NOT_SUPPORTED;
187 }
188 
189 static inline bool regulator_is_enabled(struct regulator *regulator __unused)
190 {
191 	return false;
192 }
193 
194 static inline TEE_Result regulator_set_voltage(struct regulator *regul __unused,
195 					       int level_mv __unused)
196 {
197 	return TEE_ERROR_NOT_SUPPORTED;
198 }
199 
200 static inline TEE_Result regulator_init(struct regulator *regulator __unused)
201 {
202 	return TEE_ERROR_NOT_SUPPORTED;
203 }
204 
205 static inline void regulator_print_state(const char *message __unused)
206 {
207 }
208 #endif /*CFG_DRIVERS_REGULATOR*/
209 
210 #if defined(CFG_DRIVERS_REGULATOR) && defined(CFG_DT)
211 /*
212  * regulator_dt_get_supply() - Get a regulator supply from name and DT node
213  * @fdt: FDT to work on
214  * @node: DT node of the regulator consumer
215  * @supply_name: Name of the supply in DT property xxx-supply
216  * @regulator: Output regulator upon success
217  *
218  * Upon success, this function provides the pointer to regulator
219  * defined by DT binding property @name-supply phandle reference.
220  *
221  * This function returns TEE_ERROR_DEFER_DRIVER_INIT if supply exists but is
222  * not yet initialized.
223  */
224 TEE_Result regulator_dt_get_supply(const void *fdt, int node,
225 				   const char *supply_name,
226 				   struct regulator **regulator);
227 
228 /*
229  * regulator_dt_register() - Register a regulator to related to a DT node
230  * @fdt: FDT to work on
231  * @node: DT node of the regulator exposed by regulator driver
232  * @provider_node: Node where xxx-supply property is found or -1 if no supply.
233  * @desc: Description of the regulator to register
234  *
235  * This function registers and initializes a regulator instance once its supply
236  * if found, if any. Regulators registered with this function can be found by
237  * their consumer drivers using API function regulator_dt_get_supply() or like.
238  *
239  * Return TEE_SUCCESS in case of success
240  * Return TEE_ERROR_OUT_OF_MEMORY if failed on memory allocation
241  * Return any other TEE_Result compliant code in case of error
242  */
243 TEE_Result regulator_dt_register(const void *fdt, int node, int provider_node,
244 				 const struct regu_dt_desc *desc);
245 #else
246 static inline TEE_Result regulator_dt_get_supply(const void *fdt __unused,
247 						 int node __unused,
248 						 const char *supply __unused,
249 						 struct regulator **r __unused)
250 {
251 	return TEE_ERROR_NOT_SUPPORTED;
252 }
253 
254 static inline TEE_Result
255 regulator_dt_register(const void *fdt __unused, int node __unused,
256 		      int provider_node __unused,
257 		      const struct regu_dt_desc *d __unused)
258 {
259 	return TEE_ERROR_NOT_SUPPORTED;
260 }
261 #endif /* CFG_DRIVERS_REGULATOR && CFG_DT */
262 
263 /*
264  * regulator_name() - Return regulator name or NULL
265  * @regulator: Regulator reference
266  */
267 static inline const char *regulator_name(struct regulator *regulator)
268 {
269 	return regulator->name;
270 }
271 
272 /*
273  * regulator_is_always_on() - Return the state of REGULATOR_ALWAYS_ON flag
274  * @regulator: Regulator reference
275  */
276 static inline bool regulator_is_always_on(struct regulator *regulator)
277 {
278 	return regulator->flags & REGULATOR_ALWAYS_ON;
279 }
280 
281 /*
282  * regulator_set_min_voltage() - Set regulator to its min level
283  * @regulator: Regulator reference
284  */
285 static inline TEE_Result regulator_set_min_voltage(struct regulator *regulator)
286 {
287 	return regulator_set_voltage(regulator, regulator->min_uv);
288 }
289 
290 /*
291  * regulator_get_voltage() - Get regulator effective voltage level in microvolt
292  * @regulator: Regulator reference
293  */
294 int regulator_get_voltage(struct regulator *regulator);
295 
296 /*
297  * regulator_get_range() - Get regulator min and/or max support levels
298  * @regulator: Regulator reference
299  * @min_mv: Output reference to min level in microvolt (uV) or NULL
300  * @max_mv: Output reference to max level in microvolt (uV) or NULL
301  */
302 static inline void regulator_get_range(struct regulator *regulator, int *min_uv,
303 				       int *max_uv)
304 {
305 	assert(regulator);
306 	if (min_uv)
307 		*min_uv = regulator->min_uv;
308 	if (max_uv)
309 		*max_uv = regulator->max_uv;
310 }
311 
312 /*
313  * regulator_supported_voltages() - Get regulator supported levels in microvolt
314  * @regulator: Regulator reference
315  * @desc: Output reference to supported voltage levels description
316  * @levels: Output reference to voltage level array, in microvolts
317  *
318  * When @desc->type is VOLTAGE_TYPE_FULL_LIST, number of cells of @*levels
319  * is defined by @desc->num_levels, each cell being a level in microvolts (uV).
320  * When @desc->type is VOLTAGE_TYPE_INCREMENT, @levels has 3 cells:
321  * @levels[0] is the min voltage level, @levels[1] is the max level, @levels[2]
322  * is the incremental level step, all in microvolts (uV).
323  */
324 TEE_Result regulator_supported_voltages(struct regulator *regulator,
325 					struct regulator_voltages_desc **desc,
326 					const int **levels);
327 
328 /* Print current regulator tree summary to console with info trace level */
329 #ifdef CFG_DRIVERS_REGULATOR
330 void regulator_print_tree(void);
331 #else
332 static inline void regulator_print_tree(void)
333 {
334 }
335 #endif /* CFG_DRIVERS_REGULATOR */
336 #endif /* __DRIVERS_REGULATOR_H */
337