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