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