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