Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 //
0003 // helpers.c  --  Voltage/Current Regulator framework helper functions.
0004 //
0005 // Copyright 2007, 2008 Wolfson Microelectronics PLC.
0006 // Copyright 2008 SlimLogic Ltd.
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/err.h>
0010 #include <linux/delay.h>
0011 #include <linux/regmap.h>
0012 #include <linux/regulator/consumer.h>
0013 #include <linux/regulator/driver.h>
0014 #include <linux/module.h>
0015 
0016 #include "internal.h"
0017 
0018 /**
0019  * regulator_is_enabled_regmap - standard is_enabled() for regmap users
0020  *
0021  * @rdev: regulator to operate on
0022  *
0023  * Regulators that use regmap for their register I/O can set the
0024  * enable_reg and enable_mask fields in their descriptor and then use
0025  * this as their is_enabled operation, saving some code.
0026  */
0027 int regulator_is_enabled_regmap(struct regulator_dev *rdev)
0028 {
0029     unsigned int val;
0030     int ret;
0031 
0032     ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
0033     if (ret != 0)
0034         return ret;
0035 
0036     val &= rdev->desc->enable_mask;
0037 
0038     if (rdev->desc->enable_is_inverted) {
0039         if (rdev->desc->enable_val)
0040             return val != rdev->desc->enable_val;
0041         return val == 0;
0042     } else {
0043         if (rdev->desc->enable_val)
0044             return val == rdev->desc->enable_val;
0045         return val != 0;
0046     }
0047 }
0048 EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
0049 
0050 /**
0051  * regulator_enable_regmap - standard enable() for regmap users
0052  *
0053  * @rdev: regulator to operate on
0054  *
0055  * Regulators that use regmap for their register I/O can set the
0056  * enable_reg and enable_mask fields in their descriptor and then use
0057  * this as their enable() operation, saving some code.
0058  */
0059 int regulator_enable_regmap(struct regulator_dev *rdev)
0060 {
0061     unsigned int val;
0062 
0063     if (rdev->desc->enable_is_inverted) {
0064         val = rdev->desc->disable_val;
0065     } else {
0066         val = rdev->desc->enable_val;
0067         if (!val)
0068             val = rdev->desc->enable_mask;
0069     }
0070 
0071     return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
0072                   rdev->desc->enable_mask, val);
0073 }
0074 EXPORT_SYMBOL_GPL(regulator_enable_regmap);
0075 
0076 /**
0077  * regulator_disable_regmap - standard disable() for regmap users
0078  *
0079  * @rdev: regulator to operate on
0080  *
0081  * Regulators that use regmap for their register I/O can set the
0082  * enable_reg and enable_mask fields in their descriptor and then use
0083  * this as their disable() operation, saving some code.
0084  */
0085 int regulator_disable_regmap(struct regulator_dev *rdev)
0086 {
0087     unsigned int val;
0088 
0089     if (rdev->desc->enable_is_inverted) {
0090         val = rdev->desc->enable_val;
0091         if (!val)
0092             val = rdev->desc->enable_mask;
0093     } else {
0094         val = rdev->desc->disable_val;
0095     }
0096 
0097     return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
0098                   rdev->desc->enable_mask, val);
0099 }
0100 EXPORT_SYMBOL_GPL(regulator_disable_regmap);
0101 
0102 static int regulator_range_selector_to_index(struct regulator_dev *rdev,
0103                          unsigned int rval)
0104 {
0105     int i;
0106 
0107     if (!rdev->desc->linear_range_selectors)
0108         return -EINVAL;
0109 
0110     rval &= rdev->desc->vsel_range_mask;
0111 
0112     for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
0113         if (rdev->desc->linear_range_selectors[i] == rval)
0114             return i;
0115     }
0116     return -EINVAL;
0117 }
0118 
0119 /**
0120  * regulator_get_voltage_sel_pickable_regmap - pickable range get_voltage_sel
0121  *
0122  * @rdev: regulator to operate on
0123  *
0124  * Regulators that use regmap for their register I/O and use pickable
0125  * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
0126  * fields in their descriptor and then use this as their get_voltage_vsel
0127  * operation, saving some code.
0128  */
0129 int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
0130 {
0131     unsigned int r_val;
0132     int range;
0133     unsigned int val;
0134     int ret;
0135     unsigned int voltages = 0;
0136     const struct linear_range *r = rdev->desc->linear_ranges;
0137 
0138     if (!r)
0139         return -EINVAL;
0140 
0141     ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
0142     if (ret != 0)
0143         return ret;
0144 
0145     ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &r_val);
0146     if (ret != 0)
0147         return ret;
0148 
0149     val &= rdev->desc->vsel_mask;
0150     val >>= ffs(rdev->desc->vsel_mask) - 1;
0151 
0152     range = regulator_range_selector_to_index(rdev, r_val);
0153     if (range < 0)
0154         return -EINVAL;
0155 
0156     voltages = linear_range_values_in_range_array(r, range);
0157 
0158     return val + voltages;
0159 }
0160 EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
0161 
0162 /**
0163  * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel
0164  *
0165  * @rdev: regulator to operate on
0166  * @sel: Selector to set
0167  *
0168  * Regulators that use regmap for their register I/O and use pickable
0169  * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
0170  * fields in their descriptor and then use this as their set_voltage_vsel
0171  * operation, saving some code.
0172  */
0173 int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
0174                           unsigned int sel)
0175 {
0176     unsigned int range;
0177     int ret, i;
0178     unsigned int voltages_in_range = 0;
0179 
0180     for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
0181         const struct linear_range *r;
0182 
0183         r = &rdev->desc->linear_ranges[i];
0184         voltages_in_range = linear_range_values_in_range(r);
0185 
0186         if (sel < voltages_in_range)
0187             break;
0188         sel -= voltages_in_range;
0189     }
0190 
0191     if (i == rdev->desc->n_linear_ranges)
0192         return -EINVAL;
0193 
0194     sel <<= ffs(rdev->desc->vsel_mask) - 1;
0195     sel += rdev->desc->linear_ranges[i].min_sel;
0196 
0197     range = rdev->desc->linear_range_selectors[i];
0198 
0199     if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
0200         ret = regmap_update_bits(rdev->regmap,
0201                      rdev->desc->vsel_reg,
0202                      rdev->desc->vsel_range_mask |
0203                      rdev->desc->vsel_mask, sel | range);
0204     } else {
0205         ret = regmap_update_bits(rdev->regmap,
0206                      rdev->desc->vsel_range_reg,
0207                      rdev->desc->vsel_range_mask, range);
0208         if (ret)
0209             return ret;
0210 
0211         ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
0212                   rdev->desc->vsel_mask, sel);
0213     }
0214 
0215     if (ret)
0216         return ret;
0217 
0218     if (rdev->desc->apply_bit)
0219         ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
0220                      rdev->desc->apply_bit,
0221                      rdev->desc->apply_bit);
0222     return ret;
0223 }
0224 EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap);
0225 
0226 /**
0227  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
0228  *
0229  * @rdev: regulator to operate on
0230  *
0231  * Regulators that use regmap for their register I/O can set the
0232  * vsel_reg and vsel_mask fields in their descriptor and then use this
0233  * as their get_voltage_vsel operation, saving some code.
0234  */
0235 int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
0236 {
0237     unsigned int val;
0238     int ret;
0239 
0240     ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
0241     if (ret != 0)
0242         return ret;
0243 
0244     val &= rdev->desc->vsel_mask;
0245     val >>= ffs(rdev->desc->vsel_mask) - 1;
0246 
0247     return val;
0248 }
0249 EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
0250 
0251 /**
0252  * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
0253  *
0254  * @rdev: regulator to operate on
0255  * @sel: Selector to set
0256  *
0257  * Regulators that use regmap for their register I/O can set the
0258  * vsel_reg and vsel_mask fields in their descriptor and then use this
0259  * as their set_voltage_vsel operation, saving some code.
0260  */
0261 int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
0262 {
0263     int ret;
0264 
0265     sel <<= ffs(rdev->desc->vsel_mask) - 1;
0266 
0267     ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
0268                   rdev->desc->vsel_mask, sel);
0269     if (ret)
0270         return ret;
0271 
0272     if (rdev->desc->apply_bit)
0273         ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
0274                      rdev->desc->apply_bit,
0275                      rdev->desc->apply_bit);
0276     return ret;
0277 }
0278 EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
0279 
0280 /**
0281  * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
0282  *
0283  * @rdev: Regulator to operate on
0284  * @min_uV: Lower bound for voltage
0285  * @max_uV: Upper bound for voltage
0286  *
0287  * Drivers implementing set_voltage_sel() and list_voltage() can use
0288  * this as their map_voltage() operation.  It will find a suitable
0289  * voltage by calling list_voltage() until it gets something in bounds
0290  * for the requested voltages.
0291  */
0292 int regulator_map_voltage_iterate(struct regulator_dev *rdev,
0293                   int min_uV, int max_uV)
0294 {
0295     int best_val = INT_MAX;
0296     int selector = 0;
0297     int i, ret;
0298 
0299     /* Find the smallest voltage that falls within the specified
0300      * range.
0301      */
0302     for (i = 0; i < rdev->desc->n_voltages; i++) {
0303         ret = rdev->desc->ops->list_voltage(rdev, i);
0304         if (ret < 0)
0305             continue;
0306 
0307         if (ret < best_val && ret >= min_uV && ret <= max_uV) {
0308             best_val = ret;
0309             selector = i;
0310         }
0311     }
0312 
0313     if (best_val != INT_MAX)
0314         return selector;
0315     else
0316         return -EINVAL;
0317 }
0318 EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
0319 
0320 /**
0321  * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
0322  *
0323  * @rdev: Regulator to operate on
0324  * @min_uV: Lower bound for voltage
0325  * @max_uV: Upper bound for voltage
0326  *
0327  * Drivers that have ascendant voltage list can use this as their
0328  * map_voltage() operation.
0329  */
0330 int regulator_map_voltage_ascend(struct regulator_dev *rdev,
0331                  int min_uV, int max_uV)
0332 {
0333     int i, ret;
0334 
0335     for (i = 0; i < rdev->desc->n_voltages; i++) {
0336         ret = rdev->desc->ops->list_voltage(rdev, i);
0337         if (ret < 0)
0338             continue;
0339 
0340         if (ret > max_uV)
0341             break;
0342 
0343         if (ret >= min_uV && ret <= max_uV)
0344             return i;
0345     }
0346 
0347     return -EINVAL;
0348 }
0349 EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
0350 
0351 /**
0352  * regulator_map_voltage_linear - map_voltage() for simple linear mappings
0353  *
0354  * @rdev: Regulator to operate on
0355  * @min_uV: Lower bound for voltage
0356  * @max_uV: Upper bound for voltage
0357  *
0358  * Drivers providing min_uV and uV_step in their regulator_desc can
0359  * use this as their map_voltage() operation.
0360  */
0361 int regulator_map_voltage_linear(struct regulator_dev *rdev,
0362                  int min_uV, int max_uV)
0363 {
0364     int ret, voltage;
0365 
0366     /* Allow uV_step to be 0 for fixed voltage */
0367     if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
0368         if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
0369             return 0;
0370         else
0371             return -EINVAL;
0372     }
0373 
0374     if (!rdev->desc->uV_step) {
0375         BUG_ON(!rdev->desc->uV_step);
0376         return -EINVAL;
0377     }
0378 
0379     if (min_uV < rdev->desc->min_uV)
0380         min_uV = rdev->desc->min_uV;
0381 
0382     ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
0383     if (ret < 0)
0384         return ret;
0385 
0386     ret += rdev->desc->linear_min_sel;
0387 
0388     /* Map back into a voltage to verify we're still in bounds */
0389     voltage = rdev->desc->ops->list_voltage(rdev, ret);
0390     if (voltage < min_uV || voltage > max_uV)
0391         return -EINVAL;
0392 
0393     return ret;
0394 }
0395 EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
0396 
0397 /**
0398  * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges
0399  *
0400  * @rdev: Regulator to operate on
0401  * @min_uV: Lower bound for voltage
0402  * @max_uV: Upper bound for voltage
0403  *
0404  * Drivers providing linear_ranges in their descriptor can use this as
0405  * their map_voltage() callback.
0406  */
0407 int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
0408                        int min_uV, int max_uV)
0409 {
0410     const struct linear_range *range;
0411     int ret = -EINVAL;
0412     unsigned int sel;
0413     bool found;
0414     int voltage, i;
0415 
0416     if (!rdev->desc->n_linear_ranges) {
0417         BUG_ON(!rdev->desc->n_linear_ranges);
0418         return -EINVAL;
0419     }
0420 
0421     for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
0422         range = &rdev->desc->linear_ranges[i];
0423 
0424         ret = linear_range_get_selector_high(range, min_uV, &sel,
0425                              &found);
0426         if (ret)
0427             continue;
0428         ret = sel;
0429 
0430         /*
0431          * Map back into a voltage to verify we're still in bounds.
0432          * If we are not, then continue checking rest of the ranges.
0433          */
0434         voltage = rdev->desc->ops->list_voltage(rdev, sel);
0435         if (voltage >= min_uV && voltage <= max_uV)
0436             break;
0437     }
0438 
0439     if (i == rdev->desc->n_linear_ranges)
0440         return -EINVAL;
0441 
0442     return ret;
0443 }
0444 EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
0445 
0446 /**
0447  * regulator_map_voltage_pickable_linear_range - map_voltage, pickable ranges
0448  *
0449  * @rdev: Regulator to operate on
0450  * @min_uV: Lower bound for voltage
0451  * @max_uV: Upper bound for voltage
0452  *
0453  * Drivers providing pickable linear_ranges in their descriptor can use
0454  * this as their map_voltage() callback.
0455  */
0456 int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
0457                         int min_uV, int max_uV)
0458 {
0459     const struct linear_range *range;
0460     int ret = -EINVAL;
0461     int voltage, i;
0462     unsigned int selector = 0;
0463 
0464     if (!rdev->desc->n_linear_ranges) {
0465         BUG_ON(!rdev->desc->n_linear_ranges);
0466         return -EINVAL;
0467     }
0468 
0469     for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
0470         int linear_max_uV;
0471         bool found;
0472         unsigned int sel;
0473 
0474         range = &rdev->desc->linear_ranges[i];
0475         linear_max_uV = linear_range_get_max_value(range);
0476 
0477         if (!(min_uV <= linear_max_uV && max_uV >= range->min)) {
0478             selector += linear_range_values_in_range(range);
0479             continue;
0480         }
0481 
0482         ret = linear_range_get_selector_high(range, min_uV, &sel,
0483                              &found);
0484         if (ret) {
0485             selector += linear_range_values_in_range(range);
0486             continue;
0487         }
0488 
0489         ret = selector + sel - range->min_sel;
0490 
0491         voltage = rdev->desc->ops->list_voltage(rdev, ret);
0492 
0493         /*
0494          * Map back into a voltage to verify we're still in bounds.
0495          * We may have overlapping voltage ranges. Hence we don't
0496          * exit but retry until we have checked all ranges.
0497          */
0498         if (voltage < min_uV || voltage > max_uV)
0499             selector += linear_range_values_in_range(range);
0500         else
0501             break;
0502     }
0503 
0504     if (i == rdev->desc->n_linear_ranges)
0505         return -EINVAL;
0506 
0507     return ret;
0508 }
0509 EXPORT_SYMBOL_GPL(regulator_map_voltage_pickable_linear_range);
0510 
0511 /**
0512  * regulator_desc_list_voltage_linear - List voltages with simple calculation
0513  *
0514  * @desc: Regulator desc for regulator which volatges are to be listed
0515  * @selector: Selector to convert into a voltage
0516  *
0517  * Regulators with a simple linear mapping between voltages and
0518  * selectors can set min_uV and uV_step in the regulator descriptor
0519  * and then use this function prior regulator registration to list
0520  * the voltages. This is useful when voltages need to be listed during
0521  * device-tree parsing.
0522  */
0523 int regulator_desc_list_voltage_linear(const struct regulator_desc *desc,
0524                        unsigned int selector)
0525 {
0526     if (selector >= desc->n_voltages)
0527         return -EINVAL;
0528 
0529     if (selector < desc->linear_min_sel)
0530         return 0;
0531 
0532     selector -= desc->linear_min_sel;
0533 
0534     return desc->min_uV + (desc->uV_step * selector);
0535 }
0536 EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear);
0537 
0538 /**
0539  * regulator_list_voltage_linear - List voltages with simple calculation
0540  *
0541  * @rdev: Regulator device
0542  * @selector: Selector to convert into a voltage
0543  *
0544  * Regulators with a simple linear mapping between voltages and
0545  * selectors can set min_uV and uV_step in the regulator descriptor
0546  * and then use this function as their list_voltage() operation,
0547  */
0548 int regulator_list_voltage_linear(struct regulator_dev *rdev,
0549                   unsigned int selector)
0550 {
0551     return regulator_desc_list_voltage_linear(rdev->desc, selector);
0552 }
0553 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
0554 
0555 /**
0556  * regulator_list_voltage_pickable_linear_range - pickable range list voltages
0557  *
0558  * @rdev: Regulator device
0559  * @selector: Selector to convert into a voltage
0560  *
0561  * list_voltage() operation, intended to be used by drivers utilizing pickable
0562  * ranges helpers.
0563  */
0564 int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
0565                          unsigned int selector)
0566 {
0567     const struct linear_range *range;
0568     int i;
0569     unsigned int all_sels = 0;
0570 
0571     if (!rdev->desc->n_linear_ranges) {
0572         BUG_ON(!rdev->desc->n_linear_ranges);
0573         return -EINVAL;
0574     }
0575 
0576     for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
0577         unsigned int sel_indexes;
0578 
0579         range = &rdev->desc->linear_ranges[i];
0580 
0581         sel_indexes = linear_range_values_in_range(range) - 1;
0582 
0583         if (all_sels + sel_indexes >= selector) {
0584             selector -= all_sels;
0585             /*
0586              * As we see here, pickable ranges work only as
0587              * long as the first selector for each pickable
0588              * range is 0, and the each subsequent range for
0589              * this 'pick' follow immediately at next unused
0590              * selector (Eg. there is no gaps between ranges).
0591              * I think this is fine but it probably should be
0592              * documented. OTOH, whole pickable range stuff
0593              * might benefit from some documentation
0594              */
0595             return range->min + (range->step * selector);
0596         }
0597 
0598         all_sels += (sel_indexes + 1);
0599     }
0600 
0601     return -EINVAL;
0602 }
0603 EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
0604 
0605 /**
0606  * regulator_desc_list_voltage_linear_range - List voltages for linear ranges
0607  *
0608  * @desc: Regulator desc for regulator which volatges are to be listed
0609  * @selector: Selector to convert into a voltage
0610  *
0611  * Regulators with a series of simple linear mappings between voltages
0612  * and selectors who have set linear_ranges in the regulator descriptor
0613  * can use this function prior regulator registration to list voltages.
0614  * This is useful when voltages need to be listed during device-tree
0615  * parsing.
0616  */
0617 int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
0618                          unsigned int selector)
0619 {
0620     unsigned int val;
0621     int ret;
0622 
0623     BUG_ON(!desc->n_linear_ranges);
0624 
0625     ret = linear_range_get_value_array(desc->linear_ranges,
0626                        desc->n_linear_ranges, selector,
0627                        &val);
0628     if (ret)
0629         return ret;
0630 
0631     return val;
0632 }
0633 EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range);
0634 
0635 /**
0636  * regulator_list_voltage_linear_range - List voltages for linear ranges
0637  *
0638  * @rdev: Regulator device
0639  * @selector: Selector to convert into a voltage
0640  *
0641  * Regulators with a series of simple linear mappings between voltages
0642  * and selectors can set linear_ranges in the regulator descriptor and
0643  * then use this function as their list_voltage() operation,
0644  */
0645 int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
0646                     unsigned int selector)
0647 {
0648     return regulator_desc_list_voltage_linear_range(rdev->desc, selector);
0649 }
0650 EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
0651 
0652 /**
0653  * regulator_list_voltage_table - List voltages with table based mapping
0654  *
0655  * @rdev: Regulator device
0656  * @selector: Selector to convert into a voltage
0657  *
0658  * Regulators with table based mapping between voltages and
0659  * selectors can set volt_table in the regulator descriptor
0660  * and then use this function as their list_voltage() operation.
0661  */
0662 int regulator_list_voltage_table(struct regulator_dev *rdev,
0663                  unsigned int selector)
0664 {
0665     if (!rdev->desc->volt_table) {
0666         BUG_ON(!rdev->desc->volt_table);
0667         return -EINVAL;
0668     }
0669 
0670     if (selector >= rdev->desc->n_voltages)
0671         return -EINVAL;
0672     if (selector < rdev->desc->linear_min_sel)
0673         return 0;
0674 
0675     return rdev->desc->volt_table[selector];
0676 }
0677 EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
0678 
0679 /**
0680  * regulator_set_bypass_regmap - Default set_bypass() using regmap
0681  *
0682  * @rdev: device to operate on.
0683  * @enable: state to set.
0684  */
0685 int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
0686 {
0687     unsigned int val;
0688 
0689     if (enable) {
0690         val = rdev->desc->bypass_val_on;
0691         if (!val)
0692             val = rdev->desc->bypass_mask;
0693     } else {
0694         val = rdev->desc->bypass_val_off;
0695     }
0696 
0697     return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
0698                   rdev->desc->bypass_mask, val);
0699 }
0700 EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
0701 
0702 /**
0703  * regulator_set_soft_start_regmap - Default set_soft_start() using regmap
0704  *
0705  * @rdev: device to operate on.
0706  */
0707 int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
0708 {
0709     unsigned int val;
0710 
0711     val = rdev->desc->soft_start_val_on;
0712     if (!val)
0713         val = rdev->desc->soft_start_mask;
0714 
0715     return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,
0716                   rdev->desc->soft_start_mask, val);
0717 }
0718 EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
0719 
0720 /**
0721  * regulator_set_pull_down_regmap - Default set_pull_down() using regmap
0722  *
0723  * @rdev: device to operate on.
0724  */
0725 int regulator_set_pull_down_regmap(struct regulator_dev *rdev)
0726 {
0727     unsigned int val;
0728 
0729     val = rdev->desc->pull_down_val_on;
0730     if (!val)
0731         val = rdev->desc->pull_down_mask;
0732 
0733     return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,
0734                   rdev->desc->pull_down_mask, val);
0735 }
0736 EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);
0737 
0738 /**
0739  * regulator_get_bypass_regmap - Default get_bypass() using regmap
0740  *
0741  * @rdev: device to operate on.
0742  * @enable: current state.
0743  */
0744 int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
0745 {
0746     unsigned int val;
0747     unsigned int val_on = rdev->desc->bypass_val_on;
0748     int ret;
0749 
0750     ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
0751     if (ret != 0)
0752         return ret;
0753 
0754     if (!val_on)
0755         val_on = rdev->desc->bypass_mask;
0756 
0757     *enable = (val & rdev->desc->bypass_mask) == val_on;
0758 
0759     return 0;
0760 }
0761 EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
0762 
0763 /**
0764  * regulator_set_active_discharge_regmap - Default set_active_discharge()
0765  *                     using regmap
0766  *
0767  * @rdev: device to operate on.
0768  * @enable: state to set, 0 to disable and 1 to enable.
0769  */
0770 int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
0771                       bool enable)
0772 {
0773     unsigned int val;
0774 
0775     if (enable)
0776         val = rdev->desc->active_discharge_on;
0777     else
0778         val = rdev->desc->active_discharge_off;
0779 
0780     return regmap_update_bits(rdev->regmap,
0781                   rdev->desc->active_discharge_reg,
0782                   rdev->desc->active_discharge_mask, val);
0783 }
0784 EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
0785 
0786 /**
0787  * regulator_set_current_limit_regmap - set_current_limit for regmap users
0788  *
0789  * @rdev: regulator to operate on
0790  * @min_uA: Lower bound for current limit
0791  * @max_uA: Upper bound for current limit
0792  *
0793  * Regulators that use regmap for their register I/O can set curr_table,
0794  * csel_reg and csel_mask fields in their descriptor and then use this
0795  * as their set_current_limit operation, saving some code.
0796  */
0797 int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
0798                        int min_uA, int max_uA)
0799 {
0800     unsigned int n_currents = rdev->desc->n_current_limits;
0801     int i, sel = -1;
0802 
0803     if (n_currents == 0)
0804         return -EINVAL;
0805 
0806     if (rdev->desc->curr_table) {
0807         const unsigned int *curr_table = rdev->desc->curr_table;
0808         bool ascend = curr_table[n_currents - 1] > curr_table[0];
0809 
0810         /* search for closest to maximum */
0811         if (ascend) {
0812             for (i = n_currents - 1; i >= 0; i--) {
0813                 if (min_uA <= curr_table[i] &&
0814                     curr_table[i] <= max_uA) {
0815                     sel = i;
0816                     break;
0817                 }
0818             }
0819         } else {
0820             for (i = 0; i < n_currents; i++) {
0821                 if (min_uA <= curr_table[i] &&
0822                     curr_table[i] <= max_uA) {
0823                     sel = i;
0824                     break;
0825                 }
0826             }
0827         }
0828     }
0829 
0830     if (sel < 0)
0831         return -EINVAL;
0832 
0833     sel <<= ffs(rdev->desc->csel_mask) - 1;
0834 
0835     return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,
0836                   rdev->desc->csel_mask, sel);
0837 }
0838 EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap);
0839 
0840 /**
0841  * regulator_get_current_limit_regmap - get_current_limit for regmap users
0842  *
0843  * @rdev: regulator to operate on
0844  *
0845  * Regulators that use regmap for their register I/O can set the
0846  * csel_reg and csel_mask fields in their descriptor and then use this
0847  * as their get_current_limit operation, saving some code.
0848  */
0849 int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
0850 {
0851     unsigned int val;
0852     int ret;
0853 
0854     ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);
0855     if (ret != 0)
0856         return ret;
0857 
0858     val &= rdev->desc->csel_mask;
0859     val >>= ffs(rdev->desc->csel_mask) - 1;
0860 
0861     if (rdev->desc->curr_table) {
0862         if (val >= rdev->desc->n_current_limits)
0863             return -EINVAL;
0864 
0865         return rdev->desc->curr_table[val];
0866     }
0867 
0868     return -EINVAL;
0869 }
0870 EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
0871 
0872 /**
0873  * regulator_bulk_set_supply_names - initialize the 'supply' fields in an array
0874  *                                   of regulator_bulk_data structs
0875  *
0876  * @consumers: array of regulator_bulk_data entries to initialize
0877  * @supply_names: array of supply name strings
0878  * @num_supplies: number of supply names to initialize
0879  *
0880  * Note: the 'consumers' array must be the size of 'num_supplies'.
0881  */
0882 void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
0883                      const char *const *supply_names,
0884                      unsigned int num_supplies)
0885 {
0886     unsigned int i;
0887 
0888     for (i = 0; i < num_supplies; i++)
0889         consumers[i].supply = supply_names[i];
0890 }
0891 EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
0892 
0893 /**
0894  * regulator_is_equal - test whether two regulators are the same
0895  *
0896  * @reg1: first regulator to operate on
0897  * @reg2: second regulator to operate on
0898  */
0899 bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
0900 {
0901     return reg1->rdev == reg2->rdev;
0902 }
0903 EXPORT_SYMBOL_GPL(regulator_is_equal);
0904 
0905 static int find_closest_bigger(unsigned int target, const unsigned int *table,
0906                    unsigned int num_sel, unsigned int *sel)
0907 {
0908     unsigned int s, tmp, max, maxsel = 0;
0909     bool found = false;
0910 
0911     max = table[0];
0912 
0913     for (s = 0; s < num_sel; s++) {
0914         if (table[s] > max) {
0915             max = table[s];
0916             maxsel = s;
0917         }
0918         if (table[s] >= target) {
0919             if (!found || table[s] - target < tmp - target) {
0920                 tmp = table[s];
0921                 *sel = s;
0922                 found = true;
0923                 if (tmp == target)
0924                     break;
0925             }
0926         }
0927     }
0928 
0929     if (!found) {
0930         *sel = maxsel;
0931         return -EINVAL;
0932     }
0933 
0934     return 0;
0935 }
0936 
0937 /**
0938  * regulator_set_ramp_delay_regmap - set_ramp_delay() helper
0939  *
0940  * @rdev: regulator to operate on
0941  *
0942  * Regulators that use regmap for their register I/O can set the ramp_reg
0943  * and ramp_mask fields in their descriptor and then use this as their
0944  * set_ramp_delay operation, saving some code.
0945  */
0946 int regulator_set_ramp_delay_regmap(struct regulator_dev *rdev, int ramp_delay)
0947 {
0948     int ret;
0949     unsigned int sel;
0950 
0951     if (WARN_ON(!rdev->desc->n_ramp_values || !rdev->desc->ramp_delay_table))
0952         return -EINVAL;
0953 
0954     ret = find_closest_bigger(ramp_delay, rdev->desc->ramp_delay_table,
0955                   rdev->desc->n_ramp_values, &sel);
0956 
0957     if (ret) {
0958         dev_warn(rdev_get_dev(rdev),
0959              "Can't set ramp-delay %u, setting %u\n", ramp_delay,
0960              rdev->desc->ramp_delay_table[sel]);
0961     }
0962 
0963     sel <<= ffs(rdev->desc->ramp_mask) - 1;
0964 
0965     return regmap_update_bits(rdev->regmap, rdev->desc->ramp_reg,
0966                   rdev->desc->ramp_mask, sel);
0967 }
0968 EXPORT_SYMBOL_GPL(regulator_set_ramp_delay_regmap);