1c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/* 2c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * helpers.c -- Voltage/Current Regulator framework helper functions. 3c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 4c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Copyright 2007, 2008 Wolfson Microelectronics PLC. 5c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Copyright 2008 SlimLogic Ltd. 6c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 7c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * This program is free software; you can redistribute it and/or modify it 8c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * under the terms of the GNU General Public License as published by the 9c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Free Software Foundation; either version 2 of the License, or (at your 10c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * option) any later version. 11c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 12c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 13c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 14c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/kernel.h> 15c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/err.h> 16c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/delay.h> 17c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/regmap.h> 18c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/regulator/consumer.h> 19c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/regulator/driver.h> 20c4a54b8d54218a75b94ab9947449e688869df00dMark Brown#include <linux/module.h> 21c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 22c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 23c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_is_enabled_regmap - standard is_enabled() for regmap users 24c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 25c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on 26c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 27c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the 28c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * enable_reg and enable_mask fields in their descriptor and then use 29c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their is_enabled operation, saving some code. 30c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 31c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_is_enabled_regmap(struct regulator_dev *rdev) 32c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 33c4a54b8d54218a75b94ab9947449e688869df00dMark Brown unsigned int val; 34c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int ret; 35c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 36c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); 37c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret != 0) 38c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 39c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 40ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val &= rdev->desc->enable_mask; 41ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione 42ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (rdev->desc->enable_is_inverted) { 43ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (rdev->desc->enable_val) 44ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione return val != rdev->desc->enable_val; 45ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione return val == 0; 46ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } else { 47ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (rdev->desc->enable_val) 48ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione return val == rdev->desc->enable_val; 49ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione return val != 0; 50ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } 51c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 52c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); 53c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 54c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 55c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_enable_regmap - standard enable() for regmap users 56c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 57c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on 58c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 59c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the 60c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * enable_reg and enable_mask fields in their descriptor and then use 61c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their enable() operation, saving some code. 62c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 63c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_enable_regmap(struct regulator_dev *rdev) 64c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 65c4a54b8d54218a75b94ab9947449e688869df00dMark Brown unsigned int val; 66c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 67ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (rdev->desc->enable_is_inverted) { 68ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->disable_val; 69ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } else { 70ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->enable_val; 71ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (!val) 72ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->enable_mask; 73ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } 74c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 75c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 76c4a54b8d54218a75b94ab9947449e688869df00dMark Brown rdev->desc->enable_mask, val); 77c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 78c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_enable_regmap); 79c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 80c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 81c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_disable_regmap - standard disable() for regmap users 82c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 83c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on 84c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 85c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the 86c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * enable_reg and enable_mask fields in their descriptor and then use 87c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their disable() operation, saving some code. 88c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 89c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_disable_regmap(struct regulator_dev *rdev) 90c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 91c4a54b8d54218a75b94ab9947449e688869df00dMark Brown unsigned int val; 92c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 93ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (rdev->desc->enable_is_inverted) { 94ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->enable_val; 95ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (!val) 96ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->enable_mask; 97ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } else { 98ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->disable_val; 99ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } 100c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 101c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 102c4a54b8d54218a75b94ab9947449e688869df00dMark Brown rdev->desc->enable_mask, val); 103c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 104c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_disable_regmap); 105c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 106c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 107c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users 108c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 109c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on 110c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 111c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the 112c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * vsel_reg and vsel_mask fields in their descriptor and then use this 113c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * as their get_voltage_vsel operation, saving some code. 114c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 115c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) 116c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 117c4a54b8d54218a75b94ab9947449e688869df00dMark Brown unsigned int val; 118c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int ret; 119c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 120c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); 121c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret != 0) 122c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 123c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 124c4a54b8d54218a75b94ab9947449e688869df00dMark Brown val &= rdev->desc->vsel_mask; 125c4a54b8d54218a75b94ab9947449e688869df00dMark Brown val >>= ffs(rdev->desc->vsel_mask) - 1; 126c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 127c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return val; 128c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 129c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); 130c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 131c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 132c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users 133c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 134c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: regulator to operate on 135c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @sel: Selector to set 136c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 137c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Regulators that use regmap for their register I/O can set the 138c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * vsel_reg and vsel_mask fields in their descriptor and then use this 139c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * as their set_voltage_vsel operation, saving some code. 140c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 141c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) 142c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 143c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int ret; 144c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 145c4a54b8d54218a75b94ab9947449e688869df00dMark Brown sel <<= ffs(rdev->desc->vsel_mask) - 1; 146c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 147c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, 148c4a54b8d54218a75b94ab9947449e688869df00dMark Brown rdev->desc->vsel_mask, sel); 149c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret) 150c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 151c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 152c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (rdev->desc->apply_bit) 153c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg, 154c4a54b8d54218a75b94ab9947449e688869df00dMark Brown rdev->desc->apply_bit, 155c4a54b8d54218a75b94ab9947449e688869df00dMark Brown rdev->desc->apply_bit); 156c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 157c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 158c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); 159c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 160c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 161c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_iterate - map_voltage() based on list_voltage() 162c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 163c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on 164c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage 165c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage 166c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 167c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers implementing set_voltage_sel() and list_voltage() can use 168c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * this as their map_voltage() operation. It will find a suitable 169c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * voltage by calling list_voltage() until it gets something in bounds 170c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * for the requested voltages. 171c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 172c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_iterate(struct regulator_dev *rdev, 173c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int min_uV, int max_uV) 174c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 175c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int best_val = INT_MAX; 176c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int selector = 0; 177c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int i, ret; 178c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 179c4a54b8d54218a75b94ab9947449e688869df00dMark Brown /* Find the smallest voltage that falls within the specified 180c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * range. 181c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 182c4a54b8d54218a75b94ab9947449e688869df00dMark Brown for (i = 0; i < rdev->desc->n_voltages; i++) { 183c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = rdev->desc->ops->list_voltage(rdev, i); 184c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret < 0) 185c4a54b8d54218a75b94ab9947449e688869df00dMark Brown continue; 186c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 187c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret < best_val && ret >= min_uV && ret <= max_uV) { 188c4a54b8d54218a75b94ab9947449e688869df00dMark Brown best_val = ret; 189c4a54b8d54218a75b94ab9947449e688869df00dMark Brown selector = i; 190c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 191c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 192c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 193c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (best_val != INT_MAX) 194c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return selector; 195c4a54b8d54218a75b94ab9947449e688869df00dMark Brown else 196c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 197c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 198c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_iterate); 199c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 200c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 201c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list 202c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 203c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on 204c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage 205c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage 206c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 207c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers that have ascendant voltage list can use this as their 208c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * map_voltage() operation. 209c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 210c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_ascend(struct regulator_dev *rdev, 211c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int min_uV, int max_uV) 212c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 213c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int i, ret; 214c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 215c4a54b8d54218a75b94ab9947449e688869df00dMark Brown for (i = 0; i < rdev->desc->n_voltages; i++) { 216c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = rdev->desc->ops->list_voltage(rdev, i); 217c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret < 0) 218c4a54b8d54218a75b94ab9947449e688869df00dMark Brown continue; 219c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 220c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret > max_uV) 221c4a54b8d54218a75b94ab9947449e688869df00dMark Brown break; 222c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 223c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret >= min_uV && ret <= max_uV) 224c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return i; 225c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 226c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 227c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 228c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 229c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_ascend); 230c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 231c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 232c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_linear - map_voltage() for simple linear mappings 233c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 234c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on 235c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage 236c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage 237c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 238c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers providing min_uV and uV_step in their regulator_desc can 239c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * use this as their map_voltage() operation. 240c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 241c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_linear(struct regulator_dev *rdev, 242c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int min_uV, int max_uV) 243c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 244c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int ret, voltage; 245c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 246c4a54b8d54218a75b94ab9947449e688869df00dMark Brown /* Allow uV_step to be 0 for fixed voltage */ 247c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) { 248c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV) 249c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return 0; 250c4a54b8d54218a75b94ab9947449e688869df00dMark Brown else 251c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 252c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 253c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 254c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (!rdev->desc->uV_step) { 255c4a54b8d54218a75b94ab9947449e688869df00dMark Brown BUG_ON(!rdev->desc->uV_step); 256c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 257c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 258c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 259c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (min_uV < rdev->desc->min_uV) 260c4a54b8d54218a75b94ab9947449e688869df00dMark Brown min_uV = rdev->desc->min_uV; 261c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 262c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); 263c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret < 0) 264c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 265c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 266c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret += rdev->desc->linear_min_sel; 267c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 268c4a54b8d54218a75b94ab9947449e688869df00dMark Brown /* Map back into a voltage to verify we're still in bounds */ 269c4a54b8d54218a75b94ab9947449e688869df00dMark Brown voltage = rdev->desc->ops->list_voltage(rdev, ret); 270c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (voltage < min_uV || voltage > max_uV) 271c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 272c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 273c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 274c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 275c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_linear); 276c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 277c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 278c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_map_voltage_linear - map_voltage() for multiple linear ranges 279c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 280c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: Regulator to operate on 281c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @min_uV: Lower bound for voltage 282c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @max_uV: Upper bound for voltage 283c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 284c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * Drivers providing linear_ranges in their descriptor can use this as 285c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * their map_voltage() callback. 286c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 287c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_map_voltage_linear_range(struct regulator_dev *rdev, 288c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int min_uV, int max_uV) 289c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 290c4a54b8d54218a75b94ab9947449e688869df00dMark Brown const struct regulator_linear_range *range; 291c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int ret = -EINVAL; 292c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int voltage, i; 293c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 294c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (!rdev->desc->n_linear_ranges) { 295c4a54b8d54218a75b94ab9947449e688869df00dMark Brown BUG_ON(!rdev->desc->n_linear_ranges); 296c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 297c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 298c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 299c4a54b8d54218a75b94ab9947449e688869df00dMark Brown for (i = 0; i < rdev->desc->n_linear_ranges; i++) { 300e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin int linear_max_uV; 301e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin 302c4a54b8d54218a75b94ab9947449e688869df00dMark Brown range = &rdev->desc->linear_ranges[i]; 303e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin linear_max_uV = range->min_uV + 304e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin (range->max_sel - range->min_sel) * range->uV_step; 305c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 306e277e656804c85a0729d4fd8cdd3c8ab3e6b3b86Axel Lin if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV)) 307c4a54b8d54218a75b94ab9947449e688869df00dMark Brown continue; 308c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 309c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (min_uV <= range->min_uV) 310c4a54b8d54218a75b94ab9947449e688869df00dMark Brown min_uV = range->min_uV; 311c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 312c4a54b8d54218a75b94ab9947449e688869df00dMark Brown /* range->uV_step == 0 means fixed voltage range */ 313c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (range->uV_step == 0) { 314c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = 0; 315c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } else { 316c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = DIV_ROUND_UP(min_uV - range->min_uV, 317c4a54b8d54218a75b94ab9947449e688869df00dMark Brown range->uV_step); 318c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret < 0) 319c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 320c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 321c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 322c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret += range->min_sel; 323c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 324c4a54b8d54218a75b94ab9947449e688869df00dMark Brown break; 325c4a54b8d54218a75b94ab9947449e688869df00dMark Brown } 326c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 327c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (i == rdev->desc->n_linear_ranges) 328c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 329c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 330c4a54b8d54218a75b94ab9947449e688869df00dMark Brown /* Map back into a voltage to verify we're still in bounds */ 331c4a54b8d54218a75b94ab9947449e688869df00dMark Brown voltage = rdev->desc->ops->list_voltage(rdev, ret); 332c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (voltage < min_uV || voltage > max_uV) 333c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return -EINVAL; 334c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 335c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 336c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 337c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range); 338c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 339c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 340d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * regulator_list_voltage_linear - List voltages with simple calculation 341d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * 342d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @rdev: Regulator device 343d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @selector: Selector to convert into a voltage 344d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * 345d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * Regulators with a simple linear mapping between voltages and 346d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * selectors can set min_uV and uV_step in the regulator descriptor 347d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * and then use this function as their list_voltage() operation, 348d295f7670127eb241d81e96e003b380c77c2b254Axel Lin */ 349d295f7670127eb241d81e96e003b380c77c2b254Axel Linint regulator_list_voltage_linear(struct regulator_dev *rdev, 350d295f7670127eb241d81e96e003b380c77c2b254Axel Lin unsigned int selector) 351d295f7670127eb241d81e96e003b380c77c2b254Axel Lin{ 352d295f7670127eb241d81e96e003b380c77c2b254Axel Lin if (selector >= rdev->desc->n_voltages) 353d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return -EINVAL; 354d295f7670127eb241d81e96e003b380c77c2b254Axel Lin if (selector < rdev->desc->linear_min_sel) 355d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return 0; 356d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 357d295f7670127eb241d81e96e003b380c77c2b254Axel Lin selector -= rdev->desc->linear_min_sel; 358d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 359d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return rdev->desc->min_uV + (rdev->desc->uV_step * selector); 360d295f7670127eb241d81e96e003b380c77c2b254Axel Lin} 361d295f7670127eb241d81e96e003b380c77c2b254Axel LinEXPORT_SYMBOL_GPL(regulator_list_voltage_linear); 362d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 363d295f7670127eb241d81e96e003b380c77c2b254Axel Lin/** 364d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * regulator_list_voltage_linear_range - List voltages for linear ranges 365d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * 366d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @rdev: Regulator device 367d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @selector: Selector to convert into a voltage 368d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * 369d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * Regulators with a series of simple linear mappings between voltages 370d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * and selectors can set linear_ranges in the regulator descriptor and 371d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * then use this function as their list_voltage() operation, 372d295f7670127eb241d81e96e003b380c77c2b254Axel Lin */ 373d295f7670127eb241d81e96e003b380c77c2b254Axel Linint regulator_list_voltage_linear_range(struct regulator_dev *rdev, 374d295f7670127eb241d81e96e003b380c77c2b254Axel Lin unsigned int selector) 375d295f7670127eb241d81e96e003b380c77c2b254Axel Lin{ 376d295f7670127eb241d81e96e003b380c77c2b254Axel Lin const struct regulator_linear_range *range; 377d295f7670127eb241d81e96e003b380c77c2b254Axel Lin int i; 378d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 379d295f7670127eb241d81e96e003b380c77c2b254Axel Lin if (!rdev->desc->n_linear_ranges) { 380d295f7670127eb241d81e96e003b380c77c2b254Axel Lin BUG_ON(!rdev->desc->n_linear_ranges); 381d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return -EINVAL; 382d295f7670127eb241d81e96e003b380c77c2b254Axel Lin } 383d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 384d295f7670127eb241d81e96e003b380c77c2b254Axel Lin for (i = 0; i < rdev->desc->n_linear_ranges; i++) { 385d295f7670127eb241d81e96e003b380c77c2b254Axel Lin range = &rdev->desc->linear_ranges[i]; 386d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 387d295f7670127eb241d81e96e003b380c77c2b254Axel Lin if (!(selector >= range->min_sel && 388d295f7670127eb241d81e96e003b380c77c2b254Axel Lin selector <= range->max_sel)) 389d295f7670127eb241d81e96e003b380c77c2b254Axel Lin continue; 390d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 391d295f7670127eb241d81e96e003b380c77c2b254Axel Lin selector -= range->min_sel; 392d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 393d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return range->min_uV + (range->uV_step * selector); 394d295f7670127eb241d81e96e003b380c77c2b254Axel Lin } 395d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 396d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return -EINVAL; 397d295f7670127eb241d81e96e003b380c77c2b254Axel Lin} 398d295f7670127eb241d81e96e003b380c77c2b254Axel LinEXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range); 399d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 400d295f7670127eb241d81e96e003b380c77c2b254Axel Lin/** 401d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * regulator_list_voltage_table - List voltages with table based mapping 402d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * 403d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @rdev: Regulator device 404d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * @selector: Selector to convert into a voltage 405d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * 406d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * Regulators with table based mapping between voltages and 407d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * selectors can set volt_table in the regulator descriptor 408d295f7670127eb241d81e96e003b380c77c2b254Axel Lin * and then use this function as their list_voltage() operation. 409d295f7670127eb241d81e96e003b380c77c2b254Axel Lin */ 410d295f7670127eb241d81e96e003b380c77c2b254Axel Linint regulator_list_voltage_table(struct regulator_dev *rdev, 411d295f7670127eb241d81e96e003b380c77c2b254Axel Lin unsigned int selector) 412d295f7670127eb241d81e96e003b380c77c2b254Axel Lin{ 413d295f7670127eb241d81e96e003b380c77c2b254Axel Lin if (!rdev->desc->volt_table) { 414d295f7670127eb241d81e96e003b380c77c2b254Axel Lin BUG_ON(!rdev->desc->volt_table); 415d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return -EINVAL; 416d295f7670127eb241d81e96e003b380c77c2b254Axel Lin } 417d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 418d295f7670127eb241d81e96e003b380c77c2b254Axel Lin if (selector >= rdev->desc->n_voltages) 419d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return -EINVAL; 420d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 421d295f7670127eb241d81e96e003b380c77c2b254Axel Lin return rdev->desc->volt_table[selector]; 422d295f7670127eb241d81e96e003b380c77c2b254Axel Lin} 423d295f7670127eb241d81e96e003b380c77c2b254Axel LinEXPORT_SYMBOL_GPL(regulator_list_voltage_table); 424d295f7670127eb241d81e96e003b380c77c2b254Axel Lin 425d295f7670127eb241d81e96e003b380c77c2b254Axel Lin/** 426c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_set_bypass_regmap - Default set_bypass() using regmap 427c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 428c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: device to operate on. 429c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @enable: state to set. 430c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 431c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable) 432c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 433c4a54b8d54218a75b94ab9947449e688869df00dMark Brown unsigned int val; 434c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 435ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (enable) { 436ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->bypass_val_on; 437ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione if (!val) 438ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->bypass_mask; 439ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } else { 440ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione val = rdev->desc->bypass_val_off; 441ca5d1b3524b4d90a2e2f1f71583c1dca6b96fd92Carlo Caione } 442c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 443c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, 444c4a54b8d54218a75b94ab9947449e688869df00dMark Brown rdev->desc->bypass_mask, val); 445c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 446c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_set_bypass_regmap); 447c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 448c4a54b8d54218a75b94ab9947449e688869df00dMark Brown/** 449c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * regulator_get_bypass_regmap - Default get_bypass() using regmap 450c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * 451c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @rdev: device to operate on. 452c4a54b8d54218a75b94ab9947449e688869df00dMark Brown * @enable: current state. 453c4a54b8d54218a75b94ab9947449e688869df00dMark Brown */ 454c4a54b8d54218a75b94ab9947449e688869df00dMark Brownint regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable) 455c4a54b8d54218a75b94ab9947449e688869df00dMark Brown{ 456c4a54b8d54218a75b94ab9947449e688869df00dMark Brown unsigned int val; 457c4a54b8d54218a75b94ab9947449e688869df00dMark Brown int ret; 458c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 459c4a54b8d54218a75b94ab9947449e688869df00dMark Brown ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val); 460c4a54b8d54218a75b94ab9947449e688869df00dMark Brown if (ret != 0) 461c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return ret; 462c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 463c4a54b8d54218a75b94ab9947449e688869df00dMark Brown *enable = val & rdev->desc->bypass_mask; 464c4a54b8d54218a75b94ab9947449e688869df00dMark Brown 465c4a54b8d54218a75b94ab9947449e688869df00dMark Brown return 0; 466c4a54b8d54218a75b94ab9947449e688869df00dMark Brown} 467c4a54b8d54218a75b94ab9947449e688869df00dMark BrownEXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); 468