Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
f2c6203f MB |
2 | // |
3 | // helpers.c -- Voltage/Current Regulator framework helper functions. | |
4 | // | |
5 | // Copyright 2007, 2008 Wolfson Microelectronics PLC. | |
6 | // Copyright 2008 SlimLogic Ltd. | |
c4a54b8d | 7 | |
269cb04b | 8 | #include <linux/bitops.h> |
c4a54b8d | 9 | #include <linux/delay.h> |
269cb04b CYT |
10 | #include <linux/err.h> |
11 | #include <linux/export.h> | |
12 | #include <linux/kernel.h> | |
c4a54b8d MB |
13 | #include <linux/regmap.h> |
14 | #include <linux/regulator/consumer.h> | |
15 | #include <linux/regulator/driver.h> | |
c4a54b8d | 16 | |
b059b7e0 MV |
17 | #include "internal.h" |
18 | ||
c4a54b8d MB |
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(rdev->regmap, rdev->desc->enable_reg, &val); | |
34 | if (ret != 0) | |
35 | return ret; | |
36 | ||
ca5d1b35 CC |
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 | } | |
c4a54b8d MB |
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 | ||
ca5d1b35 CC |
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 | } | |
c4a54b8d MB |
71 | |
72 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
73 | 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 | ||
ca5d1b35 CC |
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 | } | |
c4a54b8d MB |
97 | |
98 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
99 | rdev->desc->enable_mask, val); | |
100 | } | |
101 | EXPORT_SYMBOL_GPL(regulator_disable_regmap); | |
102 | ||
18e4b55f MV |
103 | static int regulator_range_selector_to_index(struct regulator_dev *rdev, |
104 | unsigned int rval) | |
105 | { | |
106 | int i; | |
107 | ||
269cb04b | 108 | if (!rdev->desc->linear_range_selectors_bitfield) |
18e4b55f MV |
109 | return -EINVAL; |
110 | ||
111 | rval &= rdev->desc->vsel_range_mask; | |
269cb04b | 112 | rval >>= ffs(rdev->desc->vsel_range_mask) - 1; |
18e4b55f MV |
113 | |
114 | for (i = 0; i < rdev->desc->n_linear_ranges; i++) { | |
269cb04b | 115 | if (rdev->desc->linear_range_selectors_bitfield[i] == rval) |
18e4b55f MV |
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; | |
60ab7f41 MV |
136 | int ret; |
137 | unsigned int voltages = 0; | |
138 | const struct linear_range *r = rdev->desc->linear_ranges; | |
18e4b55f | 139 | |
60ab7f41 | 140 | if (!r) |
18e4b55f MV |
141 | return -EINVAL; |
142 | ||
143 | ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); | |
144 | if (ret != 0) | |
145 | return ret; | |
146 | ||
147 | ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &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, r_val); | |
155 | if (range < 0) | |
156 | return -EINVAL; | |
157 | ||
60ab7f41 | 158 | voltages = linear_range_values_in_range_array(r, range); |
18e4b55f | 159 | |
60ab7f41 | 160 | return val + voltages; |
18e4b55f MV |
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++) { | |
60ab7f41 MV |
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 | ||
18e4b55f MV |
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 | ||
269cb04b | 199 | range = rdev->desc->linear_range_selectors_bitfield[i]; |
6223e073 | 200 | range <<= ffs(rdev->desc->vsel_range_mask) - 1; |
18e4b55f MV |
201 | |
202 | if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) { | |
203 | ret = regmap_update_bits(rdev->regmap, | |
204 | rdev->desc->vsel_reg, | |
205 | rdev->desc->vsel_range_mask | | |
206 | rdev->desc->vsel_mask, sel | range); | |
207 | } else { | |
208 | ret = regmap_update_bits(rdev->regmap, | |
209 | rdev->desc->vsel_range_reg, | |
210 | rdev->desc->vsel_range_mask, range); | |
211 | if (ret) | |
212 | return ret; | |
213 | ||
214 | ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, | |
215 | rdev->desc->vsel_mask, sel); | |
216 | } | |
217 | ||
218 | if (ret) | |
219 | return ret; | |
220 | ||
221 | if (rdev->desc->apply_bit) | |
222 | ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, | |
223 | rdev->desc->apply_bit, | |
224 | rdev->desc->apply_bit); | |
225 | return ret; | |
226 | } | |
227 | EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap); | |
228 | ||
c4a54b8d MB |
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(rdev->regmap, rdev->desc->vsel_reg, &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(rdev->regmap, rdev->desc->vsel_reg, | |
271 | rdev->desc->vsel_mask, sel); | |
272 | if (ret) | |
273 | return ret; | |
274 | ||
275 | if (rdev->desc->apply_bit) | |
276 | ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, | |
277 | rdev->desc->apply_bit, | |
278 | 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 | /** | |
43343f8d | 401 | * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges |
c4a54b8d MB |
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 | { | |
60ab7f41 | 413 | const struct linear_range *range; |
c4a54b8d | 414 | int ret = -EINVAL; |
60ab7f41 MV |
415 | unsigned int sel; |
416 | bool found; | |
c4a54b8d MB |
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 | ||
60ab7f41 MV |
427 | ret = linear_range_get_selector_high(range, min_uV, &sel, |
428 | &found); | |
429 | if (ret) | |
c4a54b8d | 430 | continue; |
60ab7f41 | 431 | ret = sel; |
c4a54b8d | 432 | |
e7d80b6b MV |
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 | */ | |
60ab7f41 | 437 | voltage = rdev->desc->ops->list_voltage(rdev, sel); |
e7d80b6b MV |
438 | if (voltage >= min_uV && voltage <= max_uV) |
439 | break; | |
c4a54b8d MB |
440 | } |
441 | ||
442 | if (i == rdev->desc->n_linear_ranges) | |
443 | return -EINVAL; | |
444 | ||
c4a54b8d MB |
445 | return ret; |
446 | } | |
447 | EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range); | |
448 | ||
18e4b55f MV |
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 | { | |
60ab7f41 | 462 | const struct linear_range *range; |
18e4b55f MV |
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; | |
60ab7f41 MV |
474 | bool found; |
475 | unsigned int sel; | |
18e4b55f MV |
476 | |
477 | range = &rdev->desc->linear_ranges[i]; | |
60ab7f41 | 478 | linear_max_uV = linear_range_get_max_value(range); |
18e4b55f | 479 | |
60ab7f41 MV |
480 | if (!(min_uV <= linear_max_uV && max_uV >= range->min)) { |
481 | selector += linear_range_values_in_range(range); | |
18e4b55f MV |
482 | continue; |
483 | } | |
484 | ||
60ab7f41 MV |
485 | ret = linear_range_get_selector_high(range, min_uV, &sel, |
486 | &found); | |
487 | if (ret) { | |
488 | selector += linear_range_values_in_range(range); | |
489 | continue; | |
18e4b55f MV |
490 | } |
491 | ||
92919679 | 492 | ret = selector + sel - range->min_sel; |
18e4b55f MV |
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) | |
60ab7f41 | 502 | selector += linear_range_values_in_range(range); |
18e4b55f MV |
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 | ||
e3baacf5 MV |
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 | ||
d295f767 AL |
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 | { | |
e3baacf5 | 554 | return regulator_desc_list_voltage_linear(rdev->desc, selector); |
d295f767 AL |
555 | } |
556 | EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); | |
557 | ||
18e4b55f MV |
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 | { | |
60ab7f41 | 570 | const struct linear_range *range; |
18e4b55f MV |
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++) { | |
60ab7f41 | 580 | unsigned int sel_indexes; |
18e4b55f MV |
581 | |
582 | range = &rdev->desc->linear_ranges[i]; | |
583 | ||
60ab7f41 | 584 | sel_indexes = linear_range_values_in_range(range) - 1; |
18e4b55f | 585 | |
60ab7f41 | 586 | if (all_sels + sel_indexes >= selector) { |
18e4b55f | 587 | selector -= all_sels; |
60ab7f41 MV |
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); | |
18e4b55f MV |
599 | } |
600 | ||
60ab7f41 | 601 | all_sels += (sel_indexes + 1); |
18e4b55f MV |
602 | } |
603 | ||
604 | return -EINVAL; | |
605 | } | |
606 | EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range); | |
607 | ||
d295f767 | 608 | /** |
6a47b4da | 609 | * regulator_desc_list_voltage_linear_range - List voltages for linear ranges |
d295f767 | 610 | * |
6a47b4da | 611 | * @desc: Regulator desc for regulator which volatges are to be listed |
d295f767 AL |
612 | * @selector: Selector to convert into a voltage |
613 | * | |
614 | * Regulators with a series of simple linear mappings between voltages | |
6a47b4da MV |
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. | |
d295f767 | 619 | */ |
6a47b4da MV |
620 | int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc, |
621 | unsigned int selector) | |
d295f767 | 622 | { |
60ab7f41 MV |
623 | unsigned int val; |
624 | int ret; | |
d295f767 | 625 | |
60ab7f41 | 626 | BUG_ON(!desc->n_linear_ranges); |
d295f767 | 627 | |
60ab7f41 MV |
628 | ret = linear_range_get_value_array(desc->linear_ranges, |
629 | desc->n_linear_ranges, selector, | |
630 | &val); | |
631 | if (ret) | |
632 | return ret; | |
d295f767 | 633 | |
60ab7f41 | 634 | return val; |
d295f767 | 635 | } |
6a47b4da MV |
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 | } | |
d295f767 AL |
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 | ||
55cca739 | 673 | if (selector >= rdev->desc->n_voltages) |
d295f767 | 674 | return -EINVAL; |
55cca739 CB |
675 | if (selector < rdev->desc->linear_min_sel) |
676 | return 0; | |
d295f767 AL |
677 | |
678 | return rdev->desc->volt_table[selector]; | |
679 | } | |
680 | EXPORT_SYMBOL_GPL(regulator_list_voltage_table); | |
681 | ||
c4a54b8d MB |
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 | ||
ca5d1b35 CC |
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 | } | |
c4a54b8d MB |
699 | |
700 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | |
701 | rdev->desc->bypass_mask, val); | |
702 | } | |
703 | EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); | |
704 | ||
a7a453f5 CK |
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(rdev->regmap, rdev->desc->soft_start_reg, | |
719 | rdev->desc->soft_start_mask, val); | |
720 | } | |
721 | EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap); | |
722 | ||
f7d37bc3 CK |
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(rdev->regmap, rdev->desc->pull_down_reg, | |
737 | rdev->desc->pull_down_mask, val); | |
738 | } | |
739 | EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap); | |
740 | ||
c4a54b8d MB |
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; | |
85b03744 | 750 | unsigned int val_on = rdev->desc->bypass_val_on; |
c4a54b8d MB |
751 | int ret; |
752 | ||
753 | ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); | |
754 | if (ret != 0) | |
755 | return ret; | |
756 | ||
85b03744 CK |
757 | if (!val_on) |
758 | val_on = rdev->desc->bypass_mask; | |
759 | ||
760 | *enable = (val & rdev->desc->bypass_mask) == val_on; | |
c4a54b8d MB |
761 | |
762 | return 0; | |
763 | } | |
764 | EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); | |
354794da LD |
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(rdev->regmap, | |
784 | rdev->desc->active_discharge_reg, | |
785 | rdev->desc->active_discharge_mask, val); | |
786 | } | |
787 | EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap); | |
a32e0c77 AL |
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(rdev->regmap, rdev->desc->csel_reg, | |
839 | rdev->desc->csel_mask, 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(rdev->regmap, rdev->desc->csel_reg, &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); | |
d0087e72 BG |
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); | |
b059b7e0 MV |
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); | |
fb8fee9e | 907 | |
431cb97b SR |
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) | |
fb8fee9e MV |
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 | } | |
431cb97b | 952 | EXPORT_SYMBOL_GPL(regulator_find_closest_bigger); |
fb8fee9e MV |
953 | |
954 | /** | |
955 | * regulator_set_ramp_delay_regmap - set_ramp_delay() helper | |
956 | * | |
957 | * @rdev: regulator to operate on | |
d3b555e5 | 958 | * @ramp_delay: ramp-rate value given in units V/S (uV/uS) |
fb8fee9e MV |
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 | ||
687c9e3b | 969 | if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table)) |
fb8fee9e MV |
970 | return -EINVAL; |
971 | ||
431cb97b SR |
972 | ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table, |
973 | rdev->desc->n_ramp_values, &sel); | |
fb8fee9e MV |
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(rdev->regmap, rdev->desc->ramp_reg, | |
984 | rdev->desc->ramp_mask, sel); | |
985 | } | |
986 | EXPORT_SYMBOL_GPL(regulator_set_ramp_delay_regmap); |