xref: /openbmc/linux/drivers/regulator/helpers.c (revision bc000245)
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 		int linear_max_uV;
288 
289 		range = &rdev->desc->linear_ranges[i];
290 		linear_max_uV = range->min_uV +
291 			(range->max_sel - range->min_sel) * range->uV_step;
292 
293 		if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
294 			continue;
295 
296 		if (min_uV <= range->min_uV)
297 			min_uV = range->min_uV;
298 
299 		/* range->uV_step == 0 means fixed voltage range */
300 		if (range->uV_step == 0) {
301 			ret = 0;
302 		} else {
303 			ret = DIV_ROUND_UP(min_uV - range->min_uV,
304 					   range->uV_step);
305 			if (ret < 0)
306 				return ret;
307 		}
308 
309 		ret += range->min_sel;
310 
311 		break;
312 	}
313 
314 	if (i == rdev->desc->n_linear_ranges)
315 		return -EINVAL;
316 
317 	/* Map back into a voltage to verify we're still in bounds */
318 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
319 	if (voltage < min_uV || voltage > max_uV)
320 		return -EINVAL;
321 
322 	return ret;
323 }
324 EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
325 
326 /**
327  * regulator_list_voltage_linear - List voltages with simple calculation
328  *
329  * @rdev: Regulator device
330  * @selector: Selector to convert into a voltage
331  *
332  * Regulators with a simple linear mapping between voltages and
333  * selectors can set min_uV and uV_step in the regulator descriptor
334  * and then use this function as their list_voltage() operation,
335  */
336 int regulator_list_voltage_linear(struct regulator_dev *rdev,
337 				  unsigned int selector)
338 {
339 	if (selector >= rdev->desc->n_voltages)
340 		return -EINVAL;
341 	if (selector < rdev->desc->linear_min_sel)
342 		return 0;
343 
344 	selector -= rdev->desc->linear_min_sel;
345 
346 	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
347 }
348 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
349 
350 /**
351  * regulator_list_voltage_linear_range - List voltages for linear ranges
352  *
353  * @rdev: Regulator device
354  * @selector: Selector to convert into a voltage
355  *
356  * Regulators with a series of simple linear mappings between voltages
357  * and selectors can set linear_ranges in the regulator descriptor and
358  * then use this function as their list_voltage() operation,
359  */
360 int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
361 					unsigned int selector)
362 {
363 	const struct regulator_linear_range *range;
364 	int i;
365 
366 	if (!rdev->desc->n_linear_ranges) {
367 		BUG_ON(!rdev->desc->n_linear_ranges);
368 		return -EINVAL;
369 	}
370 
371 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
372 		range = &rdev->desc->linear_ranges[i];
373 
374 		if (!(selector >= range->min_sel &&
375 		      selector <= range->max_sel))
376 			continue;
377 
378 		selector -= range->min_sel;
379 
380 		return range->min_uV + (range->uV_step * selector);
381 	}
382 
383 	return -EINVAL;
384 }
385 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
386 
387 /**
388  * regulator_list_voltage_table - List voltages with table based mapping
389  *
390  * @rdev: Regulator device
391  * @selector: Selector to convert into a voltage
392  *
393  * Regulators with table based mapping between voltages and
394  * selectors can set volt_table in the regulator descriptor
395  * and then use this function as their list_voltage() operation.
396  */
397 int regulator_list_voltage_table(struct regulator_dev *rdev,
398 				 unsigned int selector)
399 {
400 	if (!rdev->desc->volt_table) {
401 		BUG_ON(!rdev->desc->volt_table);
402 		return -EINVAL;
403 	}
404 
405 	if (selector >= rdev->desc->n_voltages)
406 		return -EINVAL;
407 
408 	return rdev->desc->volt_table[selector];
409 }
410 EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
411 
412 /**
413  * regulator_set_bypass_regmap - Default set_bypass() using regmap
414  *
415  * @rdev: device to operate on.
416  * @enable: state to set.
417  */
418 int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
419 {
420 	unsigned int val;
421 
422 	if (enable)
423 		val = rdev->desc->bypass_mask;
424 	else
425 		val = 0;
426 
427 	return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
428 				  rdev->desc->bypass_mask, val);
429 }
430 EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
431 
432 /**
433  * regulator_get_bypass_regmap - Default get_bypass() using regmap
434  *
435  * @rdev: device to operate on.
436  * @enable: current state.
437  */
438 int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
439 {
440 	unsigned int val;
441 	int ret;
442 
443 	ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
444 	if (ret != 0)
445 		return ret;
446 
447 	*enable = val & rdev->desc->bypass_mask;
448 
449 	return 0;
450 }
451 EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
452