Commit | Line | Data |
---|---|---|
c4a54b8d MB |
1 | /* |
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 | */ | |
31 | int 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 | ||
ca5d1b35 CC |
40 | 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 | } | |
c4a54b8d MB |
51 | } |
52 | EXPORT_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 | */ | |
63 | int regulator_enable_regmap(struct regulator_dev *rdev) | |
64 | { | |
65 | unsigned int val; | |
66 | ||
ca5d1b35 CC |
67 | 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 | } | |
c4a54b8d MB |
74 | |
75 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
76 | rdev->desc->enable_mask, val); | |
77 | } | |
78 | EXPORT_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 | */ | |
89 | int regulator_disable_regmap(struct regulator_dev *rdev) | |
90 | { | |
91 | unsigned int val; | |
92 | ||
ca5d1b35 CC |
93 | 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 | } | |
c4a54b8d MB |
100 | |
101 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
102 | rdev->desc->enable_mask, val); | |
103 | } | |
104 | EXPORT_SYMBOL_GPL(regulator_disable_regmap); | |
105 | ||
106 | /** | |
107 | * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users | |
108 | * | |
109 | * @rdev: regulator to operate on | |
110 | * | |
111 | * Regulators that use regmap for their register I/O can set the | |
112 | * vsel_reg and vsel_mask fields in their descriptor and then use this | |
113 | * as their get_voltage_vsel operation, saving some code. | |
114 | */ | |
115 | int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) | |
116 | { | |
117 | unsigned int val; | |
118 | int ret; | |
119 | ||
120 | ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); | |
121 | if (ret != 0) | |
122 | return ret; | |
123 | ||
124 | val &= rdev->desc->vsel_mask; | |
125 | val >>= ffs(rdev->desc->vsel_mask) - 1; | |
126 | ||
127 | return val; | |
128 | } | |
129 | EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); | |
130 | ||
131 | /** | |
132 | * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users | |
133 | * | |
134 | * @rdev: regulator to operate on | |
135 | * @sel: Selector to set | |
136 | * | |
137 | * Regulators that use regmap for their register I/O can set the | |
138 | * vsel_reg and vsel_mask fields in their descriptor and then use this | |
139 | * as their set_voltage_vsel operation, saving some code. | |
140 | */ | |
141 | int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) | |
142 | { | |
143 | int ret; | |
144 | ||
145 | sel <<= ffs(rdev->desc->vsel_mask) - 1; | |
146 | ||
147 | ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, | |
148 | rdev->desc->vsel_mask, sel); | |
149 | if (ret) | |
150 | return ret; | |
151 | ||
152 | if (rdev->desc->apply_bit) | |
153 | ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, | |
154 | rdev->desc->apply_bit, | |
155 | rdev->desc->apply_bit); | |
156 | return ret; | |
157 | } | |
158 | EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); | |
159 | ||
160 | /** | |
161 | * regulator_map_voltage_iterate - map_voltage() based on list_voltage() | |
162 | * | |
163 | * @rdev: Regulator to operate on | |
164 | * @min_uV: Lower bound for voltage | |
165 | * @max_uV: Upper bound for voltage | |
166 | * | |
167 | * Drivers implementing set_voltage_sel() and list_voltage() can use | |
168 | * this as their map_voltage() operation. It will find a suitable | |
169 | * voltage by calling list_voltage() until it gets something in bounds | |
170 | * for the requested voltages. | |
171 | */ | |
172 | int regulator_map_voltage_iterate(struct regulator_dev *rdev, | |
173 | int min_uV, int max_uV) | |
174 | { | |
175 | int best_val = INT_MAX; | |
176 | int selector = 0; | |
177 | int i, ret; | |
178 | ||
179 | /* Find the smallest voltage that falls within the specified | |
180 | * range. | |
181 | */ | |
182 | for (i = 0; i < rdev->desc->n_voltages; i++) { | |
183 | ret = rdev->desc->ops->list_voltage(rdev, i); | |
184 | if (ret < 0) | |
185 | continue; | |
186 | ||
187 | if (ret < best_val && ret >= min_uV && ret <= max_uV) { | |
188 | best_val = ret; | |
189 | selector = i; | |
190 | } | |
191 | } | |
192 | ||
193 | if (best_val != INT_MAX) | |
194 | return selector; | |
195 | else | |
196 | return -EINVAL; | |
197 | } | |
198 | EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate); | |
199 | ||
200 | /** | |
201 | * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list | |
202 | * | |
203 | * @rdev: Regulator to operate on | |
204 | * @min_uV: Lower bound for voltage | |
205 | * @max_uV: Upper bound for voltage | |
206 | * | |
207 | * Drivers that have ascendant voltage list can use this as their | |
208 | * map_voltage() operation. | |
209 | */ | |
210 | int regulator_map_voltage_ascend(struct regulator_dev *rdev, | |
211 | int min_uV, int max_uV) | |
212 | { | |
213 | int i, ret; | |
214 | ||
215 | for (i = 0; i < rdev->desc->n_voltages; i++) { | |
216 | ret = rdev->desc->ops->list_voltage(rdev, i); | |
217 | if (ret < 0) | |
218 | continue; | |
219 | ||
220 | if (ret > max_uV) | |
221 | break; | |
222 | ||
223 | if (ret >= min_uV && ret <= max_uV) | |
224 | return i; | |
225 | } | |
226 | ||
227 | return -EINVAL; | |
228 | } | |
229 | EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend); | |
230 | ||
231 | /** | |
232 | * regulator_map_voltage_linear - map_voltage() for simple linear mappings | |
233 | * | |
234 | * @rdev: Regulator to operate on | |
235 | * @min_uV: Lower bound for voltage | |
236 | * @max_uV: Upper bound for voltage | |
237 | * | |
238 | * Drivers providing min_uV and uV_step in their regulator_desc can | |
239 | * use this as their map_voltage() operation. | |
240 | */ | |
241 | int regulator_map_voltage_linear(struct regulator_dev *rdev, | |
242 | int min_uV, int max_uV) | |
243 | { | |
244 | int ret, voltage; | |
245 | ||
246 | /* Allow uV_step to be 0 for fixed voltage */ | |
247 | if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { | |
248 | if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) | |
249 | return 0; | |
250 | else | |
251 | return -EINVAL; | |
252 | } | |
253 | ||
254 | if (!rdev->desc->uV_step) { | |
255 | BUG_ON(!rdev->desc->uV_step); | |
256 | return -EINVAL; | |
257 | } | |
258 | ||
259 | if (min_uV < rdev->desc->min_uV) | |
260 | min_uV = rdev->desc->min_uV; | |
261 | ||
262 | ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); | |
263 | if (ret < 0) | |
264 | return ret; | |
265 | ||
266 | ret += rdev->desc->linear_min_sel; | |
267 | ||
268 | /* Map back into a voltage to verify we're still in bounds */ | |
269 | voltage = rdev->desc->ops->list_voltage(rdev, ret); | |
270 | if (voltage < min_uV || voltage > max_uV) | |
271 | return -EINVAL; | |
272 | ||
273 | return ret; | |
274 | } | |
275 | EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); | |
276 | ||
277 | /** | |
43343f8d | 278 | * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges |
c4a54b8d MB |
279 | * |
280 | * @rdev: Regulator to operate on | |
281 | * @min_uV: Lower bound for voltage | |
282 | * @max_uV: Upper bound for voltage | |
283 | * | |
284 | * Drivers providing linear_ranges in their descriptor can use this as | |
285 | * their map_voltage() callback. | |
286 | */ | |
287 | int regulator_map_voltage_linear_range(struct regulator_dev *rdev, | |
288 | int min_uV, int max_uV) | |
289 | { | |
290 | const struct regulator_linear_range *range; | |
291 | int ret = -EINVAL; | |
292 | int voltage, i; | |
293 | ||
294 | if (!rdev->desc->n_linear_ranges) { | |
295 | BUG_ON(!rdev->desc->n_linear_ranges); | |
296 | return -EINVAL; | |
297 | } | |
298 | ||
299 | for (i = 0; i < rdev->desc->n_linear_ranges; i++) { | |
e277e656 AL |
300 | int linear_max_uV; |
301 | ||
c4a54b8d | 302 | range = &rdev->desc->linear_ranges[i]; |
e277e656 AL |
303 | linear_max_uV = range->min_uV + |
304 | (range->max_sel - range->min_sel) * range->uV_step; | |
c4a54b8d | 305 | |
e277e656 | 306 | if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) |
c4a54b8d MB |
307 | continue; |
308 | ||
309 | if (min_uV <= range->min_uV) | |
310 | min_uV = range->min_uV; | |
311 | ||
312 | /* range->uV_step == 0 means fixed voltage range */ | |
313 | if (range->uV_step == 0) { | |
314 | ret = 0; | |
315 | } else { | |
316 | ret = DIV_ROUND_UP(min_uV - range->min_uV, | |
317 | range->uV_step); | |
318 | if (ret < 0) | |
319 | return ret; | |
320 | } | |
321 | ||
322 | ret += range->min_sel; | |
323 | ||
324 | break; | |
325 | } | |
326 | ||
327 | if (i == rdev->desc->n_linear_ranges) | |
328 | return -EINVAL; | |
329 | ||
330 | /* Map back into a voltage to verify we're still in bounds */ | |
331 | voltage = rdev->desc->ops->list_voltage(rdev, ret); | |
332 | if (voltage < min_uV || voltage > max_uV) | |
333 | return -EINVAL; | |
334 | ||
335 | return ret; | |
336 | } | |
337 | EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range); | |
338 | ||
d295f767 AL |
339 | /** |
340 | * regulator_list_voltage_linear - List voltages with simple calculation | |
341 | * | |
342 | * @rdev: Regulator device | |
343 | * @selector: Selector to convert into a voltage | |
344 | * | |
345 | * Regulators with a simple linear mapping between voltages and | |
346 | * selectors can set min_uV and uV_step in the regulator descriptor | |
347 | * and then use this function as their list_voltage() operation, | |
348 | */ | |
349 | int regulator_list_voltage_linear(struct regulator_dev *rdev, | |
350 | unsigned int selector) | |
351 | { | |
352 | if (selector >= rdev->desc->n_voltages) | |
353 | return -EINVAL; | |
354 | if (selector < rdev->desc->linear_min_sel) | |
355 | return 0; | |
356 | ||
357 | selector -= rdev->desc->linear_min_sel; | |
358 | ||
359 | return rdev->desc->min_uV + (rdev->desc->uV_step * selector); | |
360 | } | |
361 | EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); | |
362 | ||
363 | /** | |
364 | * regulator_list_voltage_linear_range - List voltages for linear ranges | |
365 | * | |
366 | * @rdev: Regulator device | |
367 | * @selector: Selector to convert into a voltage | |
368 | * | |
369 | * Regulators with a series of simple linear mappings between voltages | |
370 | * and selectors can set linear_ranges in the regulator descriptor and | |
371 | * then use this function as their list_voltage() operation, | |
372 | */ | |
373 | int regulator_list_voltage_linear_range(struct regulator_dev *rdev, | |
374 | unsigned int selector) | |
375 | { | |
376 | const struct regulator_linear_range *range; | |
377 | int i; | |
378 | ||
379 | if (!rdev->desc->n_linear_ranges) { | |
380 | BUG_ON(!rdev->desc->n_linear_ranges); | |
381 | return -EINVAL; | |
382 | } | |
383 | ||
384 | for (i = 0; i < rdev->desc->n_linear_ranges; i++) { | |
385 | range = &rdev->desc->linear_ranges[i]; | |
386 | ||
387 | if (!(selector >= range->min_sel && | |
388 | selector <= range->max_sel)) | |
389 | continue; | |
390 | ||
391 | selector -= range->min_sel; | |
392 | ||
393 | return range->min_uV + (range->uV_step * selector); | |
394 | } | |
395 | ||
396 | return -EINVAL; | |
397 | } | |
398 | EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range); | |
399 | ||
400 | /** | |
401 | * regulator_list_voltage_table - List voltages with table based mapping | |
402 | * | |
403 | * @rdev: Regulator device | |
404 | * @selector: Selector to convert into a voltage | |
405 | * | |
406 | * Regulators with table based mapping between voltages and | |
407 | * selectors can set volt_table in the regulator descriptor | |
408 | * and then use this function as their list_voltage() operation. | |
409 | */ | |
410 | int regulator_list_voltage_table(struct regulator_dev *rdev, | |
411 | unsigned int selector) | |
412 | { | |
413 | if (!rdev->desc->volt_table) { | |
414 | BUG_ON(!rdev->desc->volt_table); | |
415 | return -EINVAL; | |
416 | } | |
417 | ||
418 | if (selector >= rdev->desc->n_voltages) | |
419 | return -EINVAL; | |
420 | ||
421 | return rdev->desc->volt_table[selector]; | |
422 | } | |
423 | EXPORT_SYMBOL_GPL(regulator_list_voltage_table); | |
424 | ||
c4a54b8d MB |
425 | /** |
426 | * regulator_set_bypass_regmap - Default set_bypass() using regmap | |
427 | * | |
428 | * @rdev: device to operate on. | |
429 | * @enable: state to set. | |
430 | */ | |
431 | int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | |
432 | { | |
433 | unsigned int val; | |
434 | ||
ca5d1b35 CC |
435 | if (enable) { |
436 | val = rdev->desc->bypass_val_on; | |
437 | if (!val) | |
438 | val = rdev->desc->bypass_mask; | |
439 | } else { | |
440 | val = rdev->desc->bypass_val_off; | |
441 | } | |
c4a54b8d MB |
442 | |
443 | return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | |
444 | rdev->desc->bypass_mask, val); | |
445 | } | |
446 | EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); | |
447 | ||
448 | /** | |
449 | * regulator_get_bypass_regmap - Default get_bypass() using regmap | |
450 | * | |
451 | * @rdev: device to operate on. | |
452 | * @enable: current state. | |
453 | */ | |
454 | int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) | |
455 | { | |
456 | unsigned int val; | |
457 | int ret; | |
458 | ||
459 | ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); | |
460 | if (ret != 0) | |
461 | return ret; | |
462 | ||
dd1a571d | 463 | *enable = (val & rdev->desc->bypass_mask) == rdev->desc->bypass_val_on; |
c4a54b8d MB |
464 | |
465 | return 0; | |
466 | } | |
467 | EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); | |
354794da LD |
468 | |
469 | /** | |
470 | * regulator_set_active_discharge_regmap - Default set_active_discharge() | |
471 | * using regmap | |
472 | * | |
473 | * @rdev: device to operate on. | |
474 | * @enable: state to set, 0 to disable and 1 to enable. | |
475 | */ | |
476 | int regulator_set_active_discharge_regmap(struct regulator_dev *rdev, | |
477 | bool enable) | |
478 | { | |
479 | unsigned int val; | |
480 | ||
481 | if (enable) | |
482 | val = rdev->desc->active_discharge_on; | |
483 | else | |
484 | val = rdev->desc->active_discharge_off; | |
485 | ||
486 | return regmap_update_bits(rdev->regmap, | |
487 | rdev->desc->active_discharge_reg, | |
488 | rdev->desc->active_discharge_mask, val); | |
489 | } | |
490 | EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap); |