Commit c4a54b8d54218a75b94ab9947449e688869df00d
1 parent
eca2a654b8
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
regulator: core: Move helpers for drivers out into a separate file
Reduce the size of core.c a bit. Signed-off-by: Mark Brown <broonie@linaro.org>
Showing 3 changed files with 362 additions and 342 deletions Side-by-side Diff
drivers/regulator/Makefile
... | ... | @@ -3,7 +3,7 @@ |
3 | 3 | # |
4 | 4 | |
5 | 5 | |
6 | -obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o | |
6 | +obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o | |
7 | 7 | obj-$(CONFIG_OF) += of_regulator.o |
8 | 8 | obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o |
9 | 9 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o |
drivers/regulator/core.c
... | ... | @@ -1904,77 +1904,6 @@ |
1904 | 1904 | } |
1905 | 1905 | EXPORT_SYMBOL_GPL(regulator_disable_deferred); |
1906 | 1906 | |
1907 | -/** | |
1908 | - * regulator_is_enabled_regmap - standard is_enabled() for regmap users | |
1909 | - * | |
1910 | - * @rdev: regulator to operate on | |
1911 | - * | |
1912 | - * Regulators that use regmap for their register I/O can set the | |
1913 | - * enable_reg and enable_mask fields in their descriptor and then use | |
1914 | - * this as their is_enabled operation, saving some code. | |
1915 | - */ | |
1916 | -int regulator_is_enabled_regmap(struct regulator_dev *rdev) | |
1917 | -{ | |
1918 | - unsigned int val; | |
1919 | - int ret; | |
1920 | - | |
1921 | - ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); | |
1922 | - if (ret != 0) | |
1923 | - return ret; | |
1924 | - | |
1925 | - if (rdev->desc->enable_is_inverted) | |
1926 | - return (val & rdev->desc->enable_mask) == 0; | |
1927 | - else | |
1928 | - return (val & rdev->desc->enable_mask) != 0; | |
1929 | -} | |
1930 | -EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); | |
1931 | - | |
1932 | -/** | |
1933 | - * regulator_enable_regmap - standard enable() for regmap users | |
1934 | - * | |
1935 | - * @rdev: regulator to operate on | |
1936 | - * | |
1937 | - * Regulators that use regmap for their register I/O can set the | |
1938 | - * enable_reg and enable_mask fields in their descriptor and then use | |
1939 | - * this as their enable() operation, saving some code. | |
1940 | - */ | |
1941 | -int regulator_enable_regmap(struct regulator_dev *rdev) | |
1942 | -{ | |
1943 | - unsigned int val; | |
1944 | - | |
1945 | - if (rdev->desc->enable_is_inverted) | |
1946 | - val = 0; | |
1947 | - else | |
1948 | - val = rdev->desc->enable_mask; | |
1949 | - | |
1950 | - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
1951 | - rdev->desc->enable_mask, val); | |
1952 | -} | |
1953 | -EXPORT_SYMBOL_GPL(regulator_enable_regmap); | |
1954 | - | |
1955 | -/** | |
1956 | - * regulator_disable_regmap - standard disable() for regmap users | |
1957 | - * | |
1958 | - * @rdev: regulator to operate on | |
1959 | - * | |
1960 | - * Regulators that use regmap for their register I/O can set the | |
1961 | - * enable_reg and enable_mask fields in their descriptor and then use | |
1962 | - * this as their disable() operation, saving some code. | |
1963 | - */ | |
1964 | -int regulator_disable_regmap(struct regulator_dev *rdev) | |
1965 | -{ | |
1966 | - unsigned int val; | |
1967 | - | |
1968 | - if (rdev->desc->enable_is_inverted) | |
1969 | - val = rdev->desc->enable_mask; | |
1970 | - else | |
1971 | - val = 0; | |
1972 | - | |
1973 | - return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
1974 | - rdev->desc->enable_mask, val); | |
1975 | -} | |
1976 | -EXPORT_SYMBOL_GPL(regulator_disable_regmap); | |
1977 | - | |
1978 | 1907 | static int _regulator_is_enabled(struct regulator_dev *rdev) |
1979 | 1908 | { |
1980 | 1909 | /* A GPIO control always takes precedence */ |
... | ... | @@ -2239,235 +2168,6 @@ |
2239 | 2168 | } |
2240 | 2169 | EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); |
2241 | 2170 | |
2242 | -/** | |
2243 | - * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users | |
2244 | - * | |
2245 | - * @rdev: regulator to operate on | |
2246 | - * | |
2247 | - * Regulators that use regmap for their register I/O can set the | |
2248 | - * vsel_reg and vsel_mask fields in their descriptor and then use this | |
2249 | - * as their get_voltage_vsel operation, saving some code. | |
2250 | - */ | |
2251 | -int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) | |
2252 | -{ | |
2253 | - unsigned int val; | |
2254 | - int ret; | |
2255 | - | |
2256 | - ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); | |
2257 | - if (ret != 0) | |
2258 | - return ret; | |
2259 | - | |
2260 | - val &= rdev->desc->vsel_mask; | |
2261 | - val >>= ffs(rdev->desc->vsel_mask) - 1; | |
2262 | - | |
2263 | - return val; | |
2264 | -} | |
2265 | -EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); | |
2266 | - | |
2267 | -/** | |
2268 | - * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users | |
2269 | - * | |
2270 | - * @rdev: regulator to operate on | |
2271 | - * @sel: Selector to set | |
2272 | - * | |
2273 | - * Regulators that use regmap for their register I/O can set the | |
2274 | - * vsel_reg and vsel_mask fields in their descriptor and then use this | |
2275 | - * as their set_voltage_vsel operation, saving some code. | |
2276 | - */ | |
2277 | -int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) | |
2278 | -{ | |
2279 | - int ret; | |
2280 | - | |
2281 | - sel <<= ffs(rdev->desc->vsel_mask) - 1; | |
2282 | - | |
2283 | - ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, | |
2284 | - rdev->desc->vsel_mask, sel); | |
2285 | - if (ret) | |
2286 | - return ret; | |
2287 | - | |
2288 | - if (rdev->desc->apply_bit) | |
2289 | - ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, | |
2290 | - rdev->desc->apply_bit, | |
2291 | - rdev->desc->apply_bit); | |
2292 | - return ret; | |
2293 | -} | |
2294 | -EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); | |
2295 | - | |
2296 | -/** | |
2297 | - * regulator_map_voltage_iterate - map_voltage() based on list_voltage() | |
2298 | - * | |
2299 | - * @rdev: Regulator to operate on | |
2300 | - * @min_uV: Lower bound for voltage | |
2301 | - * @max_uV: Upper bound for voltage | |
2302 | - * | |
2303 | - * Drivers implementing set_voltage_sel() and list_voltage() can use | |
2304 | - * this as their map_voltage() operation. It will find a suitable | |
2305 | - * voltage by calling list_voltage() until it gets something in bounds | |
2306 | - * for the requested voltages. | |
2307 | - */ | |
2308 | -int regulator_map_voltage_iterate(struct regulator_dev *rdev, | |
2309 | - int min_uV, int max_uV) | |
2310 | -{ | |
2311 | - int best_val = INT_MAX; | |
2312 | - int selector = 0; | |
2313 | - int i, ret; | |
2314 | - | |
2315 | - /* Find the smallest voltage that falls within the specified | |
2316 | - * range. | |
2317 | - */ | |
2318 | - for (i = 0; i < rdev->desc->n_voltages; i++) { | |
2319 | - ret = rdev->desc->ops->list_voltage(rdev, i); | |
2320 | - if (ret < 0) | |
2321 | - continue; | |
2322 | - | |
2323 | - if (ret < best_val && ret >= min_uV && ret <= max_uV) { | |
2324 | - best_val = ret; | |
2325 | - selector = i; | |
2326 | - } | |
2327 | - } | |
2328 | - | |
2329 | - if (best_val != INT_MAX) | |
2330 | - return selector; | |
2331 | - else | |
2332 | - return -EINVAL; | |
2333 | -} | |
2334 | -EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate); | |
2335 | - | |
2336 | -/** | |
2337 | - * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list | |
2338 | - * | |
2339 | - * @rdev: Regulator to operate on | |
2340 | - * @min_uV: Lower bound for voltage | |
2341 | - * @max_uV: Upper bound for voltage | |
2342 | - * | |
2343 | - * Drivers that have ascendant voltage list can use this as their | |
2344 | - * map_voltage() operation. | |
2345 | - */ | |
2346 | -int regulator_map_voltage_ascend(struct regulator_dev *rdev, | |
2347 | - int min_uV, int max_uV) | |
2348 | -{ | |
2349 | - int i, ret; | |
2350 | - | |
2351 | - for (i = 0; i < rdev->desc->n_voltages; i++) { | |
2352 | - ret = rdev->desc->ops->list_voltage(rdev, i); | |
2353 | - if (ret < 0) | |
2354 | - continue; | |
2355 | - | |
2356 | - if (ret > max_uV) | |
2357 | - break; | |
2358 | - | |
2359 | - if (ret >= min_uV && ret <= max_uV) | |
2360 | - return i; | |
2361 | - } | |
2362 | - | |
2363 | - return -EINVAL; | |
2364 | -} | |
2365 | -EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend); | |
2366 | - | |
2367 | -/** | |
2368 | - * regulator_map_voltage_linear - map_voltage() for simple linear mappings | |
2369 | - * | |
2370 | - * @rdev: Regulator to operate on | |
2371 | - * @min_uV: Lower bound for voltage | |
2372 | - * @max_uV: Upper bound for voltage | |
2373 | - * | |
2374 | - * Drivers providing min_uV and uV_step in their regulator_desc can | |
2375 | - * use this as their map_voltage() operation. | |
2376 | - */ | |
2377 | -int regulator_map_voltage_linear(struct regulator_dev *rdev, | |
2378 | - int min_uV, int max_uV) | |
2379 | -{ | |
2380 | - int ret, voltage; | |
2381 | - | |
2382 | - /* Allow uV_step to be 0 for fixed voltage */ | |
2383 | - if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { | |
2384 | - if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) | |
2385 | - return 0; | |
2386 | - else | |
2387 | - return -EINVAL; | |
2388 | - } | |
2389 | - | |
2390 | - if (!rdev->desc->uV_step) { | |
2391 | - BUG_ON(!rdev->desc->uV_step); | |
2392 | - return -EINVAL; | |
2393 | - } | |
2394 | - | |
2395 | - if (min_uV < rdev->desc->min_uV) | |
2396 | - min_uV = rdev->desc->min_uV; | |
2397 | - | |
2398 | - ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); | |
2399 | - if (ret < 0) | |
2400 | - return ret; | |
2401 | - | |
2402 | - ret += rdev->desc->linear_min_sel; | |
2403 | - | |
2404 | - /* Map back into a voltage to verify we're still in bounds */ | |
2405 | - voltage = rdev->desc->ops->list_voltage(rdev, ret); | |
2406 | - if (voltage < min_uV || voltage > max_uV) | |
2407 | - return -EINVAL; | |
2408 | - | |
2409 | - return ret; | |
2410 | -} | |
2411 | -EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); | |
2412 | - | |
2413 | -/** | |
2414 | - * regulator_map_voltage_linear - map_voltage() for multiple linear ranges | |
2415 | - * | |
2416 | - * @rdev: Regulator to operate on | |
2417 | - * @min_uV: Lower bound for voltage | |
2418 | - * @max_uV: Upper bound for voltage | |
2419 | - * | |
2420 | - * Drivers providing linear_ranges in their descriptor can use this as | |
2421 | - * their map_voltage() callback. | |
2422 | - */ | |
2423 | -int regulator_map_voltage_linear_range(struct regulator_dev *rdev, | |
2424 | - int min_uV, int max_uV) | |
2425 | -{ | |
2426 | - const struct regulator_linear_range *range; | |
2427 | - int ret = -EINVAL; | |
2428 | - int voltage, i; | |
2429 | - | |
2430 | - if (!rdev->desc->n_linear_ranges) { | |
2431 | - BUG_ON(!rdev->desc->n_linear_ranges); | |
2432 | - return -EINVAL; | |
2433 | - } | |
2434 | - | |
2435 | - for (i = 0; i < rdev->desc->n_linear_ranges; i++) { | |
2436 | - range = &rdev->desc->linear_ranges[i]; | |
2437 | - | |
2438 | - if (!(min_uV <= range->max_uV && max_uV >= range->min_uV)) | |
2439 | - continue; | |
2440 | - | |
2441 | - if (min_uV <= range->min_uV) | |
2442 | - min_uV = range->min_uV; | |
2443 | - | |
2444 | - /* range->uV_step == 0 means fixed voltage range */ | |
2445 | - if (range->uV_step == 0) { | |
2446 | - ret = 0; | |
2447 | - } else { | |
2448 | - ret = DIV_ROUND_UP(min_uV - range->min_uV, | |
2449 | - range->uV_step); | |
2450 | - if (ret < 0) | |
2451 | - return ret; | |
2452 | - } | |
2453 | - | |
2454 | - ret += range->min_sel; | |
2455 | - | |
2456 | - break; | |
2457 | - } | |
2458 | - | |
2459 | - if (i == rdev->desc->n_linear_ranges) | |
2460 | - return -EINVAL; | |
2461 | - | |
2462 | - /* Map back into a voltage to verify we're still in bounds */ | |
2463 | - voltage = rdev->desc->ops->list_voltage(rdev, ret); | |
2464 | - if (voltage < min_uV || voltage > max_uV) | |
2465 | - return -EINVAL; | |
2466 | - | |
2467 | - return ret; | |
2468 | -} | |
2469 | -EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range); | |
2470 | - | |
2471 | 2171 | static int _regulator_do_set_voltage(struct regulator_dev *rdev, |
2472 | 2172 | int min_uV, int max_uV) |
2473 | 2173 | { |
... | ... | @@ -3069,47 +2769,6 @@ |
3069 | 2769 | return ret; |
3070 | 2770 | } |
3071 | 2771 | EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); |
3072 | - | |
3073 | -/** | |
3074 | - * regulator_set_bypass_regmap - Default set_bypass() using regmap | |
3075 | - * | |
3076 | - * @rdev: device to operate on. | |
3077 | - * @enable: state to set. | |
3078 | - */ | |
3079 | -int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | |
3080 | -{ | |
3081 | - unsigned int val; | |
3082 | - | |
3083 | - if (enable) | |
3084 | - val = rdev->desc->bypass_mask; | |
3085 | - else | |
3086 | - val = 0; | |
3087 | - | |
3088 | - return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | |
3089 | - rdev->desc->bypass_mask, val); | |
3090 | -} | |
3091 | -EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); | |
3092 | - | |
3093 | -/** | |
3094 | - * regulator_get_bypass_regmap - Default get_bypass() using regmap | |
3095 | - * | |
3096 | - * @rdev: device to operate on. | |
3097 | - * @enable: current state. | |
3098 | - */ | |
3099 | -int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) | |
3100 | -{ | |
3101 | - unsigned int val; | |
3102 | - int ret; | |
3103 | - | |
3104 | - ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); | |
3105 | - if (ret != 0) | |
3106 | - return ret; | |
3107 | - | |
3108 | - *enable = val & rdev->desc->bypass_mask; | |
3109 | - | |
3110 | - return 0; | |
3111 | -} | |
3112 | -EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); | |
3113 | 2772 | |
3114 | 2773 | /** |
3115 | 2774 | * regulator_allow_bypass - allow the regulator to go into bypass mode |
drivers/regulator/helpers.c
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 | + | |
40 | + if (rdev->desc->enable_is_inverted) | |
41 | + return (val & rdev->desc->enable_mask) == 0; | |
42 | + else | |
43 | + return (val & rdev->desc->enable_mask) != 0; | |
44 | +} | |
45 | +EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); | |
46 | + | |
47 | +/** | |
48 | + * regulator_enable_regmap - standard enable() for regmap users | |
49 | + * | |
50 | + * @rdev: regulator to operate on | |
51 | + * | |
52 | + * Regulators that use regmap for their register I/O can set the | |
53 | + * enable_reg and enable_mask fields in their descriptor and then use | |
54 | + * this as their enable() operation, saving some code. | |
55 | + */ | |
56 | +int regulator_enable_regmap(struct regulator_dev *rdev) | |
57 | +{ | |
58 | + unsigned int val; | |
59 | + | |
60 | + if (rdev->desc->enable_is_inverted) | |
61 | + val = 0; | |
62 | + else | |
63 | + val = rdev->desc->enable_mask; | |
64 | + | |
65 | + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
66 | + rdev->desc->enable_mask, val); | |
67 | +} | |
68 | +EXPORT_SYMBOL_GPL(regulator_enable_regmap); | |
69 | + | |
70 | +/** | |
71 | + * regulator_disable_regmap - standard disable() for regmap users | |
72 | + * | |
73 | + * @rdev: regulator to operate on | |
74 | + * | |
75 | + * Regulators that use regmap for their register I/O can set the | |
76 | + * enable_reg and enable_mask fields in their descriptor and then use | |
77 | + * this as their disable() operation, saving some code. | |
78 | + */ | |
79 | +int regulator_disable_regmap(struct regulator_dev *rdev) | |
80 | +{ | |
81 | + unsigned int val; | |
82 | + | |
83 | + if (rdev->desc->enable_is_inverted) | |
84 | + val = rdev->desc->enable_mask; | |
85 | + else | |
86 | + val = 0; | |
87 | + | |
88 | + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | |
89 | + rdev->desc->enable_mask, val); | |
90 | +} | |
91 | +EXPORT_SYMBOL_GPL(regulator_disable_regmap); | |
92 | + | |
93 | +/** | |
94 | + * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users | |
95 | + * | |
96 | + * @rdev: regulator to operate on | |
97 | + * | |
98 | + * Regulators that use regmap for their register I/O can set the | |
99 | + * vsel_reg and vsel_mask fields in their descriptor and then use this | |
100 | + * as their get_voltage_vsel operation, saving some code. | |
101 | + */ | |
102 | +int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) | |
103 | +{ | |
104 | + unsigned int val; | |
105 | + int ret; | |
106 | + | |
107 | + ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); | |
108 | + if (ret != 0) | |
109 | + return ret; | |
110 | + | |
111 | + val &= rdev->desc->vsel_mask; | |
112 | + val >>= ffs(rdev->desc->vsel_mask) - 1; | |
113 | + | |
114 | + return val; | |
115 | +} | |
116 | +EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); | |
117 | + | |
118 | +/** | |
119 | + * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users | |
120 | + * | |
121 | + * @rdev: regulator to operate on | |
122 | + * @sel: Selector to set | |
123 | + * | |
124 | + * Regulators that use regmap for their register I/O can set the | |
125 | + * vsel_reg and vsel_mask fields in their descriptor and then use this | |
126 | + * as their set_voltage_vsel operation, saving some code. | |
127 | + */ | |
128 | +int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) | |
129 | +{ | |
130 | + int ret; | |
131 | + | |
132 | + sel <<= ffs(rdev->desc->vsel_mask) - 1; | |
133 | + | |
134 | + ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, | |
135 | + rdev->desc->vsel_mask, sel); | |
136 | + if (ret) | |
137 | + return ret; | |
138 | + | |
139 | + if (rdev->desc->apply_bit) | |
140 | + ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, | |
141 | + rdev->desc->apply_bit, | |
142 | + rdev->desc->apply_bit); | |
143 | + return ret; | |
144 | +} | |
145 | +EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); | |
146 | + | |
147 | +/** | |
148 | + * regulator_map_voltage_iterate - map_voltage() based on list_voltage() | |
149 | + * | |
150 | + * @rdev: Regulator to operate on | |
151 | + * @min_uV: Lower bound for voltage | |
152 | + * @max_uV: Upper bound for voltage | |
153 | + * | |
154 | + * Drivers implementing set_voltage_sel() and list_voltage() can use | |
155 | + * this as their map_voltage() operation. It will find a suitable | |
156 | + * voltage by calling list_voltage() until it gets something in bounds | |
157 | + * for the requested voltages. | |
158 | + */ | |
159 | +int regulator_map_voltage_iterate(struct regulator_dev *rdev, | |
160 | + int min_uV, int max_uV) | |
161 | +{ | |
162 | + int best_val = INT_MAX; | |
163 | + int selector = 0; | |
164 | + int i, ret; | |
165 | + | |
166 | + /* Find the smallest voltage that falls within the specified | |
167 | + * range. | |
168 | + */ | |
169 | + for (i = 0; i < rdev->desc->n_voltages; i++) { | |
170 | + ret = rdev->desc->ops->list_voltage(rdev, i); | |
171 | + if (ret < 0) | |
172 | + continue; | |
173 | + | |
174 | + if (ret < best_val && ret >= min_uV && ret <= max_uV) { | |
175 | + best_val = ret; | |
176 | + selector = i; | |
177 | + } | |
178 | + } | |
179 | + | |
180 | + if (best_val != INT_MAX) | |
181 | + return selector; | |
182 | + else | |
183 | + return -EINVAL; | |
184 | +} | |
185 | +EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate); | |
186 | + | |
187 | +/** | |
188 | + * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list | |
189 | + * | |
190 | + * @rdev: Regulator to operate on | |
191 | + * @min_uV: Lower bound for voltage | |
192 | + * @max_uV: Upper bound for voltage | |
193 | + * | |
194 | + * Drivers that have ascendant voltage list can use this as their | |
195 | + * map_voltage() operation. | |
196 | + */ | |
197 | +int regulator_map_voltage_ascend(struct regulator_dev *rdev, | |
198 | + int min_uV, int max_uV) | |
199 | +{ | |
200 | + int i, ret; | |
201 | + | |
202 | + for (i = 0; i < rdev->desc->n_voltages; i++) { | |
203 | + ret = rdev->desc->ops->list_voltage(rdev, i); | |
204 | + if (ret < 0) | |
205 | + continue; | |
206 | + | |
207 | + if (ret > max_uV) | |
208 | + break; | |
209 | + | |
210 | + if (ret >= min_uV && ret <= max_uV) | |
211 | + return i; | |
212 | + } | |
213 | + | |
214 | + return -EINVAL; | |
215 | +} | |
216 | +EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend); | |
217 | + | |
218 | +/** | |
219 | + * regulator_map_voltage_linear - map_voltage() for simple linear mappings | |
220 | + * | |
221 | + * @rdev: Regulator to operate on | |
222 | + * @min_uV: Lower bound for voltage | |
223 | + * @max_uV: Upper bound for voltage | |
224 | + * | |
225 | + * Drivers providing min_uV and uV_step in their regulator_desc can | |
226 | + * use this as their map_voltage() operation. | |
227 | + */ | |
228 | +int regulator_map_voltage_linear(struct regulator_dev *rdev, | |
229 | + int min_uV, int max_uV) | |
230 | +{ | |
231 | + int ret, voltage; | |
232 | + | |
233 | + /* Allow uV_step to be 0 for fixed voltage */ | |
234 | + if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { | |
235 | + if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) | |
236 | + return 0; | |
237 | + else | |
238 | + return -EINVAL; | |
239 | + } | |
240 | + | |
241 | + if (!rdev->desc->uV_step) { | |
242 | + BUG_ON(!rdev->desc->uV_step); | |
243 | + return -EINVAL; | |
244 | + } | |
245 | + | |
246 | + if (min_uV < rdev->desc->min_uV) | |
247 | + min_uV = rdev->desc->min_uV; | |
248 | + | |
249 | + ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); | |
250 | + if (ret < 0) | |
251 | + return ret; | |
252 | + | |
253 | + ret += rdev->desc->linear_min_sel; | |
254 | + | |
255 | + /* Map back into a voltage to verify we're still in bounds */ | |
256 | + voltage = rdev->desc->ops->list_voltage(rdev, ret); | |
257 | + if (voltage < min_uV || voltage > max_uV) | |
258 | + return -EINVAL; | |
259 | + | |
260 | + return ret; | |
261 | +} | |
262 | +EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); | |
263 | + | |
264 | +/** | |
265 | + * regulator_map_voltage_linear - map_voltage() for multiple linear ranges | |
266 | + * | |
267 | + * @rdev: Regulator to operate on | |
268 | + * @min_uV: Lower bound for voltage | |
269 | + * @max_uV: Upper bound for voltage | |
270 | + * | |
271 | + * Drivers providing linear_ranges in their descriptor can use this as | |
272 | + * their map_voltage() callback. | |
273 | + */ | |
274 | +int regulator_map_voltage_linear_range(struct regulator_dev *rdev, | |
275 | + int min_uV, int max_uV) | |
276 | +{ | |
277 | + const struct regulator_linear_range *range; | |
278 | + int ret = -EINVAL; | |
279 | + int voltage, i; | |
280 | + | |
281 | + if (!rdev->desc->n_linear_ranges) { | |
282 | + BUG_ON(!rdev->desc->n_linear_ranges); | |
283 | + return -EINVAL; | |
284 | + } | |
285 | + | |
286 | + for (i = 0; i < rdev->desc->n_linear_ranges; i++) { | |
287 | + range = &rdev->desc->linear_ranges[i]; | |
288 | + | |
289 | + if (!(min_uV <= range->max_uV && max_uV >= range->min_uV)) | |
290 | + continue; | |
291 | + | |
292 | + if (min_uV <= range->min_uV) | |
293 | + min_uV = range->min_uV; | |
294 | + | |
295 | + /* range->uV_step == 0 means fixed voltage range */ | |
296 | + if (range->uV_step == 0) { | |
297 | + ret = 0; | |
298 | + } else { | |
299 | + ret = DIV_ROUND_UP(min_uV - range->min_uV, | |
300 | + range->uV_step); | |
301 | + if (ret < 0) | |
302 | + return ret; | |
303 | + } | |
304 | + | |
305 | + ret += range->min_sel; | |
306 | + | |
307 | + break; | |
308 | + } | |
309 | + | |
310 | + if (i == rdev->desc->n_linear_ranges) | |
311 | + return -EINVAL; | |
312 | + | |
313 | + /* Map back into a voltage to verify we're still in bounds */ | |
314 | + voltage = rdev->desc->ops->list_voltage(rdev, ret); | |
315 | + if (voltage < min_uV || voltage > max_uV) | |
316 | + return -EINVAL; | |
317 | + | |
318 | + return ret; | |
319 | +} | |
320 | +EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range); | |
321 | + | |
322 | +/** | |
323 | + * regulator_set_bypass_regmap - Default set_bypass() using regmap | |
324 | + * | |
325 | + * @rdev: device to operate on. | |
326 | + * @enable: state to set. | |
327 | + */ | |
328 | +int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) | |
329 | +{ | |
330 | + unsigned int val; | |
331 | + | |
332 | + if (enable) | |
333 | + val = rdev->desc->bypass_mask; | |
334 | + else | |
335 | + val = 0; | |
336 | + | |
337 | + return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, | |
338 | + rdev->desc->bypass_mask, val); | |
339 | +} | |
340 | +EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); | |
341 | + | |
342 | +/** | |
343 | + * regulator_get_bypass_regmap - Default get_bypass() using regmap | |
344 | + * | |
345 | + * @rdev: device to operate on. | |
346 | + * @enable: current state. | |
347 | + */ | |
348 | +int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) | |
349 | +{ | |
350 | + unsigned int val; | |
351 | + int ret; | |
352 | + | |
353 | + ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); | |
354 | + if (ret != 0) | |
355 | + return ret; | |
356 | + | |
357 | + *enable = val & rdev->desc->bypass_mask; | |
358 | + | |
359 | + return 0; | |
360 | +} | |
361 | +EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); |