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