Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later
2 : : //
3 : : // helpers.c -- Voltage/Current Regulator framework helper functions.
4 : : //
5 : : // Copyright 2007, 2008 Wolfson Microelectronics PLC.
6 : : // Copyright 2008 SlimLogic Ltd.
7 : :
8 : : #include <linux/kernel.h>
9 : : #include <linux/err.h>
10 : : #include <linux/delay.h>
11 : : #include <linux/regmap.h>
12 : : #include <linux/regulator/consumer.h>
13 : : #include <linux/regulator/driver.h>
14 : : #include <linux/module.h>
15 : :
16 : : #include "internal.h"
17 : :
18 : : /**
19 : : * regulator_is_enabled_regmap - standard is_enabled() for regmap users
20 : : *
21 : : * @rdev: regulator to operate on
22 : : *
23 : : * Regulators that use regmap for their register I/O can set the
24 : : * enable_reg and enable_mask fields in their descriptor and then use
25 : : * this as their is_enabled operation, saving some code.
26 : : */
27 : 0 : int regulator_is_enabled_regmap(struct regulator_dev *rdev)
28 : : {
29 : : unsigned int val;
30 : : int ret;
31 : :
32 : 0 : ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
33 [ # # ]: 0 : if (ret != 0)
34 : : return ret;
35 : :
36 : 0 : val &= rdev->desc->enable_mask;
37 : :
38 [ # # ]: 0 : if (rdev->desc->enable_is_inverted) {
39 [ # # ]: 0 : if (rdev->desc->enable_val)
40 : 0 : return val != rdev->desc->enable_val;
41 : 0 : return val == 0;
42 : : } else {
43 [ # # ]: 0 : if (rdev->desc->enable_val)
44 : 0 : return val == rdev->desc->enable_val;
45 : 0 : return val != 0;
46 : : }
47 : : }
48 : : EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
49 : :
50 : : /**
51 : : * regulator_enable_regmap - standard enable() for regmap users
52 : : *
53 : : * @rdev: regulator to operate on
54 : : *
55 : : * Regulators that use regmap for their register I/O can set the
56 : : * enable_reg and enable_mask fields in their descriptor and then use
57 : : * this as their enable() operation, saving some code.
58 : : */
59 : 0 : int regulator_enable_regmap(struct regulator_dev *rdev)
60 : : {
61 : : unsigned int val;
62 : :
63 [ # # ]: 0 : if (rdev->desc->enable_is_inverted) {
64 : 0 : val = rdev->desc->disable_val;
65 : : } else {
66 : 0 : val = rdev->desc->enable_val;
67 [ # # ]: 0 : if (!val)
68 : 0 : val = rdev->desc->enable_mask;
69 : : }
70 : :
71 : 0 : return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
72 : : rdev->desc->enable_mask, val);
73 : : }
74 : : EXPORT_SYMBOL_GPL(regulator_enable_regmap);
75 : :
76 : : /**
77 : : * regulator_disable_regmap - standard disable() for regmap users
78 : : *
79 : : * @rdev: regulator to operate on
80 : : *
81 : : * Regulators that use regmap for their register I/O can set the
82 : : * enable_reg and enable_mask fields in their descriptor and then use
83 : : * this as their disable() operation, saving some code.
84 : : */
85 : 0 : int regulator_disable_regmap(struct regulator_dev *rdev)
86 : : {
87 : : unsigned int val;
88 : :
89 [ # # ]: 0 : if (rdev->desc->enable_is_inverted) {
90 : 0 : val = rdev->desc->enable_val;
91 [ # # ]: 0 : if (!val)
92 : 0 : val = rdev->desc->enable_mask;
93 : : } else {
94 : 0 : val = rdev->desc->disable_val;
95 : : }
96 : :
97 : 0 : return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
98 : : rdev->desc->enable_mask, val);
99 : : }
100 : : EXPORT_SYMBOL_GPL(regulator_disable_regmap);
101 : :
102 : : static int regulator_range_selector_to_index(struct regulator_dev *rdev,
103 : : unsigned int rval)
104 : : {
105 : : int i;
106 : :
107 [ # # ]: 0 : if (!rdev->desc->linear_range_selectors)
108 : : return -EINVAL;
109 : :
110 : 0 : rval &= rdev->desc->vsel_range_mask;
111 : :
112 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
113 [ # # ]: 0 : if (rdev->desc->linear_range_selectors[i] == rval)
114 : 0 : return i;
115 : : }
116 : : return -EINVAL;
117 : : }
118 : :
119 : : /**
120 : : * regulator_get_voltage_sel_pickable_regmap - pickable range get_voltage_sel
121 : : *
122 : : * @rdev: regulator to operate on
123 : : *
124 : : * Regulators that use regmap for their register I/O and use pickable
125 : : * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
126 : : * fields in their descriptor and then use this as their get_voltage_vsel
127 : : * operation, saving some code.
128 : : */
129 : 0 : int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
130 : : {
131 : : unsigned int r_val;
132 : : int range;
133 : : unsigned int val;
134 : : int ret, i;
135 : : unsigned int voltages_in_range = 0;
136 : :
137 [ # # ]: 0 : if (!rdev->desc->linear_ranges)
138 : : return -EINVAL;
139 : :
140 : 0 : ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
141 [ # # ]: 0 : if (ret != 0)
142 : : return ret;
143 : :
144 : 0 : ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &r_val);
145 [ # # ]: 0 : if (ret != 0)
146 : : return ret;
147 : :
148 : 0 : val &= rdev->desc->vsel_mask;
149 : 0 : val >>= ffs(rdev->desc->vsel_mask) - 1;
150 : :
151 : 0 : range = regulator_range_selector_to_index(rdev, r_val);
152 [ # # ]: 0 : if (range < 0)
153 : : return -EINVAL;
154 : :
155 [ # # ]: 0 : for (i = 0; i < range; i++)
156 : 0 : voltages_in_range += (rdev->desc->linear_ranges[i].max_sel -
157 : 0 : rdev->desc->linear_ranges[i].min_sel) + 1;
158 : :
159 : 0 : return val + voltages_in_range;
160 : : }
161 : : EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
162 : :
163 : : /**
164 : : * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel
165 : : *
166 : : * @rdev: regulator to operate on
167 : : * @sel: Selector to set
168 : : *
169 : : * Regulators that use regmap for their register I/O and use pickable
170 : : * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
171 : : * fields in their descriptor and then use this as their set_voltage_vsel
172 : : * operation, saving some code.
173 : : */
174 : 0 : int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
175 : : unsigned int sel)
176 : : {
177 : : unsigned int range;
178 : : int ret, i;
179 : : unsigned int voltages_in_range = 0;
180 : :
181 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
182 : 0 : voltages_in_range = (rdev->desc->linear_ranges[i].max_sel -
183 : 0 : rdev->desc->linear_ranges[i].min_sel) + 1;
184 [ # # ]: 0 : if (sel < voltages_in_range)
185 : : break;
186 : 0 : sel -= voltages_in_range;
187 : : }
188 : :
189 [ # # ]: 0 : if (i == rdev->desc->n_linear_ranges)
190 : : return -EINVAL;
191 : :
192 : 0 : sel <<= ffs(rdev->desc->vsel_mask) - 1;
193 : 0 : sel += rdev->desc->linear_ranges[i].min_sel;
194 : :
195 : 0 : range = rdev->desc->linear_range_selectors[i];
196 : :
197 [ # # ]: 0 : if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
198 : 0 : ret = regmap_update_bits(rdev->regmap,
199 : : rdev->desc->vsel_reg,
200 : : rdev->desc->vsel_range_mask |
201 : : rdev->desc->vsel_mask, sel | range);
202 : : } else {
203 : 0 : ret = regmap_update_bits(rdev->regmap,
204 : : rdev->desc->vsel_range_reg,
205 : : rdev->desc->vsel_range_mask, range);
206 [ # # ]: 0 : if (ret)
207 : : return ret;
208 : :
209 : 0 : ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
210 : : rdev->desc->vsel_mask, sel);
211 : : }
212 : :
213 [ # # ]: 0 : if (ret)
214 : : return ret;
215 : :
216 [ # # ]: 0 : if (rdev->desc->apply_bit)
217 : 0 : ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
218 : : rdev->desc->apply_bit,
219 : : rdev->desc->apply_bit);
220 : 0 : return ret;
221 : : }
222 : : EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap);
223 : :
224 : : /**
225 : : * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
226 : : *
227 : : * @rdev: regulator to operate on
228 : : *
229 : : * Regulators that use regmap for their register I/O can set the
230 : : * vsel_reg and vsel_mask fields in their descriptor and then use this
231 : : * as their get_voltage_vsel operation, saving some code.
232 : : */
233 : 0 : int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
234 : : {
235 : : unsigned int val;
236 : : int ret;
237 : :
238 : 0 : ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
239 [ # # ]: 0 : if (ret != 0)
240 : : return ret;
241 : :
242 : 0 : val &= rdev->desc->vsel_mask;
243 : 0 : val >>= ffs(rdev->desc->vsel_mask) - 1;
244 : :
245 : 0 : return val;
246 : : }
247 : : EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
248 : :
249 : : /**
250 : : * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
251 : : *
252 : : * @rdev: regulator to operate on
253 : : * @sel: Selector to set
254 : : *
255 : : * Regulators that use regmap for their register I/O can set the
256 : : * vsel_reg and vsel_mask fields in their descriptor and then use this
257 : : * as their set_voltage_vsel operation, saving some code.
258 : : */
259 : 0 : int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
260 : : {
261 : : int ret;
262 : :
263 : 0 : sel <<= ffs(rdev->desc->vsel_mask) - 1;
264 : :
265 : 0 : ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
266 : : rdev->desc->vsel_mask, sel);
267 [ # # ]: 0 : if (ret)
268 : : return ret;
269 : :
270 [ # # ]: 0 : if (rdev->desc->apply_bit)
271 : 0 : ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
272 : : rdev->desc->apply_bit,
273 : : rdev->desc->apply_bit);
274 : 0 : return ret;
275 : : }
276 : : EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
277 : :
278 : : /**
279 : : * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
280 : : *
281 : : * @rdev: Regulator to operate on
282 : : * @min_uV: Lower bound for voltage
283 : : * @max_uV: Upper bound for voltage
284 : : *
285 : : * Drivers implementing set_voltage_sel() and list_voltage() can use
286 : : * this as their map_voltage() operation. It will find a suitable
287 : : * voltage by calling list_voltage() until it gets something in bounds
288 : : * for the requested voltages.
289 : : */
290 : 0 : int regulator_map_voltage_iterate(struct regulator_dev *rdev,
291 : : int min_uV, int max_uV)
292 : : {
293 : : int best_val = INT_MAX;
294 : : int selector = 0;
295 : : int i, ret;
296 : :
297 : : /* Find the smallest voltage that falls within the specified
298 : : * range.
299 : : */
300 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_voltages; i++) {
301 : 0 : ret = rdev->desc->ops->list_voltage(rdev, i);
302 [ # # ]: 0 : if (ret < 0)
303 : 0 : continue;
304 : :
305 [ # # # # ]: 0 : if (ret < best_val && ret >= min_uV && ret <= max_uV) {
306 : : best_val = ret;
307 : : selector = i;
308 : : }
309 : : }
310 : :
311 [ # # ]: 0 : if (best_val != INT_MAX)
312 : 0 : return selector;
313 : : else
314 : : return -EINVAL;
315 : : }
316 : : EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
317 : :
318 : : /**
319 : : * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
320 : : *
321 : : * @rdev: Regulator to operate on
322 : : * @min_uV: Lower bound for voltage
323 : : * @max_uV: Upper bound for voltage
324 : : *
325 : : * Drivers that have ascendant voltage list can use this as their
326 : : * map_voltage() operation.
327 : : */
328 : 0 : int regulator_map_voltage_ascend(struct regulator_dev *rdev,
329 : : int min_uV, int max_uV)
330 : : {
331 : : int i, ret;
332 : :
333 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_voltages; i++) {
334 : 0 : ret = rdev->desc->ops->list_voltage(rdev, i);
335 [ # # ]: 0 : if (ret < 0)
336 : 0 : continue;
337 : :
338 [ # # ]: 0 : if (ret > max_uV)
339 : : break;
340 : :
341 [ # # ]: 0 : if (ret >= min_uV && ret <= max_uV)
342 : 0 : return i;
343 : : }
344 : :
345 : : return -EINVAL;
346 : : }
347 : : EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
348 : :
349 : : /**
350 : : * regulator_map_voltage_linear - map_voltage() for simple linear mappings
351 : : *
352 : : * @rdev: Regulator to operate on
353 : : * @min_uV: Lower bound for voltage
354 : : * @max_uV: Upper bound for voltage
355 : : *
356 : : * Drivers providing min_uV and uV_step in their regulator_desc can
357 : : * use this as their map_voltage() operation.
358 : : */
359 : 0 : int regulator_map_voltage_linear(struct regulator_dev *rdev,
360 : : int min_uV, int max_uV)
361 : : {
362 : : int ret, voltage;
363 : :
364 : : /* Allow uV_step to be 0 for fixed voltage */
365 [ # # # # ]: 0 : if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
366 [ # # # # ]: 0 : if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
367 : : return 0;
368 : : else
369 : 0 : return -EINVAL;
370 : : }
371 : :
372 [ # # ]: 0 : if (!rdev->desc->uV_step) {
373 [ # # ]: 0 : BUG_ON(!rdev->desc->uV_step);
374 : : return -EINVAL;
375 : : }
376 : :
377 [ # # ]: 0 : if (min_uV < rdev->desc->min_uV)
378 : 0 : min_uV = rdev->desc->min_uV;
379 : :
380 : 0 : ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
381 [ # # ]: 0 : if (ret < 0)
382 : : return ret;
383 : :
384 : 0 : ret += rdev->desc->linear_min_sel;
385 : :
386 : : /* Map back into a voltage to verify we're still in bounds */
387 : 0 : voltage = rdev->desc->ops->list_voltage(rdev, ret);
388 [ # # ]: 0 : if (voltage < min_uV || voltage > max_uV)
389 : : return -EINVAL;
390 : :
391 : 0 : return ret;
392 : : }
393 : : EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
394 : :
395 : : /**
396 : : * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges
397 : : *
398 : : * @rdev: Regulator to operate on
399 : : * @min_uV: Lower bound for voltage
400 : : * @max_uV: Upper bound for voltage
401 : : *
402 : : * Drivers providing linear_ranges in their descriptor can use this as
403 : : * their map_voltage() callback.
404 : : */
405 : 0 : int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
406 : : int min_uV, int max_uV)
407 : : {
408 : : const struct regulator_linear_range *range;
409 : : int ret = -EINVAL;
410 : : int voltage, i;
411 : :
412 [ # # ]: 0 : if (!rdev->desc->n_linear_ranges) {
413 [ # # ]: 0 : BUG_ON(!rdev->desc->n_linear_ranges);
414 : : return -EINVAL;
415 : : }
416 : :
417 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
418 : : int linear_max_uV;
419 : :
420 : 0 : range = &rdev->desc->linear_ranges[i];
421 : 0 : linear_max_uV = range->min_uV +
422 : 0 : (range->max_sel - range->min_sel) * range->uV_step;
423 : :
424 [ # # # # ]: 0 : if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
425 : 0 : continue;
426 : :
427 [ # # ]: 0 : if (min_uV <= range->min_uV)
428 : 0 : min_uV = range->min_uV;
429 : :
430 : : /* range->uV_step == 0 means fixed voltage range */
431 [ # # ]: 0 : if (range->uV_step == 0) {
432 : : ret = 0;
433 : : } else {
434 : 0 : ret = DIV_ROUND_UP(min_uV - range->min_uV,
435 : : range->uV_step);
436 [ # # ]: 0 : if (ret < 0)
437 : 0 : return ret;
438 : : }
439 : :
440 : 0 : ret += range->min_sel;
441 : :
442 : : /*
443 : : * Map back into a voltage to verify we're still in bounds.
444 : : * If we are not, then continue checking rest of the ranges.
445 : : */
446 : 0 : voltage = rdev->desc->ops->list_voltage(rdev, ret);
447 [ # # ]: 0 : if (voltage >= min_uV && voltage <= max_uV)
448 : : break;
449 : : }
450 : :
451 [ # # ]: 0 : if (i == rdev->desc->n_linear_ranges)
452 : : return -EINVAL;
453 : :
454 : 0 : return ret;
455 : : }
456 : : EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
457 : :
458 : : /**
459 : : * regulator_map_voltage_pickable_linear_range - map_voltage, pickable ranges
460 : : *
461 : : * @rdev: Regulator to operate on
462 : : * @min_uV: Lower bound for voltage
463 : : * @max_uV: Upper bound for voltage
464 : : *
465 : : * Drivers providing pickable linear_ranges in their descriptor can use
466 : : * this as their map_voltage() callback.
467 : : */
468 : 0 : int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
469 : : int min_uV, int max_uV)
470 : : {
471 : : const struct regulator_linear_range *range;
472 : : int ret = -EINVAL;
473 : : int voltage, i;
474 : : unsigned int selector = 0;
475 : :
476 [ # # ]: 0 : if (!rdev->desc->n_linear_ranges) {
477 [ # # ]: 0 : BUG_ON(!rdev->desc->n_linear_ranges);
478 : : return -EINVAL;
479 : : }
480 : :
481 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
482 : : int linear_max_uV;
483 : :
484 : 0 : range = &rdev->desc->linear_ranges[i];
485 : 0 : linear_max_uV = range->min_uV +
486 : 0 : (range->max_sel - range->min_sel) * range->uV_step;
487 : :
488 [ # # # # ]: 0 : if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) {
489 : 0 : selector += (range->max_sel - range->min_sel + 1);
490 : 0 : continue;
491 : : }
492 : :
493 [ # # ]: 0 : if (min_uV <= range->min_uV)
494 : 0 : min_uV = range->min_uV;
495 : :
496 : : /* range->uV_step == 0 means fixed voltage range */
497 [ # # ]: 0 : if (range->uV_step == 0) {
498 : : ret = 0;
499 : : } else {
500 : 0 : ret = DIV_ROUND_UP(min_uV - range->min_uV,
501 : : range->uV_step);
502 [ # # ]: 0 : if (ret < 0)
503 : 0 : return ret;
504 : : }
505 : :
506 : 0 : ret += selector;
507 : :
508 : 0 : voltage = rdev->desc->ops->list_voltage(rdev, ret);
509 : :
510 : : /*
511 : : * Map back into a voltage to verify we're still in bounds.
512 : : * We may have overlapping voltage ranges. Hence we don't
513 : : * exit but retry until we have checked all ranges.
514 : : */
515 [ # # ]: 0 : if (voltage < min_uV || voltage > max_uV)
516 : 0 : selector += (range->max_sel - range->min_sel + 1);
517 : : else
518 : : break;
519 : : }
520 : :
521 [ # # ]: 0 : if (i == rdev->desc->n_linear_ranges)
522 : : return -EINVAL;
523 : :
524 : 0 : return ret;
525 : : }
526 : : EXPORT_SYMBOL_GPL(regulator_map_voltage_pickable_linear_range);
527 : :
528 : : /**
529 : : * regulator_list_voltage_linear - List voltages with simple calculation
530 : : *
531 : : * @rdev: Regulator device
532 : : * @selector: Selector to convert into a voltage
533 : : *
534 : : * Regulators with a simple linear mapping between voltages and
535 : : * selectors can set min_uV and uV_step in the regulator descriptor
536 : : * and then use this function as their list_voltage() operation,
537 : : */
538 : 0 : int regulator_list_voltage_linear(struct regulator_dev *rdev,
539 : : unsigned int selector)
540 : : {
541 [ # # ]: 0 : if (selector >= rdev->desc->n_voltages)
542 : : return -EINVAL;
543 [ # # ]: 0 : if (selector < rdev->desc->linear_min_sel)
544 : : return 0;
545 : :
546 : 0 : selector -= rdev->desc->linear_min_sel;
547 : :
548 : 0 : return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
549 : : }
550 : : EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
551 : :
552 : : /**
553 : : * regulator_list_voltage_pickable_linear_range - pickable range list voltages
554 : : *
555 : : * @rdev: Regulator device
556 : : * @selector: Selector to convert into a voltage
557 : : *
558 : : * list_voltage() operation, intended to be used by drivers utilizing pickable
559 : : * ranges helpers.
560 : : */
561 : 0 : int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
562 : : unsigned int selector)
563 : : {
564 : : const struct regulator_linear_range *range;
565 : : int i;
566 : : unsigned int all_sels = 0;
567 : :
568 [ # # ]: 0 : if (!rdev->desc->n_linear_ranges) {
569 [ # # ]: 0 : BUG_ON(!rdev->desc->n_linear_ranges);
570 : : return -EINVAL;
571 : : }
572 : :
573 [ # # ]: 0 : for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
574 : : unsigned int sels_in_range;
575 : :
576 : 0 : range = &rdev->desc->linear_ranges[i];
577 : :
578 : 0 : sels_in_range = range->max_sel - range->min_sel;
579 : :
580 [ # # ]: 0 : if (all_sels + sels_in_range >= selector) {
581 : 0 : selector -= all_sels;
582 : 0 : return range->min_uV + (range->uV_step * selector);
583 : : }
584 : :
585 : 0 : all_sels += (sels_in_range + 1);
586 : : }
587 : :
588 : : return -EINVAL;
589 : : }
590 : : EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
591 : :
592 : : /**
593 : : * regulator_desc_list_voltage_linear_range - List voltages for linear ranges
594 : : *
595 : : * @desc: Regulator desc for regulator which volatges are to be listed
596 : : * @selector: Selector to convert into a voltage
597 : : *
598 : : * Regulators with a series of simple linear mappings between voltages
599 : : * and selectors who have set linear_ranges in the regulator descriptor
600 : : * can use this function prior regulator registration to list voltages.
601 : : * This is useful when voltages need to be listed during device-tree
602 : : * parsing.
603 : : */
604 : 0 : int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
605 : : unsigned int selector)
606 : : {
607 : : const struct regulator_linear_range *range;
608 : : int i;
609 : :
610 [ # # ]: 0 : if (!desc->n_linear_ranges) {
611 [ # # ]: 0 : BUG_ON(!desc->n_linear_ranges);
612 : : return -EINVAL;
613 : : }
614 : :
615 [ # # ]: 0 : for (i = 0; i < desc->n_linear_ranges; i++) {
616 : 0 : range = &desc->linear_ranges[i];
617 : :
618 [ # # # # ]: 0 : if (!(selector >= range->min_sel &&
619 : 0 : selector <= range->max_sel))
620 : 0 : continue;
621 : :
622 : 0 : selector -= range->min_sel;
623 : :
624 : 0 : return range->min_uV + (range->uV_step * selector);
625 : : }
626 : :
627 : : return -EINVAL;
628 : : }
629 : : EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range);
630 : :
631 : : /**
632 : : * regulator_list_voltage_linear_range - List voltages for linear ranges
633 : : *
634 : : * @rdev: Regulator device
635 : : * @selector: Selector to convert into a voltage
636 : : *
637 : : * Regulators with a series of simple linear mappings between voltages
638 : : * and selectors can set linear_ranges in the regulator descriptor and
639 : : * then use this function as their list_voltage() operation,
640 : : */
641 : 0 : int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
642 : : unsigned int selector)
643 : : {
644 : 0 : return regulator_desc_list_voltage_linear_range(rdev->desc, selector);
645 : : }
646 : : EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
647 : :
648 : : /**
649 : : * regulator_list_voltage_table - List voltages with table based mapping
650 : : *
651 : : * @rdev: Regulator device
652 : : * @selector: Selector to convert into a voltage
653 : : *
654 : : * Regulators with table based mapping between voltages and
655 : : * selectors can set volt_table in the regulator descriptor
656 : : * and then use this function as their list_voltage() operation.
657 : : */
658 : 0 : int regulator_list_voltage_table(struct regulator_dev *rdev,
659 : : unsigned int selector)
660 : : {
661 [ # # ]: 0 : if (!rdev->desc->volt_table) {
662 [ # # ]: 0 : BUG_ON(!rdev->desc->volt_table);
663 : : return -EINVAL;
664 : : }
665 : :
666 [ # # ]: 0 : if (selector >= rdev->desc->n_voltages)
667 : : return -EINVAL;
668 : :
669 : 0 : return rdev->desc->volt_table[selector];
670 : : }
671 : : EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
672 : :
673 : : /**
674 : : * regulator_set_bypass_regmap - Default set_bypass() using regmap
675 : : *
676 : : * @rdev: device to operate on.
677 : : * @enable: state to set.
678 : : */
679 : 0 : int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
680 : : {
681 : : unsigned int val;
682 : :
683 [ # # ]: 0 : if (enable) {
684 : 0 : val = rdev->desc->bypass_val_on;
685 [ # # ]: 0 : if (!val)
686 : 0 : val = rdev->desc->bypass_mask;
687 : : } else {
688 : 0 : val = rdev->desc->bypass_val_off;
689 : : }
690 : :
691 : 0 : return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
692 : : rdev->desc->bypass_mask, val);
693 : : }
694 : : EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
695 : :
696 : : /**
697 : : * regulator_set_soft_start_regmap - Default set_soft_start() using regmap
698 : : *
699 : : * @rdev: device to operate on.
700 : : */
701 : 0 : int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
702 : : {
703 : : unsigned int val;
704 : :
705 : 0 : val = rdev->desc->soft_start_val_on;
706 [ # # ]: 0 : if (!val)
707 : 0 : val = rdev->desc->soft_start_mask;
708 : :
709 : 0 : return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,
710 : : rdev->desc->soft_start_mask, val);
711 : : }
712 : : EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
713 : :
714 : : /**
715 : : * regulator_set_pull_down_regmap - Default set_pull_down() using regmap
716 : : *
717 : : * @rdev: device to operate on.
718 : : */
719 : 0 : int regulator_set_pull_down_regmap(struct regulator_dev *rdev)
720 : : {
721 : : unsigned int val;
722 : :
723 : 0 : val = rdev->desc->pull_down_val_on;
724 [ # # ]: 0 : if (!val)
725 : 0 : val = rdev->desc->pull_down_mask;
726 : :
727 : 0 : return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,
728 : : rdev->desc->pull_down_mask, val);
729 : : }
730 : : EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);
731 : :
732 : : /**
733 : : * regulator_get_bypass_regmap - Default get_bypass() using regmap
734 : : *
735 : : * @rdev: device to operate on.
736 : : * @enable: current state.
737 : : */
738 : 0 : int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
739 : : {
740 : : unsigned int val;
741 : 0 : unsigned int val_on = rdev->desc->bypass_val_on;
742 : : int ret;
743 : :
744 : 0 : ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
745 [ # # ]: 0 : if (ret != 0)
746 : : return ret;
747 : :
748 [ # # ]: 0 : if (!val_on)
749 : 0 : val_on = rdev->desc->bypass_mask;
750 : :
751 : 0 : *enable = (val & rdev->desc->bypass_mask) == val_on;
752 : :
753 : 0 : return 0;
754 : : }
755 : : EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
756 : :
757 : : /**
758 : : * regulator_set_active_discharge_regmap - Default set_active_discharge()
759 : : * using regmap
760 : : *
761 : : * @rdev: device to operate on.
762 : : * @enable: state to set, 0 to disable and 1 to enable.
763 : : */
764 : 0 : int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
765 : : bool enable)
766 : : {
767 : : unsigned int val;
768 : :
769 [ # # ]: 0 : if (enable)
770 : 0 : val = rdev->desc->active_discharge_on;
771 : : else
772 : 0 : val = rdev->desc->active_discharge_off;
773 : :
774 : 0 : return regmap_update_bits(rdev->regmap,
775 : : rdev->desc->active_discharge_reg,
776 : : rdev->desc->active_discharge_mask, val);
777 : : }
778 : : EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
779 : :
780 : : /**
781 : : * regulator_set_current_limit_regmap - set_current_limit for regmap users
782 : : *
783 : : * @rdev: regulator to operate on
784 : : * @min_uA: Lower bound for current limit
785 : : * @max_uA: Upper bound for current limit
786 : : *
787 : : * Regulators that use regmap for their register I/O can set curr_table,
788 : : * csel_reg and csel_mask fields in their descriptor and then use this
789 : : * as their set_current_limit operation, saving some code.
790 : : */
791 : 0 : int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
792 : : int min_uA, int max_uA)
793 : : {
794 : 0 : unsigned int n_currents = rdev->desc->n_current_limits;
795 : : int i, sel = -1;
796 : :
797 [ # # ]: 0 : if (n_currents == 0)
798 : : return -EINVAL;
799 : :
800 [ # # ]: 0 : if (rdev->desc->curr_table) {
801 : : const unsigned int *curr_table = rdev->desc->curr_table;
802 : 0 : bool ascend = curr_table[n_currents - 1] > curr_table[0];
803 : :
804 : : /* search for closest to maximum */
805 [ # # ]: 0 : if (ascend) {
806 [ # # ]: 0 : for (i = n_currents - 1; i >= 0; i--) {
807 [ # # # # ]: 0 : if (min_uA <= curr_table[i] &&
808 : 0 : curr_table[i] <= max_uA) {
809 : 0 : sel = i;
810 : 0 : break;
811 : : }
812 : : }
813 : : } else {
814 [ # # ]: 0 : for (i = 0; i < n_currents; i++) {
815 [ # # # # ]: 0 : if (min_uA <= curr_table[i] &&
816 : 0 : curr_table[i] <= max_uA) {
817 : 0 : sel = i;
818 : 0 : break;
819 : : }
820 : : }
821 : : }
822 : : }
823 : :
824 [ # # ]: 0 : if (sel < 0)
825 : : return -EINVAL;
826 : :
827 : 0 : sel <<= ffs(rdev->desc->csel_mask) - 1;
828 : :
829 : 0 : return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,
830 : : rdev->desc->csel_mask, sel);
831 : : }
832 : : EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap);
833 : :
834 : : /**
835 : : * regulator_get_current_limit_regmap - get_current_limit for regmap users
836 : : *
837 : : * @rdev: regulator to operate on
838 : : *
839 : : * Regulators that use regmap for their register I/O can set the
840 : : * csel_reg and csel_mask fields in their descriptor and then use this
841 : : * as their get_current_limit operation, saving some code.
842 : : */
843 : 0 : int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
844 : : {
845 : : unsigned int val;
846 : : int ret;
847 : :
848 : 0 : ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);
849 [ # # ]: 0 : if (ret != 0)
850 : : return ret;
851 : :
852 : 0 : val &= rdev->desc->csel_mask;
853 : 0 : val >>= ffs(rdev->desc->csel_mask) - 1;
854 : :
855 [ # # ]: 0 : if (rdev->desc->curr_table) {
856 [ # # ]: 0 : if (val >= rdev->desc->n_current_limits)
857 : : return -EINVAL;
858 : :
859 : 0 : return rdev->desc->curr_table[val];
860 : : }
861 : :
862 : : return -EINVAL;
863 : : }
864 : : EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
865 : :
866 : : /**
867 : : * regulator_bulk_set_supply_names - initialize the 'supply' fields in an array
868 : : * of regulator_bulk_data structs
869 : : *
870 : : * @consumers: array of regulator_bulk_data entries to initialize
871 : : * @supply_names: array of supply name strings
872 : : * @num_supplies: number of supply names to initialize
873 : : *
874 : : * Note: the 'consumers' array must be the size of 'num_supplies'.
875 : : */
876 : 0 : void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
877 : : const char *const *supply_names,
878 : : unsigned int num_supplies)
879 : : {
880 : : unsigned int i;
881 : :
882 [ # # ]: 0 : for (i = 0; i < num_supplies; i++)
883 : 0 : consumers[i].supply = supply_names[i];
884 : 0 : }
885 : : EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
886 : :
887 : : /**
888 : : * regulator_is_equal - test whether two regulators are the same
889 : : *
890 : : * @reg1: first regulator to operate on
891 : : * @reg2: second regulator to operate on
892 : : */
893 : 0 : bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
894 : : {
895 : 0 : return reg1->rdev == reg2->rdev;
896 : : }
897 : : EXPORT_SYMBOL_GPL(regulator_is_equal);
|