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