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