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