linux/drivers/regulator/helpers.c
<<
>>
Prefs
   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 */
  31int 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        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        }
  51}
  52EXPORT_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 */
  63int regulator_enable_regmap(struct regulator_dev *rdev)
  64{
  65        unsigned int val;
  66
  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        }
  74
  75        return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
  76                                  rdev->desc->enable_mask, val);
  77}
  78EXPORT_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 */
  89int regulator_disable_regmap(struct regulator_dev *rdev)
  90{
  91        unsigned int val;
  92
  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        }
 100
 101        return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
 102                                  rdev->desc->enable_mask, val);
 103}
 104EXPORT_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 */
 115int 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}
 129EXPORT_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 */
 141int 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}
 158EXPORT_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 */
 172int 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}
 198EXPORT_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 */
 210int 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}
 229EXPORT_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 */
 241int 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}
 275EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
 276
 277/**
 278 * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges
 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 */
 287int 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++) {
 300                int linear_max_uV;
 301
 302                range = &rdev->desc->linear_ranges[i];
 303                linear_max_uV = range->min_uV +
 304                        (range->max_sel - range->min_sel) * range->uV_step;
 305
 306                if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
 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}
 337EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
 338
 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 */
 349int 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}
 361EXPORT_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 */
 373int 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}
 398EXPORT_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 */
 410int 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}
 423EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
 424
 425/**
 426 * regulator_set_bypass_regmap - Default set_bypass() using regmap
 427 *
 428 * @rdev: device to operate on.
 429 * @enable: state to set.
 430 */
 431int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
 432{
 433        unsigned int val;
 434
 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        }
 442
 443        return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
 444                                  rdev->desc->bypass_mask, val);
 445}
 446EXPORT_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 */
 454int 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
 463        *enable = val & rdev->desc->bypass_mask;
 464
 465        return 0;
 466}
 467EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
 468