1 /*
2  * Copyright 2022 Nordic Semiconductor ASA
3  * Copyright 2023 Meta Platforms
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/regulator.h>
9 
regulator_delay(uint32_t delay_us)10 static void regulator_delay(uint32_t delay_us)
11 {
12 	if (delay_us > 0U) {
13 #ifdef CONFIG_MULTITHREADING
14 		k_sleep(K_USEC(delay_us));
15 #else
16 		k_busy_wait(delay_us);
17 #endif
18 	}
19 }
20 
regulator_common_data_init(const struct device * dev)21 void regulator_common_data_init(const struct device *dev)
22 {
23 	struct regulator_common_data *data = dev->data;
24 
25 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
26 	(void)k_mutex_init(&data->lock);
27 #endif
28 	data->refcnt = 0;
29 }
30 
regulator_common_init(const struct device * dev,bool is_enabled)31 int regulator_common_init(const struct device *dev, bool is_enabled)
32 {
33 	const struct regulator_driver_api *api = dev->api;
34 	const struct regulator_common_config *config = dev->config;
35 	struct regulator_common_data *data = dev->data;
36 	int32_t current_uv;
37 	int ret;
38 
39 	if (config->initial_mode != REGULATOR_INITIAL_MODE_UNKNOWN) {
40 		ret = regulator_set_mode(dev, config->initial_mode);
41 		if (ret < 0) {
42 			return ret;
43 		}
44 	}
45 
46 	if (REGULATOR_ACTIVE_DISCHARGE_GET_BITS(config->flags) !=
47 	    REGULATOR_ACTIVE_DISCHARGE_DEFAULT) {
48 		ret = regulator_set_active_discharge(dev,
49 		    (bool)REGULATOR_ACTIVE_DISCHARGE_GET_BITS(config->flags));
50 		if (ret < 0) {
51 			return ret;
52 		}
53 	}
54 
55 	if (config->init_uv > INT32_MIN) {
56 		ret = regulator_set_voltage(dev, config->init_uv, config->init_uv);
57 		if (ret < 0) {
58 			return ret;
59 		}
60 	}
61 
62 	if (config->init_ua > INT32_MIN) {
63 		ret = regulator_set_current_limit(dev, config->init_ua, config->init_ua);
64 		if (ret < 0) {
65 			return ret;
66 		}
67 	}
68 
69 	/* If we have valid range values, we try to match them before enabling */
70 	if ((config->min_uv > INT32_MIN) || (config->max_uv < INT32_MAX)) {
71 
72 		ret = regulator_get_voltage(dev, &current_uv);
73 		if (ret < 0) {
74 			return ret;
75 		}
76 
77 		/* Snap to closest interval value if out of range */
78 		if (current_uv < config->min_uv) {
79 			ret = regulator_set_voltage(dev, config->min_uv, config->min_uv);
80 			if (ret < 0) {
81 				return ret;
82 			}
83 		} else if (current_uv > config->max_uv) {
84 			ret = regulator_set_voltage(dev, config->max_uv, config->max_uv);
85 			if (ret < 0) {
86 				return ret;
87 			}
88 		}
89 	}
90 
91 	if (is_enabled) {
92 		data->refcnt++;
93 	} else if ((config->flags & REGULATOR_INIT_ENABLED) != 0U) {
94 		ret = api->enable(dev);
95 		if (ret < 0) {
96 			return ret;
97 		}
98 
99 		regulator_delay(config->startup_delay_us);
100 		data->refcnt++;
101 	}
102 
103 	return 0;
104 }
105 
regulator_enable(const struct device * dev)106 int regulator_enable(const struct device *dev)
107 {
108 	const struct regulator_driver_api *api = dev->api;
109 	const struct regulator_common_config *config = dev->config;
110 	struct regulator_common_data *data = dev->data;
111 	int ret = 0;
112 
113 	/* enable not supported (always on) */
114 	if (api->enable == NULL) {
115 		return 0;
116 	}
117 
118 	/* regulator must stay always on */
119 	if  ((config->flags & REGULATOR_ALWAYS_ON) != 0U) {
120 		return 0;
121 	}
122 
123 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
124 	(void)k_mutex_lock(&data->lock, K_FOREVER);
125 #endif
126 
127 	data->refcnt++;
128 
129 	if (data->refcnt == 1) {
130 		ret = api->enable(dev);
131 		if (ret < 0) {
132 			data->refcnt--;
133 		} else {
134 			regulator_delay(config->off_on_delay_us);
135 		}
136 	}
137 
138 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
139 	k_mutex_unlock(&data->lock);
140 #endif
141 
142 	return ret;
143 }
144 
regulator_is_enabled(const struct device * dev)145 bool regulator_is_enabled(const struct device *dev)
146 {
147 	const struct regulator_common_config *config = dev->config;
148 	struct regulator_common_data *data = dev->data;
149 	bool enabled;
150 
151 	if ((config->flags & REGULATOR_ALWAYS_ON) != 0U) {
152 		enabled = true;
153 	} else {
154 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
155 		(void)k_mutex_lock(&data->lock, K_FOREVER);
156 #endif
157 		enabled = data->refcnt != 0;
158 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
159 		k_mutex_unlock(&data->lock);
160 #endif
161 	}
162 
163 	return enabled;
164 }
165 
regulator_disable(const struct device * dev)166 int regulator_disable(const struct device *dev)
167 {
168 	const struct regulator_driver_api *api = dev->api;
169 	const struct regulator_common_config *config = dev->config;
170 	struct regulator_common_data *data = dev->data;
171 	int ret = 0;
172 
173 	/* disable not supported (always on) */
174 	if (api->disable == NULL) {
175 		return 0;
176 	}
177 
178 	/* regulator must stay always on */
179 	if  ((config->flags & REGULATOR_ALWAYS_ON) != 0U) {
180 		return 0;
181 	}
182 
183 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
184 	(void)k_mutex_lock(&data->lock, K_FOREVER);
185 #endif
186 
187 	data->refcnt--;
188 
189 	if (data->refcnt == 0) {
190 		ret = api->disable(dev);
191 		if (ret < 0) {
192 			data->refcnt++;
193 		}
194 	}
195 
196 #ifdef CONFIG_REGULATOR_THREAD_SAFE_REFCNT
197 	k_mutex_unlock(&data->lock);
198 #endif
199 
200 	return ret;
201 }
202 
regulator_is_supported_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)203 bool regulator_is_supported_voltage(const struct device *dev, int32_t min_uv,
204 				    int32_t max_uv)
205 {
206 	const struct regulator_common_config *config = dev->config;
207 	unsigned int volt_cnt;
208 
209 	/* voltage may not be allowed, even if supported */
210 	if ((min_uv > config->max_uv) || (max_uv < config->min_uv)) {
211 		return false;
212 	}
213 
214 	volt_cnt = regulator_count_voltages(dev);
215 
216 	for (unsigned int idx = 0U; idx < volt_cnt; idx++) {
217 		int32_t volt_uv;
218 
219 		(void)regulator_list_voltage(dev, idx, &volt_uv);
220 
221 		if ((volt_uv >= min_uv) && (volt_uv <= max_uv)) {
222 			return true;
223 		}
224 	}
225 
226 	return false;
227 }
228 
regulator_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)229 int regulator_set_voltage(const struct device *dev, int32_t min_uv,
230 			  int32_t max_uv)
231 {
232 	const struct regulator_common_config *config = dev->config;
233 	const struct regulator_driver_api *api = dev->api;
234 
235 	if (api->set_voltage == NULL) {
236 		return -ENOSYS;
237 	}
238 
239 	/* voltage may not be allowed, even if supported */
240 	if ((min_uv > config->max_uv) || (max_uv < config->min_uv)) {
241 		return -EINVAL;
242 	}
243 
244 	return api->set_voltage(dev, min_uv, max_uv);
245 }
246 
regulator_set_current_limit(const struct device * dev,int32_t min_ua,int32_t max_ua)247 int regulator_set_current_limit(const struct device *dev, int32_t min_ua,
248 				int32_t max_ua)
249 {
250 	const struct regulator_common_config *config = dev->config;
251 	const struct regulator_driver_api *api = dev->api;
252 
253 	if (api->set_current_limit == NULL) {
254 		return -ENOSYS;
255 	}
256 
257 	/* current limit may not be allowed, even if supported */
258 	if ((min_ua > config->max_ua) || (max_ua < config->min_ua)) {
259 		return -EINVAL;
260 	}
261 
262 	return api->set_current_limit(dev, min_ua, max_ua);
263 }
264 
regulator_set_mode(const struct device * dev,regulator_mode_t mode)265 int regulator_set_mode(const struct device *dev, regulator_mode_t mode)
266 {
267 	const struct regulator_common_config *config = dev->config;
268 	const struct regulator_driver_api *api = dev->api;
269 
270 	if (api->set_mode == NULL) {
271 		return -ENOSYS;
272 	}
273 
274 	/* no mode restrictions */
275 	if (config->allowed_modes_cnt == 0U) {
276 		return api->set_mode(dev, mode);
277 	}
278 
279 	/* check if mode is allowed, apply if it is */
280 	for (uint8_t i = 0U; i < config->allowed_modes_cnt; i++) {
281 		if (mode == config->allowed_modes[i]) {
282 			return api->set_mode(dev, mode);
283 		}
284 	}
285 
286 	return -ENOTSUP;
287 }
288