xref: /optee_os/core/include/drivers/regulator.h (revision 3afba469a98b7bea135aa7b3c300d98c11d17ac4)
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 
22 #define REGULATOR_FLAGS_MASK	REGULATOR_ALWAYS_ON
23 
24 struct regulator_ops;
25 
26 /*
27  * struct regu_dt_desc - Regulator description passed to regulator_dt_register()
28  * @priv: Regulator driver private data
29  * @name: Regulator string name for debug purpose
30  * @supply_name: Regulator supply name for node property *-supply or NULL
31  * @ops: Operation handlers for the regulator
32  * @regulator: Pointer to preallocated regulator or NULL if none
33  */
34 struct regu_dt_desc {
35 	void *priv;
36 	char *name;
37 	const char *supply_name;
38 	const struct regulator_ops *ops;
39 	struct regulator *regulator;
40 };
41 
42 /*
43  * struct regulator - A regulator instance
44  * @ops: Operation handlers for the regulator
45  * @supply: Regulator supply reference or NULL if none
46  * @priv: Regulator driver private data
47  * @name: Regulator string name for debug purpose or NULL
48  * @min_uv: Min possible voltage level in microvolt (uV)
49  * @max_uv: Max possible voltage level in microvolt (uV)
50  * @cur_uv: Current voltage level in microvolt (uV)
51  * @flags: REGULATOR_* property flags
52  * @refcount: Regulator enable request reference counter
53  * @lock: Mutex for concurrent access protection
54  * @link: Link in initialized regulator list
55  */
56 struct regulator {
57 	/* Fields initialized by caller of regulator_register() */
58 	const struct regulator_ops *ops;
59 	struct regulator *supply;
60 	void *priv;
61 	char *name;
62 	int min_uv;
63 	int max_uv;
64 	/* Fields internal to regulator framework */
65 	int cur_uv;
66 	unsigned int flags;
67 	unsigned int refcount;
68 	struct mutex lock;	/* Concurrent access protection */
69 	SLIST_ENTRY(regulator) link;
70 };
71 
72 /*
73  * struct regulator_ops - Regulator operation handlers
74  *
75  * @set_state: Enable or disable a regulator
76  * @get_state: Get regulator effective state
77  * @set_voltage: Set voltage level in microvolt (uV)
78  * @get_voltage: Get current voltage in microvolt (uV)
79  * @supplied_init: Optional, finalize initialization once supply is ready
80  */
81 struct regulator_ops {
82 	TEE_Result (*set_state)(struct regulator *r, bool enabled);
83 	TEE_Result (*get_state)(struct regulator *r, bool *enabled);
84 	TEE_Result (*set_voltage)(struct regulator *r, int level_uv);
85 	TEE_Result (*get_voltage)(struct regulator *r, int *level_uv);
86 	TEE_Result (*supplied_init)(struct regulator *r, const void *fdt,
87 				    int node);
88 };
89 
90 #ifdef CFG_DRIVERS_REGULATOR
91 /*
92  * regulator_enable() - Enable regulator
93  * @regulator: Regulator reference
94  */
95 TEE_Result regulator_enable(struct regulator *regulator);
96 
97 /*
98  * regulator_disable() - Disable regulator
99  * @regulator: Regulator reference
100  */
101 TEE_Result regulator_disable(struct regulator *regulator);
102 
103 /*
104  * regulator_is_enabled() - Return whether or not regulator is currently enabled
105  * despite its refcount value.
106  * @regulator: Regulator reference
107  */
108 bool regulator_is_enabled(struct regulator *regulator);
109 
110 /*
111  * regulator_set_voltage() - Set regulator to target level in microvolt
112  * @regulator: Regulator reference
113  * @level_uv: Level in microvolt
114  */
115 TEE_Result regulator_set_voltage(struct regulator *regulator, int level_uv);
116 
117 /*
118  * regulator_register() - Register and initialize a regulator
119  * @regulator: Regulator reference
120  */
121 TEE_Result regulator_register(struct regulator *regulator);
122 
123 /* Print registered regulators and their state to the output console */
124 void regulator_print_state(const char *message);
125 #else
126 static inline TEE_Result regulator_enable(struct regulator *regulator __unused)
127 {
128 	return TEE_ERROR_NOT_SUPPORTED;
129 }
130 
131 static inline TEE_Result regulator_disable(struct regulator *regulator __unused)
132 {
133 	return TEE_ERROR_NOT_SUPPORTED;
134 }
135 
136 static inline bool regulator_is_enabled(struct regulator *regulator __unused)
137 {
138 	return false;
139 }
140 
141 static inline TEE_Result regulator_set_voltage(struct regulator *regul __unused,
142 					       int level_mv __unused)
143 {
144 	return TEE_ERROR_NOT_SUPPORTED;
145 }
146 
147 static inline TEE_Result regulator_init(struct regulator *regulator __unused)
148 {
149 	return TEE_ERROR_NOT_SUPPORTED;
150 }
151 
152 static inline void regulator_print_state(const char *message __unused)
153 {
154 }
155 #endif /*CFG_DRIVERS_REGULATOR*/
156 
157 #if defined(CFG_DRIVERS_REGULATOR) && defined(CFG_DT)
158 /*
159  * regulator_dt_register() - Register a regulator to related to a DT node
160  * @fdt: FDT to work on
161  * @node: DT node of the regulator exposed by regulator driver
162  * @provider_node: Node where xxx-supply property is found or -1 if no supply.
163  * @desc: Description of the regulator to register
164  *
165  * This function registers and initializes a regulator instance once its supply
166  * if found, if any. Regulators registered with this function can be found by
167  * their consumer drivers using API function regulator_dt_get_supply() or like.
168  *
169  * Return TEE_SUCCESS in case of success
170  * Return TEE_ERROR_OUT_OF_MEMORY if failed on memory allocation
171  * Return any other TEE_Result compliant code in case of error
172  */
173 TEE_Result regulator_dt_register(const void *fdt, int node, int provider_node,
174 				 const struct regu_dt_desc *desc);
175 #else
176 static inline TEE_Result regulator_dt_get_supply(const void *fdt __unused,
177 						 int node __unused,
178 						 const char *supply __unused,
179 						 struct regulator **r __unused)
180 {
181 	return TEE_ERROR_NOT_SUPPORTED;
182 }
183 
184 static inline TEE_Result
185 regulator_dt_register(const void *fdt __unused, int node __unused,
186 		      int provider_node __unused,
187 		      const struct regu_dt_desc *d __unused)
188 {
189 	return TEE_ERROR_NOT_SUPPORTED;
190 }
191 #endif /* CFG_DRIVERS_REGULATOR && CFG_DT */
192 
193 /*
194  * regulator_name() - Return regulator name or NULL
195  * @regulator: Regulator reference
196  */
197 static inline const char *regulator_name(struct regulator *regulator)
198 {
199 	return regulator->name;
200 }
201 
202 /*
203  * regulator_is_always_on() - Return the state of REGULATOR_ALWAYS_ON flag
204  * @regulator: Regulator reference
205  */
206 static inline bool regulator_is_always_on(struct regulator *regulator)
207 {
208 	return regulator->flags & REGULATOR_ALWAYS_ON;
209 }
210 
211 /*
212  * regulator_set_min_voltage() - Set regulator to its min level
213  * @regulator: Regulator reference
214  */
215 static inline TEE_Result regulator_set_min_voltage(struct regulator *regulator)
216 {
217 	return regulator_set_voltage(regulator, regulator->min_uv);
218 }
219 
220 /*
221  * regulator_get_voltage() - Get regulator current level in microvolt
222  * @regulator: Regulator reference
223  */
224 static inline int regulator_get_voltage(struct regulator *regulator)
225 {
226 	return regulator->cur_uv;
227 }
228 
229 /*
230  * regulator_get_range() - Get regulator min and/or max support levels
231  * @regulator: Regulator reference
232  * @min_mv: Output reference to min level in microvolt (uV) or NULL
233  * @max_mv: Output reference to max level in microvolt (uV) or NULL
234  */
235 static inline void regulator_get_range(struct regulator *regulator, int *min_uv,
236 				       int *max_uv)
237 {
238 	assert(regulator);
239 	if (min_uv)
240 		*min_uv = regulator->min_uv;
241 	if (max_uv)
242 		*max_uv = regulator->max_uv;
243 }
244 #endif /* DRIVERS_REGULATOR_H */
245