xref: /OK3568_Linux_fs/kernel/drivers/regulator/helpers.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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