blob: d2b9fc35931800958c92445632e3e297cc87e2c9 [file] [log] [blame]
Mark Brownc4a54b82013-08-06 01:31:28 +01001/*
2 * helpers.c -- Voltage/Current Regulator framework helper functions.
3 *
4 * Copyright 2007, 2008 Wolfson Microelectronics PLC.
5 * Copyright 2008 SlimLogic Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/err.h>
16#include <linux/delay.h>
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
19#include <linux/regulator/driver.h>
20#include <linux/module.h>
21
22/**
23 * regulator_is_enabled_regmap - standard is_enabled() for regmap users
24 *
25 * @rdev: regulator to operate on
26 *
27 * Regulators that use regmap for their register I/O can set the
28 * enable_reg and enable_mask fields in their descriptor and then use
29 * this as their is_enabled operation, saving some code.
30 */
31int regulator_is_enabled_regmap(struct regulator_dev *rdev)
32{
33 unsigned int val;
34 int ret;
35
36 ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
37 if (ret != 0)
38 return ret;
39
Carlo Caioneca5d1b32014-03-05 22:11:29 +010040 val &= rdev->desc->enable_mask;
41
42 if (rdev->desc->enable_is_inverted) {
43 if (rdev->desc->enable_val)
44 return val != rdev->desc->enable_val;
45 return val == 0;
46 } else {
47 if (rdev->desc->enable_val)
48 return val == rdev->desc->enable_val;
49 return val != 0;
50 }
Mark Brownc4a54b82013-08-06 01:31:28 +010051}
52EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
53
54/**
55 * regulator_enable_regmap - standard enable() for regmap users
56 *
57 * @rdev: regulator to operate on
58 *
59 * Regulators that use regmap for their register I/O can set the
60 * enable_reg and enable_mask fields in their descriptor and then use
61 * this as their enable() operation, saving some code.
62 */
63int regulator_enable_regmap(struct regulator_dev *rdev)
64{
65 unsigned int val;
66
Carlo Caioneca5d1b32014-03-05 22:11:29 +010067 if (rdev->desc->enable_is_inverted) {
68 val = rdev->desc->disable_val;
69 } else {
70 val = rdev->desc->enable_val;
71 if (!val)
72 val = rdev->desc->enable_mask;
73 }
Mark Brownc4a54b82013-08-06 01:31:28 +010074
75 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
76 rdev->desc->enable_mask, val);
77}
78EXPORT_SYMBOL_GPL(regulator_enable_regmap);
79
80/**
81 * regulator_disable_regmap - standard disable() for regmap users
82 *
83 * @rdev: regulator to operate on
84 *
85 * Regulators that use regmap for their register I/O can set the
86 * enable_reg and enable_mask fields in their descriptor and then use
87 * this as their disable() operation, saving some code.
88 */
89int regulator_disable_regmap(struct regulator_dev *rdev)
90{
91 unsigned int val;
92
Carlo Caioneca5d1b32014-03-05 22:11:29 +010093 if (rdev->desc->enable_is_inverted) {
94 val = rdev->desc->enable_val;
95 if (!val)
96 val = rdev->desc->enable_mask;
97 } else {
98 val = rdev->desc->disable_val;
99 }
Mark Brownc4a54b82013-08-06 01:31:28 +0100100
101 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
102 rdev->desc->enable_mask, val);
103}
104EXPORT_SYMBOL_GPL(regulator_disable_regmap);
105
Matti Vaittinen18e4b552018-09-14 11:31:36 +0300106static int regulator_range_selector_to_index(struct regulator_dev *rdev,
107 unsigned int rval)
108{
109 int i;
110
111 if (!rdev->desc->linear_range_selectors)
112 return -EINVAL;
113
114 rval &= rdev->desc->vsel_range_mask;
115
116 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
117 if (rdev->desc->linear_range_selectors[i] == rval)
118 return i;
119 }
120 return -EINVAL;
121}
122
123/**
124 * regulator_get_voltage_sel_pickable_regmap - pickable range get_voltage_sel
125 *
126 * @rdev: regulator to operate on
127 *
128 * Regulators that use regmap for their register I/O and use pickable
129 * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
130 * fields in their descriptor and then use this as their get_voltage_vsel
131 * operation, saving some code.
132 */
133int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
134{
135 unsigned int r_val;
136 int range;
137 unsigned int val;
138 int ret, i;
139 unsigned int voltages_in_range = 0;
140
141 if (!rdev->desc->linear_ranges)
142 return -EINVAL;
143
144 ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
145 if (ret != 0)
146 return ret;
147
148 ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &r_val);
149 if (ret != 0)
150 return ret;
151
152 val &= rdev->desc->vsel_mask;
153 val >>= ffs(rdev->desc->vsel_mask) - 1;
154
155 range = regulator_range_selector_to_index(rdev, r_val);
156 if (range < 0)
157 return -EINVAL;
158
159 for (i = 0; i < range; i++)
160 voltages_in_range += (rdev->desc->linear_ranges[i].max_sel -
161 rdev->desc->linear_ranges[i].min_sel) + 1;
162
163 return val + voltages_in_range;
164}
165EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
166
167/**
168 * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel
169 *
170 * @rdev: regulator to operate on
171 * @sel: Selector to set
172 *
173 * Regulators that use regmap for their register I/O and use pickable
174 * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
175 * fields in their descriptor and then use this as their set_voltage_vsel
176 * operation, saving some code.
177 */
178int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
179 unsigned int sel)
180{
181 unsigned int range;
182 int ret, i;
183 unsigned int voltages_in_range = 0;
184
185 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
186 voltages_in_range = (rdev->desc->linear_ranges[i].max_sel -
187 rdev->desc->linear_ranges[i].min_sel) + 1;
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[i];
200
201 if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
202 ret = regmap_update_bits(rdev->regmap,
203 rdev->desc->vsel_reg,
204 rdev->desc->vsel_range_mask |
205 rdev->desc->vsel_mask, sel | range);
206 } else {
207 ret = regmap_update_bits(rdev->regmap,
208 rdev->desc->vsel_range_reg,
209 rdev->desc->vsel_range_mask, range);
210 if (ret)
211 return ret;
212
213 ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
214 rdev->desc->vsel_mask, sel);
215 }
216
217 if (ret)
218 return ret;
219
220 if (rdev->desc->apply_bit)
221 ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
222 rdev->desc->apply_bit,
223 rdev->desc->apply_bit);
224 return ret;
225}
226EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap);
227
Mark Brownc4a54b82013-08-06 01:31:28 +0100228/**
229 * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
230 *
231 * @rdev: regulator to operate on
232 *
233 * Regulators that use regmap for their register I/O can set the
234 * vsel_reg and vsel_mask fields in their descriptor and then use this
235 * as their get_voltage_vsel operation, saving some code.
236 */
237int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
238{
239 unsigned int val;
240 int ret;
241
242 ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
243 if (ret != 0)
244 return ret;
245
246 val &= rdev->desc->vsel_mask;
247 val >>= ffs(rdev->desc->vsel_mask) - 1;
248
249 return val;
250}
251EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
252
253/**
254 * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
255 *
256 * @rdev: regulator to operate on
257 * @sel: Selector to set
258 *
259 * Regulators that use regmap for their register I/O can set the
260 * vsel_reg and vsel_mask fields in their descriptor and then use this
261 * as their set_voltage_vsel operation, saving some code.
262 */
263int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
264{
265 int ret;
266
267 sel <<= ffs(rdev->desc->vsel_mask) - 1;
268
269 ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
270 rdev->desc->vsel_mask, sel);
271 if (ret)
272 return ret;
273
274 if (rdev->desc->apply_bit)
275 ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
276 rdev->desc->apply_bit,
277 rdev->desc->apply_bit);
278 return ret;
279}
280EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
281
282/**
283 * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
284 *
285 * @rdev: Regulator to operate on
286 * @min_uV: Lower bound for voltage
287 * @max_uV: Upper bound for voltage
288 *
289 * Drivers implementing set_voltage_sel() and list_voltage() can use
290 * this as their map_voltage() operation. It will find a suitable
291 * voltage by calling list_voltage() until it gets something in bounds
292 * for the requested voltages.
293 */
294int regulator_map_voltage_iterate(struct regulator_dev *rdev,
295 int min_uV, int max_uV)
296{
297 int best_val = INT_MAX;
298 int selector = 0;
299 int i, ret;
300
301 /* Find the smallest voltage that falls within the specified
302 * range.
303 */
304 for (i = 0; i < rdev->desc->n_voltages; i++) {
305 ret = rdev->desc->ops->list_voltage(rdev, i);
306 if (ret < 0)
307 continue;
308
309 if (ret < best_val && ret >= min_uV && ret <= max_uV) {
310 best_val = ret;
311 selector = i;
312 }
313 }
314
315 if (best_val != INT_MAX)
316 return selector;
317 else
318 return -EINVAL;
319}
320EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
321
322/**
323 * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
324 *
325 * @rdev: Regulator to operate on
326 * @min_uV: Lower bound for voltage
327 * @max_uV: Upper bound for voltage
328 *
329 * Drivers that have ascendant voltage list can use this as their
330 * map_voltage() operation.
331 */
332int regulator_map_voltage_ascend(struct regulator_dev *rdev,
333 int min_uV, int max_uV)
334{
335 int i, ret;
336
337 for (i = 0; i < rdev->desc->n_voltages; i++) {
338 ret = rdev->desc->ops->list_voltage(rdev, i);
339 if (ret < 0)
340 continue;
341
342 if (ret > max_uV)
343 break;
344
345 if (ret >= min_uV && ret <= max_uV)
346 return i;
347 }
348
349 return -EINVAL;
350}
351EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
352
353/**
354 * regulator_map_voltage_linear - map_voltage() for simple linear mappings
355 *
356 * @rdev: Regulator to operate on
357 * @min_uV: Lower bound for voltage
358 * @max_uV: Upper bound for voltage
359 *
360 * Drivers providing min_uV and uV_step in their regulator_desc can
361 * use this as their map_voltage() operation.
362 */
363int regulator_map_voltage_linear(struct regulator_dev *rdev,
364 int min_uV, int max_uV)
365{
366 int ret, voltage;
367
368 /* Allow uV_step to be 0 for fixed voltage */
369 if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
370 if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
371 return 0;
372 else
373 return -EINVAL;
374 }
375
376 if (!rdev->desc->uV_step) {
377 BUG_ON(!rdev->desc->uV_step);
378 return -EINVAL;
379 }
380
381 if (min_uV < rdev->desc->min_uV)
382 min_uV = rdev->desc->min_uV;
383
384 ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
385 if (ret < 0)
386 return ret;
387
388 ret += rdev->desc->linear_min_sel;
389
390 /* Map back into a voltage to verify we're still in bounds */
391 voltage = rdev->desc->ops->list_voltage(rdev, ret);
392 if (voltage < min_uV || voltage > max_uV)
393 return -EINVAL;
394
395 return ret;
396}
397EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
398
399/**
Krzysztof Kozlowski43343f82015-04-19 15:34:19 +0900400 * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges
Mark Brownc4a54b82013-08-06 01:31:28 +0100401 *
402 * @rdev: Regulator to operate on
403 * @min_uV: Lower bound for voltage
404 * @max_uV: Upper bound for voltage
405 *
406 * Drivers providing linear_ranges in their descriptor can use this as
407 * their map_voltage() callback.
408 */
409int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
410 int min_uV, int max_uV)
411{
412 const struct regulator_linear_range *range;
413 int ret = -EINVAL;
414 int voltage, i;
415
416 if (!rdev->desc->n_linear_ranges) {
417 BUG_ON(!rdev->desc->n_linear_ranges);
418 return -EINVAL;
419 }
420
421 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
Axel Line277e652013-10-11 09:30:24 +0800422 int linear_max_uV;
Mark Brownc4a54b82013-08-06 01:31:28 +0100423
Axel Line277e652013-10-11 09:30:24 +0800424 range = &rdev->desc->linear_ranges[i];
425 linear_max_uV = range->min_uV +
426 (range->max_sel - range->min_sel) * range->uV_step;
427
428 if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
Mark Brownc4a54b82013-08-06 01:31:28 +0100429 continue;
430
431 if (min_uV <= range->min_uV)
432 min_uV = range->min_uV;
433
434 /* range->uV_step == 0 means fixed voltage range */
435 if (range->uV_step == 0) {
436 ret = 0;
437 } else {
438 ret = DIV_ROUND_UP(min_uV - range->min_uV,
439 range->uV_step);
440 if (ret < 0)
441 return ret;
442 }
443
444 ret += range->min_sel;
445
446 break;
447 }
448
449 if (i == rdev->desc->n_linear_ranges)
450 return -EINVAL;
451
452 /* Map back into a voltage to verify we're still in bounds */
453 voltage = rdev->desc->ops->list_voltage(rdev, ret);
454 if (voltage < min_uV || voltage > max_uV)
455 return -EINVAL;
456
457 return ret;
458}
459EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
460
461/**
Matti Vaittinen18e4b552018-09-14 11:31:36 +0300462 * regulator_map_voltage_pickable_linear_range - map_voltage, pickable ranges
463 *
464 * @rdev: Regulator to operate on
465 * @min_uV: Lower bound for voltage
466 * @max_uV: Upper bound for voltage
467 *
468 * Drivers providing pickable linear_ranges in their descriptor can use
469 * this as their map_voltage() callback.
470 */
471int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
472 int min_uV, int max_uV)
473{
474 const struct regulator_linear_range *range;
475 int ret = -EINVAL;
476 int voltage, i;
477 unsigned int selector = 0;
478
479 if (!rdev->desc->n_linear_ranges) {
480 BUG_ON(!rdev->desc->n_linear_ranges);
481 return -EINVAL;
482 }
483
484 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
485 int linear_max_uV;
486
487 range = &rdev->desc->linear_ranges[i];
488 linear_max_uV = range->min_uV +
489 (range->max_sel - range->min_sel) * range->uV_step;
490
491 if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) {
492 selector += (range->max_sel - range->min_sel + 1);
493 continue;
494 }
495
496 if (min_uV <= range->min_uV)
497 min_uV = range->min_uV;
498
499 /* range->uV_step == 0 means fixed voltage range */
500 if (range->uV_step == 0) {
501 ret = 0;
502 } else {
503 ret = DIV_ROUND_UP(min_uV - range->min_uV,
504 range->uV_step);
505 if (ret < 0)
506 return ret;
507 }
508
509 ret += selector;
510
511 voltage = rdev->desc->ops->list_voltage(rdev, ret);
512
513 /*
514 * Map back into a voltage to verify we're still in bounds.
515 * We may have overlapping voltage ranges. Hence we don't
516 * exit but retry until we have checked all ranges.
517 */
518 if (voltage < min_uV || voltage > max_uV)
519 selector += (range->max_sel - range->min_sel + 1);
520 else
521 break;
522 }
523
524 if (i == rdev->desc->n_linear_ranges)
525 return -EINVAL;
526
527 return ret;
528}
529EXPORT_SYMBOL_GPL(regulator_map_voltage_pickable_linear_range);
530
531/**
Axel Lind295f762013-08-09 15:29:27 +0800532 * regulator_list_voltage_linear - List voltages with simple calculation
533 *
534 * @rdev: Regulator device
535 * @selector: Selector to convert into a voltage
536 *
537 * Regulators with a simple linear mapping between voltages and
538 * selectors can set min_uV and uV_step in the regulator descriptor
539 * and then use this function as their list_voltage() operation,
540 */
541int regulator_list_voltage_linear(struct regulator_dev *rdev,
542 unsigned int selector)
543{
544 if (selector >= rdev->desc->n_voltages)
545 return -EINVAL;
546 if (selector < rdev->desc->linear_min_sel)
547 return 0;
548
549 selector -= rdev->desc->linear_min_sel;
550
551 return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
552}
553EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
554
555/**
Matti Vaittinen18e4b552018-09-14 11:31:36 +0300556 * regulator_list_voltage_pickable_linear_range - pickable range list voltages
557 *
558 * @rdev: Regulator device
559 * @selector: Selector to convert into a voltage
560 *
561 * list_voltage() operation, intended to be used by drivers utilizing pickable
562 * ranges helpers.
563 */
564int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
565 unsigned int selector)
566{
567 const struct regulator_linear_range *range;
568 int i;
569 unsigned int all_sels = 0;
570
571 if (!rdev->desc->n_linear_ranges) {
572 BUG_ON(!rdev->desc->n_linear_ranges);
573 return -EINVAL;
574 }
575
576 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
577 unsigned int sels_in_range;
578
579 range = &rdev->desc->linear_ranges[i];
580
581 sels_in_range = range->max_sel - range->min_sel;
582
583 if (all_sels + sels_in_range >= selector) {
584 selector -= all_sels;
585 return range->min_uV + (range->uV_step * selector);
586 }
587
588 all_sels += (sels_in_range + 1);
589 }
590
591 return -EINVAL;
592}
593EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
594
595/**
Axel Lind295f762013-08-09 15:29:27 +0800596 * regulator_list_voltage_linear_range - List voltages for linear ranges
597 *
598 * @rdev: Regulator device
599 * @selector: Selector to convert into a voltage
600 *
601 * Regulators with a series of simple linear mappings between voltages
602 * and selectors can set linear_ranges in the regulator descriptor and
603 * then use this function as their list_voltage() operation,
604 */
605int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
606 unsigned int selector)
607{
608 const struct regulator_linear_range *range;
609 int i;
610
611 if (!rdev->desc->n_linear_ranges) {
612 BUG_ON(!rdev->desc->n_linear_ranges);
613 return -EINVAL;
614 }
615
616 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
617 range = &rdev->desc->linear_ranges[i];
618
619 if (!(selector >= range->min_sel &&
620 selector <= range->max_sel))
621 continue;
622
623 selector -= range->min_sel;
624
625 return range->min_uV + (range->uV_step * selector);
626 }
627
628 return -EINVAL;
629}
630EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
631
632/**
633 * regulator_list_voltage_table - List voltages with table based mapping
634 *
635 * @rdev: Regulator device
636 * @selector: Selector to convert into a voltage
637 *
638 * Regulators with table based mapping between voltages and
639 * selectors can set volt_table in the regulator descriptor
640 * and then use this function as their list_voltage() operation.
641 */
642int regulator_list_voltage_table(struct regulator_dev *rdev,
643 unsigned int selector)
644{
645 if (!rdev->desc->volt_table) {
646 BUG_ON(!rdev->desc->volt_table);
647 return -EINVAL;
648 }
649
650 if (selector >= rdev->desc->n_voltages)
651 return -EINVAL;
652
653 return rdev->desc->volt_table[selector];
654}
655EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
656
657/**
Mark Brownc4a54b82013-08-06 01:31:28 +0100658 * regulator_set_bypass_regmap - Default set_bypass() using regmap
659 *
660 * @rdev: device to operate on.
661 * @enable: state to set.
662 */
663int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
664{
665 unsigned int val;
666
Carlo Caioneca5d1b32014-03-05 22:11:29 +0100667 if (enable) {
668 val = rdev->desc->bypass_val_on;
669 if (!val)
670 val = rdev->desc->bypass_mask;
671 } else {
672 val = rdev->desc->bypass_val_off;
673 }
Mark Brownc4a54b82013-08-06 01:31:28 +0100674
675 return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
676 rdev->desc->bypass_mask, val);
677}
678EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
679
680/**
Charles Keepaxa7a453f2017-03-28 15:14:40 +0100681 * regulator_set_soft_start_regmap - Default set_soft_start() using regmap
682 *
683 * @rdev: device to operate on.
684 */
685int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
686{
687 unsigned int val;
688
689 val = rdev->desc->soft_start_val_on;
690 if (!val)
691 val = rdev->desc->soft_start_mask;
692
693 return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,
694 rdev->desc->soft_start_mask, val);
695}
696EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
697
698/**
Charles Keepaxf7d37bc2017-03-28 15:14:41 +0100699 * regulator_set_pull_down_regmap - Default set_pull_down() using regmap
700 *
701 * @rdev: device to operate on.
702 */
703int regulator_set_pull_down_regmap(struct regulator_dev *rdev)
704{
705 unsigned int val;
706
707 val = rdev->desc->pull_down_val_on;
708 if (!val)
709 val = rdev->desc->pull_down_mask;
710
711 return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,
712 rdev->desc->pull_down_mask, val);
713}
714EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);
715
716/**
Mark Brownc4a54b82013-08-06 01:31:28 +0100717 * regulator_get_bypass_regmap - Default get_bypass() using regmap
718 *
719 * @rdev: device to operate on.
720 * @enable: current state.
721 */
722int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
723{
724 unsigned int val;
Charles Keepax85b03742016-11-10 10:45:18 +0000725 unsigned int val_on = rdev->desc->bypass_val_on;
Mark Brownc4a54b82013-08-06 01:31:28 +0100726 int ret;
727
728 ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
729 if (ret != 0)
730 return ret;
731
Charles Keepax85b03742016-11-10 10:45:18 +0000732 if (!val_on)
733 val_on = rdev->desc->bypass_mask;
734
735 *enable = (val & rdev->desc->bypass_mask) == val_on;
Mark Brownc4a54b82013-08-06 01:31:28 +0100736
737 return 0;
738}
739EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
Laxman Dewangan354794d2016-03-02 16:24:47 +0530740
741/**
742 * regulator_set_active_discharge_regmap - Default set_active_discharge()
743 * using regmap
744 *
745 * @rdev: device to operate on.
746 * @enable: state to set, 0 to disable and 1 to enable.
747 */
748int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
749 bool enable)
750{
751 unsigned int val;
752
753 if (enable)
754 val = rdev->desc->active_discharge_on;
755 else
756 val = rdev->desc->active_discharge_off;
757
758 return regmap_update_bits(rdev->regmap,
759 rdev->desc->active_discharge_reg,
760 rdev->desc->active_discharge_mask, val);
761}
762EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);