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