xref: /openbmc/linux/drivers/regulator/helpers.c (revision e23feb16)
1 /*
2  * helpers.c  --  Voltage/Current Regulator framework helper functions.
3  *
4  * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5  * Copyright 2008 SlimLogic Ltd.
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  *
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/err.h>
16 #include <linux/delay.h>
17 #include <linux/regmap.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/regulator/driver.h>
20 #include <linux/module.h>
21 
22 /**
23  * regulator_is_enabled_regmap - standard is_enabled() for regmap users
24  *
25  * @rdev: regulator to operate on
26  *
27  * Regulators that use regmap for their register I/O can set the
28  * enable_reg and enable_mask fields in their descriptor and then use
29  * this as their is_enabled operation, saving some code.
30  */
31 int regulator_is_enabled_regmap(struct regulator_dev *rdev)
32 {
33 	unsigned int val;
34 	int ret;
35 
36 	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
37 	if (ret != 0)
38 		return ret;
39 
40 	if (rdev->desc->enable_is_inverted)
41 		return (val & rdev->desc->enable_mask) == 0;
42 	else
43 		return (val & rdev->desc->enable_mask) != 0;
44 }
45 EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
46 
47 /**
48  * regulator_enable_regmap - standard enable() for regmap users
49  *
50  * @rdev: regulator to operate on
51  *
52  * Regulators that use regmap for their register I/O can set the
53  * enable_reg and enable_mask fields in their descriptor and then use
54  * this as their enable() operation, saving some code.
55  */
56 int regulator_enable_regmap(struct regulator_dev *rdev)
57 {
58 	unsigned int val;
59 
60 	if (rdev->desc->enable_is_inverted)
61 		val = 0;
62 	else
63 		val = rdev->desc->enable_mask;
64 
65 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
66 				  rdev->desc->enable_mask, val);
67 }
68 EXPORT_SYMBOL_GPL(regulator_enable_regmap);
69 
70 /**
71  * regulator_disable_regmap - standard disable() for regmap users
72  *
73  * @rdev: regulator to operate on
74  *
75  * Regulators that use regmap for their register I/O can set the
76  * enable_reg and enable_mask fields in their descriptor and then use
77  * this as their disable() operation, saving some code.
78  */
79 int regulator_disable_regmap(struct regulator_dev *rdev)
80 {
81 	unsigned int val;
82 
83 	if (rdev->desc->enable_is_inverted)
84 		val = rdev->desc->enable_mask;
85 	else
86 		val = 0;
87 
88 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
89 				  rdev->desc->enable_mask, val);
90 }
91 EXPORT_SYMBOL_GPL(regulator_disable_regmap);
92 
93 /**
94  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
95  *
96  * @rdev: regulator to operate on
97  *
98  * Regulators that use regmap for their register I/O can set the
99  * vsel_reg and vsel_mask fields in their descriptor and then use this
100  * as their get_voltage_vsel operation, saving some code.
101  */
102 int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
103 {
104 	unsigned int val;
105 	int ret;
106 
107 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
108 	if (ret != 0)
109 		return ret;
110 
111 	val &= rdev->desc->vsel_mask;
112 	val >>= ffs(rdev->desc->vsel_mask) - 1;
113 
114 	return val;
115 }
116 EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
117 
118 /**
119  * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
120  *
121  * @rdev: regulator to operate on
122  * @sel: Selector to set
123  *
124  * Regulators that use regmap for their register I/O can set the
125  * vsel_reg and vsel_mask fields in their descriptor and then use this
126  * as their set_voltage_vsel operation, saving some code.
127  */
128 int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
129 {
130 	int ret;
131 
132 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
133 
134 	ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
135 				  rdev->desc->vsel_mask, sel);
136 	if (ret)
137 		return ret;
138 
139 	if (rdev->desc->apply_bit)
140 		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
141 					 rdev->desc->apply_bit,
142 					 rdev->desc->apply_bit);
143 	return ret;
144 }
145 EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
146 
147 /**
148  * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
149  *
150  * @rdev: Regulator to operate on
151  * @min_uV: Lower bound for voltage
152  * @max_uV: Upper bound for voltage
153  *
154  * Drivers implementing set_voltage_sel() and list_voltage() can use
155  * this as their map_voltage() operation.  It will find a suitable
156  * voltage by calling list_voltage() until it gets something in bounds
157  * for the requested voltages.
158  */
159 int regulator_map_voltage_iterate(struct regulator_dev *rdev,
160 				  int min_uV, int max_uV)
161 {
162 	int best_val = INT_MAX;
163 	int selector = 0;
164 	int i, ret;
165 
166 	/* Find the smallest voltage that falls within the specified
167 	 * range.
168 	 */
169 	for (i = 0; i < rdev->desc->n_voltages; i++) {
170 		ret = rdev->desc->ops->list_voltage(rdev, i);
171 		if (ret < 0)
172 			continue;
173 
174 		if (ret < best_val && ret >= min_uV && ret <= max_uV) {
175 			best_val = ret;
176 			selector = i;
177 		}
178 	}
179 
180 	if (best_val != INT_MAX)
181 		return selector;
182 	else
183 		return -EINVAL;
184 }
185 EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
186 
187 /**
188  * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
189  *
190  * @rdev: Regulator to operate on
191  * @min_uV: Lower bound for voltage
192  * @max_uV: Upper bound for voltage
193  *
194  * Drivers that have ascendant voltage list can use this as their
195  * map_voltage() operation.
196  */
197 int regulator_map_voltage_ascend(struct regulator_dev *rdev,
198 				 int min_uV, int max_uV)
199 {
200 	int i, ret;
201 
202 	for (i = 0; i < rdev->desc->n_voltages; i++) {
203 		ret = rdev->desc->ops->list_voltage(rdev, i);
204 		if (ret < 0)
205 			continue;
206 
207 		if (ret > max_uV)
208 			break;
209 
210 		if (ret >= min_uV && ret <= max_uV)
211 			return i;
212 	}
213 
214 	return -EINVAL;
215 }
216 EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
217 
218 /**
219  * regulator_map_voltage_linear - map_voltage() for simple linear mappings
220  *
221  * @rdev: Regulator to operate on
222  * @min_uV: Lower bound for voltage
223  * @max_uV: Upper bound for voltage
224  *
225  * Drivers providing min_uV and uV_step in their regulator_desc can
226  * use this as their map_voltage() operation.
227  */
228 int regulator_map_voltage_linear(struct regulator_dev *rdev,
229 				 int min_uV, int max_uV)
230 {
231 	int ret, voltage;
232 
233 	/* Allow uV_step to be 0 for fixed voltage */
234 	if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
235 		if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
236 			return 0;
237 		else
238 			return -EINVAL;
239 	}
240 
241 	if (!rdev->desc->uV_step) {
242 		BUG_ON(!rdev->desc->uV_step);
243 		return -EINVAL;
244 	}
245 
246 	if (min_uV < rdev->desc->min_uV)
247 		min_uV = rdev->desc->min_uV;
248 
249 	ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
250 	if (ret < 0)
251 		return ret;
252 
253 	ret += rdev->desc->linear_min_sel;
254 
255 	/* Map back into a voltage to verify we're still in bounds */
256 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
257 	if (voltage < min_uV || voltage > max_uV)
258 		return -EINVAL;
259 
260 	return ret;
261 }
262 EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
263 
264 /**
265  * regulator_map_voltage_linear - map_voltage() for multiple linear ranges
266  *
267  * @rdev: Regulator to operate on
268  * @min_uV: Lower bound for voltage
269  * @max_uV: Upper bound for voltage
270  *
271  * Drivers providing linear_ranges in their descriptor can use this as
272  * their map_voltage() callback.
273  */
274 int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
275 				       int min_uV, int max_uV)
276 {
277 	const struct regulator_linear_range *range;
278 	int ret = -EINVAL;
279 	int voltage, i;
280 
281 	if (!rdev->desc->n_linear_ranges) {
282 		BUG_ON(!rdev->desc->n_linear_ranges);
283 		return -EINVAL;
284 	}
285 
286 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
287 		range = &rdev->desc->linear_ranges[i];
288 
289 		if (!(min_uV <= range->max_uV && max_uV >= range->min_uV))
290 			continue;
291 
292 		if (min_uV <= range->min_uV)
293 			min_uV = range->min_uV;
294 
295 		/* range->uV_step == 0 means fixed voltage range */
296 		if (range->uV_step == 0) {
297 			ret = 0;
298 		} else {
299 			ret = DIV_ROUND_UP(min_uV - range->min_uV,
300 					   range->uV_step);
301 			if (ret < 0)
302 				return ret;
303 		}
304 
305 		ret += range->min_sel;
306 
307 		break;
308 	}
309 
310 	if (i == rdev->desc->n_linear_ranges)
311 		return -EINVAL;
312 
313 	/* Map back into a voltage to verify we're still in bounds */
314 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
315 	if (voltage < min_uV || voltage > max_uV)
316 		return -EINVAL;
317 
318 	return ret;
319 }
320 EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
321 
322 /**
323  * regulator_list_voltage_linear - List voltages with simple calculation
324  *
325  * @rdev: Regulator device
326  * @selector: Selector to convert into a voltage
327  *
328  * Regulators with a simple linear mapping between voltages and
329  * selectors can set min_uV and uV_step in the regulator descriptor
330  * and then use this function as their list_voltage() operation,
331  */
332 int regulator_list_voltage_linear(struct regulator_dev *rdev,
333 				  unsigned int selector)
334 {
335 	if (selector >= rdev->desc->n_voltages)
336 		return -EINVAL;
337 	if (selector < rdev->desc->linear_min_sel)
338 		return 0;
339 
340 	selector -= rdev->desc->linear_min_sel;
341 
342 	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
343 }
344 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
345 
346 /**
347  * regulator_list_voltage_linear_range - List voltages for linear ranges
348  *
349  * @rdev: Regulator device
350  * @selector: Selector to convert into a voltage
351  *
352  * Regulators with a series of simple linear mappings between voltages
353  * and selectors can set linear_ranges in the regulator descriptor and
354  * then use this function as their list_voltage() operation,
355  */
356 int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
357 					unsigned int selector)
358 {
359 	const struct regulator_linear_range *range;
360 	int i;
361 
362 	if (!rdev->desc->n_linear_ranges) {
363 		BUG_ON(!rdev->desc->n_linear_ranges);
364 		return -EINVAL;
365 	}
366 
367 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
368 		range = &rdev->desc->linear_ranges[i];
369 
370 		if (!(selector >= range->min_sel &&
371 		      selector <= range->max_sel))
372 			continue;
373 
374 		selector -= range->min_sel;
375 
376 		return range->min_uV + (range->uV_step * selector);
377 	}
378 
379 	return -EINVAL;
380 }
381 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
382 
383 /**
384  * regulator_list_voltage_table - List voltages with table based mapping
385  *
386  * @rdev: Regulator device
387  * @selector: Selector to convert into a voltage
388  *
389  * Regulators with table based mapping between voltages and
390  * selectors can set volt_table in the regulator descriptor
391  * and then use this function as their list_voltage() operation.
392  */
393 int regulator_list_voltage_table(struct regulator_dev *rdev,
394 				 unsigned int selector)
395 {
396 	if (!rdev->desc->volt_table) {
397 		BUG_ON(!rdev->desc->volt_table);
398 		return -EINVAL;
399 	}
400 
401 	if (selector >= rdev->desc->n_voltages)
402 		return -EINVAL;
403 
404 	return rdev->desc->volt_table[selector];
405 }
406 EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
407 
408 /**
409  * regulator_set_bypass_regmap - Default set_bypass() using regmap
410  *
411  * @rdev: device to operate on.
412  * @enable: state to set.
413  */
414 int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
415 {
416 	unsigned int val;
417 
418 	if (enable)
419 		val = rdev->desc->bypass_mask;
420 	else
421 		val = 0;
422 
423 	return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
424 				  rdev->desc->bypass_mask, val);
425 }
426 EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
427 
428 /**
429  * regulator_get_bypass_regmap - Default get_bypass() using regmap
430  *
431  * @rdev: device to operate on.
432  * @enable: current state.
433  */
434 int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
435 {
436 	unsigned int val;
437 	int ret;
438 
439 	ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
440 	if (ret != 0)
441 		return ret;
442 
443 	*enable = val & rdev->desc->bypass_mask;
444 
445 	return 0;
446 }
447 EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
448