Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) // helpers.c  --  Voltage/Current Regulator framework helper functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) // Copyright 2007, 2008 Wolfson Microelectronics PLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) // Copyright 2008 SlimLogic Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * regulator_is_enabled_regmap - standard is_enabled() for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * Regulators that use regmap for their register I/O can set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * enable_reg and enable_mask fields in their descriptor and then use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * this as their is_enabled operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) int regulator_is_enabled_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	val &= rdev->desc->enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	if (rdev->desc->enable_is_inverted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		if (rdev->desc->enable_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			return val != rdev->desc->enable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return val == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		if (rdev->desc->enable_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			return val == rdev->desc->enable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return val != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * regulator_enable_regmap - standard enable() for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * Regulators that use regmap for their register I/O can set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * enable_reg and enable_mask fields in their descriptor and then use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * this as their enable() operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) int regulator_enable_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (rdev->desc->enable_is_inverted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		val = rdev->desc->disable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		val = rdev->desc->enable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			val = rdev->desc->enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 				  rdev->desc->enable_mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) EXPORT_SYMBOL_GPL(regulator_enable_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * regulator_disable_regmap - standard disable() for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * Regulators that use regmap for their register I/O can set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * enable_reg and enable_mask fields in their descriptor and then use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * this as their disable() operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) int regulator_disable_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (rdev->desc->enable_is_inverted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		val = rdev->desc->enable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			val = rdev->desc->enable_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		val = rdev->desc->disable_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 				  rdev->desc->enable_mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) EXPORT_SYMBOL_GPL(regulator_disable_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int regulator_range_selector_to_index(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 					     unsigned int rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (!rdev->desc->linear_range_selectors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	rval &= rdev->desc->vsel_range_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		if (rdev->desc->linear_range_selectors[i] == rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * regulator_get_voltage_sel_pickable_regmap - pickable range get_voltage_sel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Regulators that use regmap for their register I/O and use pickable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * fields in their descriptor and then use this as their get_voltage_vsel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int regulator_get_voltage_sel_pickable_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	unsigned int r_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	int range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	unsigned int voltages = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	const struct linear_range *r = rdev->desc->linear_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_range_reg, &r_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	val &= rdev->desc->vsel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	val >>= ffs(rdev->desc->vsel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	range = regulator_range_selector_to_index(rdev, r_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (range < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	voltages = linear_range_values_in_range_array(r, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	return val + voltages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_pickable_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * regulator_set_voltage_sel_pickable_regmap - pickable range set_voltage_sel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * @sel: Selector to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * Regulators that use regmap for their register I/O and use pickable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * ranges can set the vsel_reg, vsel_mask, vsel_range_reg and vsel_range_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * fields in their descriptor and then use this as their set_voltage_vsel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int regulator_set_voltage_sel_pickable_regmap(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 					      unsigned int sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	unsigned int range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	unsigned int voltages_in_range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		const struct linear_range *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		r = &rdev->desc->linear_ranges[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		voltages_in_range = linear_range_values_in_range(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		if (sel < voltages_in_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		sel -= voltages_in_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	if (i == rdev->desc->n_linear_ranges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	sel += rdev->desc->linear_ranges[i].min_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	range = rdev->desc->linear_range_selectors[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	if (rdev->desc->vsel_reg == rdev->desc->vsel_range_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		ret = regmap_update_bits(rdev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 					 rdev->desc->vsel_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 					 rdev->desc->vsel_range_mask |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 					 rdev->desc->vsel_mask, sel | range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		ret = regmap_update_bits(rdev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 					 rdev->desc->vsel_range_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 					 rdev->desc->vsel_range_mask, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				  rdev->desc->vsel_mask, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	if (rdev->desc->apply_bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 					 rdev->desc->apply_bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 					 rdev->desc->apply_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_pickable_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * Regulators that use regmap for their register I/O can set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * vsel_reg and vsel_mask fields in their descriptor and then use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * as their get_voltage_vsel operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	val &= rdev->desc->vsel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	val >>= ffs(rdev->desc->vsel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * @sel: Selector to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  * Regulators that use regmap for their register I/O can set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  * vsel_reg and vsel_mask fields in their descriptor and then use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  * as their set_voltage_vsel operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	sel <<= ffs(rdev->desc->vsel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				  rdev->desc->vsel_mask, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (rdev->desc->apply_bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		ret = regmap_update_bits(rdev->regmap, rdev->desc->apply_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 					 rdev->desc->apply_bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					 rdev->desc->apply_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * regulator_map_voltage_iterate - map_voltage() based on list_voltage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * @rdev: Regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * @min_uV: Lower bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  * @max_uV: Upper bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  * Drivers implementing set_voltage_sel() and list_voltage() can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  * this as their map_voltage() operation.  It will find a suitable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  * voltage by calling list_voltage() until it gets something in bounds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  * for the requested voltages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int regulator_map_voltage_iterate(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 				  int min_uV, int max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	int best_val = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int selector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Find the smallest voltage that falls within the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	 * range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	for (i = 0; i < rdev->desc->n_voltages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		ret = rdev->desc->ops->list_voltage(rdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		if (ret < best_val && ret >= min_uV && ret <= max_uV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			best_val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			selector = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (best_val != INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return selector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) EXPORT_SYMBOL_GPL(regulator_map_voltage_iterate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)  * regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * @rdev: Regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  * @min_uV: Lower bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  * @max_uV: Upper bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * Drivers that have ascendant voltage list can use this as their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * map_voltage() operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int regulator_map_voltage_ascend(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				 int min_uV, int max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	for (i = 0; i < rdev->desc->n_voltages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		ret = rdev->desc->ops->list_voltage(rdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		if (ret > max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		if (ret >= min_uV && ret <= max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) EXPORT_SYMBOL_GPL(regulator_map_voltage_ascend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)  * regulator_map_voltage_linear - map_voltage() for simple linear mappings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  * @rdev: Regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * @min_uV: Lower bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  * @max_uV: Upper bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * Drivers providing min_uV and uV_step in their regulator_desc can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * use this as their map_voltage() operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int regulator_map_voltage_linear(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 				 int min_uV, int max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	int ret, voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	/* Allow uV_step to be 0 for fixed voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (rdev->desc->n_voltages == 1 && rdev->desc->uV_step == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		if (min_uV <= rdev->desc->min_uV && rdev->desc->min_uV <= max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (!rdev->desc->uV_step) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		BUG_ON(!rdev->desc->uV_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	if (min_uV < rdev->desc->min_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		min_uV = rdev->desc->min_uV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	ret += rdev->desc->linear_min_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	/* Map back into a voltage to verify we're still in bounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	voltage = rdev->desc->ops->list_voltage(rdev, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (voltage < min_uV || voltage > max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * regulator_map_voltage_linear_range - map_voltage() for multiple linear ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  * @rdev: Regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  * @min_uV: Lower bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * @max_uV: Upper bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  * Drivers providing linear_ranges in their descriptor can use this as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  * their map_voltage() callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 				       int min_uV, int max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	const struct linear_range *range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	unsigned int sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	int voltage, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	if (!rdev->desc->n_linear_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		BUG_ON(!rdev->desc->n_linear_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		range = &rdev->desc->linear_ranges[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		ret = linear_range_get_selector_high(range, min_uV, &sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 						     &found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		ret = sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		 * Map back into a voltage to verify we're still in bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		 * If we are not, then continue checking rest of the ranges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		voltage = rdev->desc->ops->list_voltage(rdev, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (voltage >= min_uV && voltage <= max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	if (i == rdev->desc->n_linear_ranges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  * regulator_map_voltage_pickable_linear_range - map_voltage, pickable ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)  * @rdev: Regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)  * @min_uV: Lower bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)  * @max_uV: Upper bound for voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  * Drivers providing pickable linear_ranges in their descriptor can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  * this as their map_voltage() callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int regulator_map_voltage_pickable_linear_range(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 						int min_uV, int max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	const struct linear_range *range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	int voltage, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	unsigned int selector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (!rdev->desc->n_linear_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		BUG_ON(!rdev->desc->n_linear_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		int linear_max_uV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		unsigned int sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		range = &rdev->desc->linear_ranges[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		linear_max_uV = linear_range_get_max_value(range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		if (!(min_uV <= linear_max_uV && max_uV >= range->min)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			selector += linear_range_values_in_range(range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		ret = linear_range_get_selector_high(range, min_uV, &sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 						     &found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			selector += linear_range_values_in_range(range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		ret = selector + sel - range->min_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		voltage = rdev->desc->ops->list_voltage(rdev, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		 * Map back into a voltage to verify we're still in bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		 * We may have overlapping voltage ranges. Hence we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		 * exit but retry until we have checked all ranges.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		if (voltage < min_uV || voltage > max_uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			selector += linear_range_values_in_range(range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (i == rdev->desc->n_linear_ranges)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) EXPORT_SYMBOL_GPL(regulator_map_voltage_pickable_linear_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  * regulator_list_voltage_linear - List voltages with simple calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)  * @rdev: Regulator device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)  * @selector: Selector to convert into a voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  * Regulators with a simple linear mapping between voltages and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)  * selectors can set min_uV and uV_step in the regulator descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)  * and then use this function as their list_voltage() operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) int regulator_list_voltage_linear(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 				  unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	if (selector >= rdev->desc->n_voltages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	if (selector < rdev->desc->linear_min_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	selector -= rdev->desc->linear_min_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)  * regulator_list_voltage_pickable_linear_range - pickable range list voltages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)  * @rdev: Regulator device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)  * @selector: Selector to convert into a voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)  * list_voltage() operation, intended to be used by drivers utilizing pickable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)  * ranges helpers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int regulator_list_voltage_pickable_linear_range(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 						 unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	const struct linear_range *range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	unsigned int all_sels = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	if (!rdev->desc->n_linear_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		BUG_ON(!rdev->desc->n_linear_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		unsigned int sel_indexes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		range = &rdev->desc->linear_ranges[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		sel_indexes = linear_range_values_in_range(range) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		if (all_sels + sel_indexes >= selector) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			selector -= all_sels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			 * As we see here, pickable ranges work only as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			 * long as the first selector for each pickable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			 * range is 0, and the each subsequent range for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			 * this 'pick' follow immediately at next unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			 * selector (Eg. there is no gaps between ranges).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			 * I think this is fine but it probably should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			 * documented. OTOH, whole pickable range stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			 * might benefit from some documentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			return range->min + (range->step * selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		all_sels += (sel_indexes + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) EXPORT_SYMBOL_GPL(regulator_list_voltage_pickable_linear_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)  * regulator_desc_list_voltage_linear_range - List voltages for linear ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)  * @desc: Regulator desc for regulator which volatges are to be listed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)  * @selector: Selector to convert into a voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)  * Regulators with a series of simple linear mappings between voltages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)  * and selectors who have set linear_ranges in the regulator descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)  * can use this function prior regulator registration to list voltages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)  * This is useful when voltages need to be listed during device-tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)  * parsing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) int regulator_desc_list_voltage_linear_range(const struct regulator_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 					     unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	BUG_ON(!desc->n_linear_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	ret = linear_range_get_value_array(desc->linear_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 					   desc->n_linear_ranges, selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 					   &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) EXPORT_SYMBOL_GPL(regulator_desc_list_voltage_linear_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)  * regulator_list_voltage_linear_range - List voltages for linear ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * @rdev: Regulator device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  * @selector: Selector to convert into a voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)  * Regulators with a series of simple linear mappings between voltages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)  * and selectors can set linear_ranges in the regulator descriptor and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)  * then use this function as their list_voltage() operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 					unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	return regulator_desc_list_voltage_linear_range(rdev->desc, selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)  * regulator_list_voltage_table - List voltages with table based mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)  * @rdev: Regulator device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)  * @selector: Selector to convert into a voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)  * Regulators with table based mapping between voltages and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)  * selectors can set volt_table in the regulator descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)  * and then use this function as their list_voltage() operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int regulator_list_voltage_table(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 				 unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (!rdev->desc->volt_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		BUG_ON(!rdev->desc->volt_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	if (selector >= rdev->desc->n_voltages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	return rdev->desc->volt_table[selector];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  * regulator_set_bypass_regmap - Default set_bypass() using regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)  * @rdev: device to operate on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)  * @enable: state to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		val = rdev->desc->bypass_val_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			val = rdev->desc->bypass_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		val = rdev->desc->bypass_val_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 				  rdev->desc->bypass_mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)  * regulator_set_soft_start_regmap - Default set_soft_start() using regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)  * @rdev: device to operate on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int regulator_set_soft_start_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	val = rdev->desc->soft_start_val_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		val = rdev->desc->soft_start_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	return regmap_update_bits(rdev->regmap, rdev->desc->soft_start_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 				  rdev->desc->soft_start_mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) EXPORT_SYMBOL_GPL(regulator_set_soft_start_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  * regulator_set_pull_down_regmap - Default set_pull_down() using regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)  * @rdev: device to operate on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int regulator_set_pull_down_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	val = rdev->desc->pull_down_val_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		val = rdev->desc->pull_down_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	return regmap_update_bits(rdev->regmap, rdev->desc->pull_down_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 				  rdev->desc->pull_down_mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) EXPORT_SYMBOL_GPL(regulator_set_pull_down_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)  * regulator_get_bypass_regmap - Default get_bypass() using regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)  * @rdev: device to operate on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)  * @enable: current state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	unsigned int val_on = rdev->desc->bypass_val_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	if (!val_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		val_on = rdev->desc->bypass_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	*enable = (val & rdev->desc->bypass_mask) == val_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)  * regulator_set_active_discharge_regmap - Default set_active_discharge()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)  *					   using regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)  * @rdev: device to operate on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)  * @enable: state to set, 0 to disable and 1 to enable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 					  bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		val = rdev->desc->active_discharge_on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		val = rdev->desc->active_discharge_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	return regmap_update_bits(rdev->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 				  rdev->desc->active_discharge_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 				  rdev->desc->active_discharge_mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)  * regulator_set_current_limit_regmap - set_current_limit for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)  * @min_uA: Lower bound for current limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)  * @max_uA: Upper bound for current limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)  * Regulators that use regmap for their register I/O can set curr_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)  * csel_reg and csel_mask fields in their descriptor and then use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)  * as their set_current_limit operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 				       int min_uA, int max_uA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	unsigned int n_currents = rdev->desc->n_current_limits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	int i, sel = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	if (n_currents == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	if (rdev->desc->curr_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		const unsigned int *curr_table = rdev->desc->curr_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 		bool ascend = curr_table[n_currents - 1] > curr_table[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		/* search for closest to maximum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		if (ascend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 			for (i = n_currents - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 				if (min_uA <= curr_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 				    curr_table[i] <= max_uA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 					sel = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 			for (i = 0; i < n_currents; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 				if (min_uA <= curr_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 				    curr_table[i] <= max_uA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 					sel = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	if (sel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	sel <<= ffs(rdev->desc->csel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 				  rdev->desc->csel_mask, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)  * regulator_get_current_limit_regmap - get_current_limit for regmap users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)  * @rdev: regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)  * Regulators that use regmap for their register I/O can set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)  * csel_reg and csel_mask fields in their descriptor and then use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)  * as their get_current_limit operation, saving some code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	val &= rdev->desc->csel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	val >>= ffs(rdev->desc->csel_mask) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	if (rdev->desc->curr_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 		if (val >= rdev->desc->n_current_limits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		return rdev->desc->curr_table[val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)  * regulator_bulk_set_supply_names - initialize the 'supply' fields in an array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)  *                                   of regulator_bulk_data structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)  * @consumers: array of regulator_bulk_data entries to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)  * @supply_names: array of supply name strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)  * @num_supplies: number of supply names to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)  * Note: the 'consumers' array must be the size of 'num_supplies'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 				     const char *const *supply_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 				     unsigned int num_supplies)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	for (i = 0; i < num_supplies; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 		consumers[i].supply = supply_names[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)  * regulator_is_equal - test whether two regulators are the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)  * @reg1: first regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)  * @reg2: second regulator to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	return reg1->rdev == reg2->rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) EXPORT_SYMBOL_GPL(regulator_is_equal);