1004 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2//3// helpers.c -- Voltage/Current Regulator framework helper functions.4//5// Copyright 2007, 2008 Wolfson Microelectronics PLC.6// Copyright 2008 SlimLogic Ltd.7 8#include <linux/bitops.h>9#include <linux/delay.h>10#include <linux/err.h>11#include <linux/export.h>12#include <linux/kernel.h>13#include <linux/regmap.h>14#include <linux/regulator/consumer.h>15#include <linux/regulator/driver.h>16 17#include "internal.h"18 19/**20 * regulator_is_enabled_regmap - standard is_enabled() for regmap users21 *22 * @rdev: regulator to operate on23 *24 * Regulators that use regmap for their register I/O can set the25 * enable_reg and enable_mask fields in their descriptor and then use26 * this as their is_enabled operation, saving some code.27 */28int regulator_is_enabled_regmap(struct regulator_dev *rdev)29{30 unsigned int val;31 int ret;32 33 ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);34 if (ret != 0)35 return ret;36 37 val &= rdev->desc->enable_mask;38 39 if (rdev->desc->enable_is_inverted) {40 if (rdev->desc->enable_val)41 return val != rdev->desc->enable_val;42 return val == 0;43 } else {44 if (rdev->desc->enable_val)45 return val == rdev->desc->enable_val;46 return val != 0;47 }48}49EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);50 51/**52 * regulator_enable_regmap - standard enable() for regmap users53 *54 * @rdev: regulator to operate on55 *56 * Regulators that use regmap for their register I/O can set the57 * enable_reg and enable_mask fields in their descriptor and then use58 * this as their enable() operation, saving some code.59 */60int regulator_enable_regmap(struct regulator_dev *rdev)61{62 unsigned int val;63 64 if (rdev->desc->enable_is_inverted) {65 val = rdev->desc->disable_val;66 } else {67 val = rdev->desc->enable_val;68 if (!val)69 val = rdev->desc->enable_mask;70 }71 72 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,73 rdev->desc->enable_mask, val);74}75EXPORT_SYMBOL_GPL(regulator_enable_regmap);76 77/**78 * regulator_disable_regmap - standard disable() for regmap users79 *80 * @rdev: regulator to operate on81 *82 * Regulators that use regmap for their register I/O can set the83 * enable_reg and enable_mask fields in their descriptor and then use84 * this as their disable() operation, saving some code.85 */86int regulator_disable_regmap(struct regulator_dev *rdev)87{88 unsigned int val;89 90 if (rdev->desc->enable_is_inverted) {91 val = rdev->desc->enable_val;92 if (!val)93 val = rdev->desc->enable_mask;94 } else {95 val = rdev->desc->disable_val;96 }97 98 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,99 rdev->desc->enable_mask, val);100}101EXPORT_SYMBOL_GPL(regulator_disable_regmap);102 103static int regulator_range_selector_to_index(struct regulator_dev *rdev,104 unsigned int rval)105{106 int i;107 108 if (!rdev->desc->linear_range_selectors_bitfield)109 return -EINVAL;110 111 rval &= rdev->desc->vsel_range_mask;112 rval >>= ffs(rdev->desc->vsel_range_mask) - 1;113 114 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {115 if (rdev->desc->linear_range_selectors_bitfield[i] == rval)116 return i;117 }118 return -EINVAL;119}120 121/**122 * regulator_get_voltage_sel_pickable_regmap - pickable range get_voltage_sel123 *124 * @rdev: regulator to operate on125 *126 * Regulators that use regmap for their register I/O and use pickable127 * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask128 * fields in their descriptor and then use this as their get_voltage_sel129 * operation, saving some code.130 */131int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)132{133 unsigned int r_val;134 int range;135 unsigned int val;136 int ret;137 unsigned int voltages = 0;138 const struct linear_range *r = rdev->desc->linear_ranges;139 140 if (!r)141 return -EINVAL;142 143 ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);144 if (ret != 0)145 return ret;146 147 ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &r_val);148 if (ret != 0)149 return ret;150 151 val &= rdev->desc->vsel_mask;152 val >>= ffs(rdev->desc->vsel_mask) - 1;153 154 range = regulator_range_selector_to_index(rdev, r_val);155 if (range < 0)156 return -EINVAL;157 158 voltages = linear_range_values_in_range_array(r, range);159 160 return val + voltages;161}162EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);163 164static int write_separate_vsel_and_range(struct regulator_dev *rdev,165 unsigned int sel, unsigned int range)166{167 bool range_updated;168 int ret;169 170 ret = regmap_update_bits_base(rdev->regmap, rdev->desc->vsel_range_reg,171 rdev->desc->vsel_range_mask,172 range, &range_updated, false, false);173 if (ret)174 return ret;175 176 /*177 * Some PMICs treat the vsel_reg same as apply-bit. Force it to be178 * written if the range changed, even if the old selector was same as179 * the new one180 */181 if (rdev->desc->range_applied_by_vsel && range_updated)182 return regmap_write_bits(rdev->regmap,183 rdev->desc->vsel_reg,184 rdev->desc->vsel_mask, sel);185 186 return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,187 rdev->desc->vsel_mask, sel);188}189 190/**191 * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel192 *193 * @rdev: regulator to operate on194 * @sel: Selector to set195 *196 * Regulators that use regmap for their register I/O and use pickable197 * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask198 * fields in their descriptor and then use this as their set_voltage_sel199 * operation, saving some code.200 */201int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,202 unsigned int sel)203{204 unsigned int range;205 int ret, i;206 unsigned int voltages_in_range = 0;207 208 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {209 const struct linear_range *r;210 211 r = &rdev->desc->linear_ranges[i];212 voltages_in_range = linear_range_values_in_range(r);213 214 if (sel < voltages_in_range)215 break;216 sel -= voltages_in_range;217 }218 219 if (i == rdev->desc->n_linear_ranges)220 return -EINVAL;221 222 sel <<= ffs(rdev->desc->vsel_mask) - 1;223 sel += rdev->desc->linear_ranges[i].min_sel;224 225 range = rdev->desc->linear_range_selectors_bitfield[i];226 range <<= ffs(rdev->desc->vsel_range_mask) - 1;227 228 if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg)229 ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,230 rdev->desc->vsel_range_mask |231 rdev->desc->vsel_mask, sel | range);232 else233 ret = write_separate_vsel_and_range(rdev, sel, range);234 235 if (ret)236 return ret;237 238 if (rdev->desc->apply_bit)239 ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,240 rdev->desc->apply_bit,241 rdev->desc->apply_bit);242 return ret;243}244EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap);245 246/**247 * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users248 *249 * @rdev: regulator to operate on250 *251 * Regulators that use regmap for their register I/O can set the252 * vsel_reg and vsel_mask fields in their descriptor and then use this253 * as their get_voltage_sel operation, saving some code.254 */255int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)256{257 unsigned int val;258 int ret;259 260 ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);261 if (ret != 0)262 return ret;263 264 val &= rdev->desc->vsel_mask;265 val >>= ffs(rdev->desc->vsel_mask) - 1;266 267 return val;268}269EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);270 271/**272 * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users273 *274 * @rdev: regulator to operate on275 * @sel: Selector to set276 *277 * Regulators that use regmap for their register I/O can set the278 * vsel_reg and vsel_mask fields in their descriptor and then use this279 * as their set_voltage_sel operation, saving some code.280 */281int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)282{283 int ret;284 285 sel <<= ffs(rdev->desc->vsel_mask) - 1;286 287 ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,288 rdev->desc->vsel_mask, sel);289 if (ret)290 return ret;291 292 if (rdev->desc->apply_bit)293 ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,294 rdev->desc->apply_bit,295 rdev->desc->apply_bit);296 return ret;297}298EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);299 300/**301 * regulator_map_voltage_iterate - map_voltage() based on list_voltage()302 *303 * @rdev: Regulator to operate on304 * @min_uV: Lower bound for voltage305 * @max_uV: Upper bound for voltage306 *307 * Drivers implementing set_voltage_sel() and list_voltage() can use308 * this as their map_voltage() operation. It will find a suitable309 * voltage by calling list_voltage() until it gets something in bounds310 * for the requested voltages.311 */312int regulator_map_voltage_iterate(struct regulator_dev *rdev,313 int min_uV, int max_uV)314{315 int best_val = INT_MAX;316 int selector = 0;317 int i, ret;318 319 /* Find the smallest voltage that falls within the specified320 * range.321 */322 for (i = 0; i < rdev->desc->n_voltages; i++) {323 ret = rdev->desc->ops->list_voltage(rdev, i);324 if (ret < 0)325 continue;326 327 if (ret < best_val && ret >= min_uV && ret <= max_uV) {328 best_val = ret;329 selector = i;330 }331 }332 333 if (best_val != INT_MAX)334 return selector;335 else336 return -EINVAL;337}338EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);339 340/**341 * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list342 *343 * @rdev: Regulator to operate on344 * @min_uV: Lower bound for voltage345 * @max_uV: Upper bound for voltage346 *347 * Drivers that have ascendant voltage list can use this as their348 * map_voltage() operation.349 */350int regulator_map_voltage_ascend(struct regulator_dev *rdev,351 int min_uV, int max_uV)352{353 int i, ret;354 355 for (i = 0; i < rdev->desc->n_voltages; i++) {356 ret = rdev->desc->ops->list_voltage(rdev, i);357 if (ret < 0)358 continue;359 360 if (ret > max_uV)361 break;362 363 if (ret >= min_uV && ret <= max_uV)364 return i;365 }366 367 return -EINVAL;368}369EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);370 371/**372 * regulator_map_voltage_linear - map_voltage() for simple linear mappings373 *374 * @rdev: Regulator to operate on375 * @min_uV: Lower bound for voltage376 * @max_uV: Upper bound for voltage377 *378 * Drivers providing min_uV and uV_step in their regulator_desc can379 * use this as their map_voltage() operation.380 */381int regulator_map_voltage_linear(struct regulator_dev *rdev,382 int min_uV, int max_uV)383{384 int ret, voltage;385 386 /* Allow uV_step to be 0 for fixed voltage */387 if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {388 if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)389 return 0;390 else391 return -EINVAL;392 }393 394 if (!rdev->desc->uV_step) {395 BUG_ON(!rdev->desc->uV_step);396 return -EINVAL;397 }398 399 if (min_uV < rdev->desc->min_uV)400 min_uV = rdev->desc->min_uV;401 402 ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);403 if (ret < 0)404 return ret;405 406 ret += rdev->desc->linear_min_sel;407 408 /* Map back into a voltage to verify we're still in bounds */409 voltage = rdev->desc->ops->list_voltage(rdev, ret);410 if (voltage < min_uV || voltage > max_uV)411 return -EINVAL;412 413 return ret;414}415EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);416 417/**418 * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges419 *420 * @rdev: Regulator to operate on421 * @min_uV: Lower bound for voltage422 * @max_uV: Upper bound for voltage423 *424 * Drivers providing linear_ranges in their descriptor can use this as425 * their map_voltage() callback.426 */427int regulator_map_voltage_linear_range(struct regulator_dev *rdev,428 int min_uV, int max_uV)429{430 const struct linear_range *range;431 int ret = -EINVAL;432 unsigned int sel;433 bool found;434 int voltage, i;435 436 if (!rdev->desc->n_linear_ranges) {437 BUG_ON(!rdev->desc->n_linear_ranges);438 return -EINVAL;439 }440 441 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {442 range = &rdev->desc->linear_ranges[i];443 444 ret = linear_range_get_selector_high(range, min_uV, &sel,445 &found);446 if (ret)447 continue;448 ret = sel;449 450 /*451 * Map back into a voltage to verify we're still in bounds.452 * If we are not, then continue checking rest of the ranges.453 */454 voltage = rdev->desc->ops->list_voltage(rdev, sel);455 if (voltage >= min_uV && voltage <= max_uV)456 break;457 }458 459 if (i == rdev->desc->n_linear_ranges)460 return -EINVAL;461 462 return ret;463}464EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);465 466/**467 * regulator_map_voltage_pickable_linear_range - map_voltage, pickable ranges468 *469 * @rdev: Regulator to operate on470 * @min_uV: Lower bound for voltage471 * @max_uV: Upper bound for voltage472 *473 * Drivers providing pickable linear_ranges in their descriptor can use474 * this as their map_voltage() callback.475 */476int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,477 int min_uV, int max_uV)478{479 const struct linear_range *range;480 int ret = -EINVAL;481 int voltage, i;482 unsigned int selector = 0;483 484 if (!rdev->desc->n_linear_ranges) {485 BUG_ON(!rdev->desc->n_linear_ranges);486 return -EINVAL;487 }488 489 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {490 int linear_max_uV;491 bool found;492 unsigned int sel;493 494 range = &rdev->desc->linear_ranges[i];495 linear_max_uV = linear_range_get_max_value(range);496 497 if (!(min_uV <= linear_max_uV && max_uV >= range->min)) {498 selector += linear_range_values_in_range(range);499 continue;500 }501 502 ret = linear_range_get_selector_high(range, min_uV, &sel,503 &found);504 if (ret) {505 selector += linear_range_values_in_range(range);506 continue;507 }508 509 ret = selector + sel - range->min_sel;510 511 voltage = rdev->desc->ops->list_voltage(rdev, ret);512 513 /*514 * Map back into a voltage to verify we're still in bounds.515 * We may have overlapping voltage ranges. Hence we don't516 * exit but retry until we have checked all ranges.517 */518 if (voltage < min_uV || voltage > max_uV)519 selector += linear_range_values_in_range(range);520 else521 break;522 }523 524 if (i == rdev->desc->n_linear_ranges)525 return -EINVAL;526 527 return ret;528}529EXPORT_SYMBOL_GPL(regulator_map_voltage_pickable_linear_range);530 531/**532 * regulator_desc_list_voltage_linear - List voltages with simple calculation533 *534 * @desc: Regulator desc for regulator which volatges are to be listed535 * @selector: Selector to convert into a voltage536 *537 * Regulators with a simple linear mapping between voltages and538 * selectors can set min_uV and uV_step in the regulator descriptor539 * and then use this function prior regulator registration to list540 * the voltages. This is useful when voltages need to be listed during541 * device-tree parsing.542 */543int regulator_desc_list_voltage_linear(const struct regulator_desc *desc,544 unsigned int selector)545{546 if (selector >= desc->n_voltages)547 return -EINVAL;548 549 if (selector < desc->linear_min_sel)550 return 0;551 552 selector -= desc->linear_min_sel;553 554 return desc->min_uV + (desc->uV_step * selector);555}556EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear);557 558/**559 * regulator_list_voltage_linear - List voltages with simple calculation560 *561 * @rdev: Regulator device562 * @selector: Selector to convert into a voltage563 *564 * Regulators with a simple linear mapping between voltages and565 * selectors can set min_uV and uV_step in the regulator descriptor566 * and then use this function as their list_voltage() operation,567 */568int regulator_list_voltage_linear(struct regulator_dev *rdev,569 unsigned int selector)570{571 return regulator_desc_list_voltage_linear(rdev->desc, selector);572}573EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);574 575/**576 * regulator_list_voltage_pickable_linear_range - pickable range list voltages577 *578 * @rdev: Regulator device579 * @selector: Selector to convert into a voltage580 *581 * list_voltage() operation, intended to be used by drivers utilizing pickable582 * ranges helpers.583 */584int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,585 unsigned int selector)586{587 const struct linear_range *range;588 int i;589 unsigned int all_sels = 0;590 591 if (!rdev->desc->n_linear_ranges) {592 BUG_ON(!rdev->desc->n_linear_ranges);593 return -EINVAL;594 }595 596 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {597 unsigned int sel_indexes;598 599 range = &rdev->desc->linear_ranges[i];600 601 sel_indexes = linear_range_values_in_range(range) - 1;602 603 if (all_sels + sel_indexes >= selector) {604 selector -= all_sels;605 /*606 * As we see here, pickable ranges work only as607 * long as the first selector for each pickable608 * range is 0, and the each subsequent range for609 * this 'pick' follow immediately at next unused610 * selector (Eg. there is no gaps between ranges).611 * I think this is fine but it probably should be612 * documented. OTOH, whole pickable range stuff613 * might benefit from some documentation614 */615 return range->min + (range->step * selector);616 }617 618 all_sels += (sel_indexes + 1);619 }620 621 return -EINVAL;622}623EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);624 625/**626 * regulator_desc_list_voltage_linear_range - List voltages for linear ranges627 *628 * @desc: Regulator desc for regulator which volatges are to be listed629 * @selector: Selector to convert into a voltage630 *631 * Regulators with a series of simple linear mappings between voltages632 * and selectors who have set linear_ranges in the regulator descriptor633 * can use this function prior regulator registration to list voltages.634 * This is useful when voltages need to be listed during device-tree635 * parsing.636 */637int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,638 unsigned int selector)639{640 unsigned int val;641 int ret;642 643 BUG_ON(!desc->n_linear_ranges);644 645 ret = linear_range_get_value_array(desc->linear_ranges,646 desc->n_linear_ranges, selector,647 &val);648 if (ret)649 return ret;650 651 return val;652}653EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range);654 655/**656 * regulator_list_voltage_linear_range - List voltages for linear ranges657 *658 * @rdev: Regulator device659 * @selector: Selector to convert into a voltage660 *661 * Regulators with a series of simple linear mappings between voltages662 * and selectors can set linear_ranges in the regulator descriptor and663 * then use this function as their list_voltage() operation,664 */665int regulator_list_voltage_linear_range(struct regulator_dev *rdev,666 unsigned int selector)667{668 return regulator_desc_list_voltage_linear_range(rdev->desc, selector);669}670EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);671 672/**673 * regulator_list_voltage_table - List voltages with table based mapping674 *675 * @rdev: Regulator device676 * @selector: Selector to convert into a voltage677 *678 * Regulators with table based mapping between voltages and679 * selectors can set volt_table in the regulator descriptor680 * and then use this function as their list_voltage() operation.681 */682int regulator_list_voltage_table(struct regulator_dev *rdev,683 unsigned int selector)684{685 if (!rdev->desc->volt_table) {686 BUG_ON(!rdev->desc->volt_table);687 return -EINVAL;688 }689 690 if (selector >= rdev->desc->n_voltages)691 return -EINVAL;692 if (selector < rdev->desc->linear_min_sel)693 return 0;694 695 return rdev->desc->volt_table[selector];696}697EXPORT_SYMBOL_GPL(regulator_list_voltage_table);698 699/**700 * regulator_set_bypass_regmap - Default set_bypass() using regmap701 *702 * @rdev: device to operate on.703 * @enable: state to set.704 */705int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)706{707 unsigned int val;708 709 if (enable) {710 val = rdev->desc->bypass_val_on;711 if (!val)712 val = rdev->desc->bypass_mask;713 } else {714 val = rdev->desc->bypass_val_off;715 }716 717 return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,718 rdev->desc->bypass_mask, val);719}720EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);721 722/**723 * regulator_set_soft_start_regmap - Default set_soft_start() using regmap724 *725 * @rdev: device to operate on.726 */727int regulator_set_soft_start_regmap(struct regulator_dev *rdev)728{729 unsigned int val;730 731 val = rdev->desc->soft_start_val_on;732 if (!val)733 val = rdev->desc->soft_start_mask;734 735 return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,736 rdev->desc->soft_start_mask, val);737}738EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);739 740/**741 * regulator_set_pull_down_regmap - Default set_pull_down() using regmap742 *743 * @rdev: device to operate on.744 */745int regulator_set_pull_down_regmap(struct regulator_dev *rdev)746{747 unsigned int val;748 749 val = rdev->desc->pull_down_val_on;750 if (!val)751 val = rdev->desc->pull_down_mask;752 753 return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,754 rdev->desc->pull_down_mask, val);755}756EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);757 758/**759 * regulator_get_bypass_regmap - Default get_bypass() using regmap760 *761 * @rdev: device to operate on.762 * @enable: current state.763 */764int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)765{766 unsigned int val;767 unsigned int val_on = rdev->desc->bypass_val_on;768 int ret;769 770 ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);771 if (ret != 0)772 return ret;773 774 if (!val_on)775 val_on = rdev->desc->bypass_mask;776 777 *enable = (val & rdev->desc->bypass_mask) == val_on;778 779 return 0;780}781EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);782 783/**784 * regulator_set_active_discharge_regmap - Default set_active_discharge()785 * using regmap786 *787 * @rdev: device to operate on.788 * @enable: state to set, 0 to disable and 1 to enable.789 */790int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,791 bool enable)792{793 unsigned int val;794 795 if (enable)796 val = rdev->desc->active_discharge_on;797 else798 val = rdev->desc->active_discharge_off;799 800 return regmap_update_bits(rdev->regmap,801 rdev->desc->active_discharge_reg,802 rdev->desc->active_discharge_mask, val);803}804EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);805 806/**807 * regulator_set_current_limit_regmap - set_current_limit for regmap users808 *809 * @rdev: regulator to operate on810 * @min_uA: Lower bound for current limit811 * @max_uA: Upper bound for current limit812 *813 * Regulators that use regmap for their register I/O can set curr_table,814 * csel_reg and csel_mask fields in their descriptor and then use this815 * as their set_current_limit operation, saving some code.816 */817int regulator_set_current_limit_regmap(struct regulator_dev *rdev,818 int min_uA, int max_uA)819{820 unsigned int n_currents = rdev->desc->n_current_limits;821 int i, sel = -1;822 823 if (n_currents == 0)824 return -EINVAL;825 826 if (rdev->desc->curr_table) {827 const unsigned int *curr_table = rdev->desc->curr_table;828 bool ascend = curr_table[n_currents - 1] > curr_table[0];829 830 /* search for closest to maximum */831 if (ascend) {832 for (i = n_currents - 1; i >= 0; i--) {833 if (min_uA <= curr_table[i] &&834 curr_table[i] <= max_uA) {835 sel = i;836 break;837 }838 }839 } else {840 for (i = 0; i < n_currents; i++) {841 if (min_uA <= curr_table[i] &&842 curr_table[i] <= max_uA) {843 sel = i;844 break;845 }846 }847 }848 }849 850 if (sel < 0)851 return -EINVAL;852 853 sel <<= ffs(rdev->desc->csel_mask) - 1;854 855 return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,856 rdev->desc->csel_mask, sel);857}858EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap);859 860/**861 * regulator_get_current_limit_regmap - get_current_limit for regmap users862 *863 * @rdev: regulator to operate on864 *865 * Regulators that use regmap for their register I/O can set the866 * csel_reg and csel_mask fields in their descriptor and then use this867 * as their get_current_limit operation, saving some code.868 */869int regulator_get_current_limit_regmap(struct regulator_dev *rdev)870{871 unsigned int val;872 int ret;873 874 ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);875 if (ret != 0)876 return ret;877 878 val &= rdev->desc->csel_mask;879 val >>= ffs(rdev->desc->csel_mask) - 1;880 881 if (rdev->desc->curr_table) {882 if (val >= rdev->desc->n_current_limits)883 return -EINVAL;884 885 return rdev->desc->curr_table[val];886 }887 888 return -EINVAL;889}890EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);891 892/**893 * regulator_bulk_set_supply_names - initialize the 'supply' fields in an array894 * of regulator_bulk_data structs895 *896 * @consumers: array of regulator_bulk_data entries to initialize897 * @supply_names: array of supply name strings898 * @num_supplies: number of supply names to initialize899 *900 * Note: the 'consumers' array must be the size of 'num_supplies'.901 */902void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,903 const char *const *supply_names,904 unsigned int num_supplies)905{906 unsigned int i;907 908 for (i = 0; i < num_supplies; i++)909 consumers[i].supply = supply_names[i];910}911EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);912 913/**914 * regulator_is_equal - test whether two regulators are the same915 *916 * @reg1: first regulator to operate on917 * @reg2: second regulator to operate on918 */919bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)920{921 return reg1->rdev == reg2->rdev;922}923EXPORT_SYMBOL_GPL(regulator_is_equal);924 925/**926 * regulator_find_closest_bigger - helper to find offset in ramp delay table927 *928 * @target: targeted ramp_delay929 * @table: table with supported ramp delays930 * @num_sel: number of entries in the table931 * @sel: Pointer to store table offset932 *933 * This is the internal helper used by regulator_set_ramp_delay_regmap to934 * map ramp delay to register value. It should only be used directly if935 * regulator_set_ramp_delay_regmap cannot handle a specific device setup936 * (e.g. because the value is split over multiple registers).937 */938int regulator_find_closest_bigger(unsigned int target, const unsigned int *table,939 unsigned int num_sel, unsigned int *sel)940{941 unsigned int s, tmp, max, maxsel = 0;942 bool found = false;943 944 max = table[0];945 946 for (s = 0; s < num_sel; s++) {947 if (table[s] > max) {948 max = table[s];949 maxsel = s;950 }951 if (table[s] >= target) {952 if (!found || table[s] - target < tmp - target) {953 tmp = table[s];954 *sel = s;955 found = true;956 if (tmp == target)957 break;958 }959 }960 }961 962 if (!found) {963 *sel = maxsel;964 return -EINVAL;965 }966 967 return 0;968}969EXPORT_SYMBOL_GPL(regulator_find_closest_bigger);970 971/**972 * regulator_set_ramp_delay_regmap - set_ramp_delay() helper973 *974 * @rdev: regulator to operate on975 * @ramp_delay: ramp-rate value given in units V/S (uV/uS)976 *977 * Regulators that use regmap for their register I/O can set the ramp_reg978 * and ramp_mask fields in their descriptor and then use this as their979 * set_ramp_delay operation, saving some code.980 */981int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)982{983 int ret;984 unsigned int sel;985 986 if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table))987 return -EINVAL;988 989 ret = regulator_find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,990 rdev->desc->n_ramp_values, &sel);991 992 if (ret) {993 dev_warn(rdev_get_dev(rdev),994 "Can't set ramp-delay %u, setting %u\n", ramp_delay,995 rdev->desc->ramp_delay_table[sel]);996 }997 998 sel <<= ffs(rdev->desc->ramp_mask) - 1;999 1000 return regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,1001 rdev->desc->ramp_mask, sel);1002}1003EXPORT_SYMBOL_GPL(regulator_set_ramp_delay_regmap);1004