Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: helpers: Modify helpers enabling multi-bit control

This patch extends the regulator helpers to account for device that use
multiple bits for control when using regmap enable/disable/bypass ops.

The actual regulator helpers wrongly assume that the regulator control
is always performed using single bits, using in the regulator_desc
struct only two parameters *_reg and *_mask defining register and mask
for control.

This patch extends this struct and introduces the helpers to take into
account devices where control is performed using multiple bits and
specific multi-bit values are used for enabling/disabling/bypassing the
regulator.

Signed-off-by: Carlo Caione <carlo@caione.org>
Signed-off-by: Mark Brown <broonie@linaro.org>

authored by

Carlo Caione and committed by
Mark Brown
ca5d1b35 38dbfb59

+40 -16
+32 -16
drivers/regulator/helpers.c
··· 37 37 if (ret != 0) 38 38 return ret; 39 39 40 - if (rdev->desc->enable_is_inverted) 41 - return (val & rdev->desc->enable_mask) == 0; 42 - else 43 - return (val & rdev->desc->enable_mask) != 0; 40 + val &= rdev->desc->enable_mask; 41 + 42 + if (rdev->desc->enable_is_inverted) { 43 + if (rdev->desc->enable_val) 44 + return val != rdev->desc->enable_val; 45 + return val == 0; 46 + } else { 47 + if (rdev->desc->enable_val) 48 + return val == rdev->desc->enable_val; 49 + return val != 0; 50 + } 44 51 } 45 52 EXPORT_SYMBOL_GPL(regulator_is_enabled_regmap); 46 53 ··· 64 57 { 65 58 unsigned int val; 66 59 67 - if (rdev->desc->enable_is_inverted) 68 - val = 0; 69 - else 70 - val = rdev->desc->enable_mask; 60 + if (rdev->desc->enable_is_inverted) { 61 + val = rdev->desc->disable_val; 62 + } else { 63 + val = rdev->desc->enable_val; 64 + if (!val) 65 + val = rdev->desc->enable_mask; 66 + } 71 67 72 68 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 73 69 rdev->desc->enable_mask, val); ··· 90 80 { 91 81 unsigned int val; 92 82 93 - if (rdev->desc->enable_is_inverted) 94 - val = rdev->desc->enable_mask; 95 - else 96 - val = 0; 83 + if (rdev->desc->enable_is_inverted) { 84 + val = rdev->desc->enable_val; 85 + if (!val) 86 + val = rdev->desc->enable_mask; 87 + } else { 88 + val = rdev->desc->disable_val; 89 + } 97 90 98 91 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, 99 92 rdev->desc->enable_mask, val); ··· 432 419 { 433 420 unsigned int val; 434 421 435 - if (enable) 436 - val = rdev->desc->bypass_mask; 437 - else 438 - val = 0; 422 + if (enable) { 423 + val = rdev->desc->bypass_val_on; 424 + if (!val) 425 + val = rdev->desc->bypass_mask; 426 + } else { 427 + val = rdev->desc->bypass_val_off; 428 + } 439 429 440 430 return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg, 441 431 rdev->desc->bypass_mask, val);
+8
include/linux/regulator/driver.h
··· 228 228 * output when using regulator_set_voltage_sel_regmap 229 229 * @enable_reg: Register for control when using regmap enable/disable ops 230 230 * @enable_mask: Mask for control when using regmap enable/disable ops 231 + * @enable_val: Enabling value for control when using regmap enable/disable ops 232 + * @disable_val: Disabling value for control when using regmap enable/disable ops 231 233 * @enable_is_inverted: A flag to indicate set enable_mask bits to disable 232 234 * when using regulator_enable_regmap and friends APIs. 233 235 * @bypass_reg: Register for control when using regmap set_bypass 234 236 * @bypass_mask: Mask for control when using regmap set_bypass 237 + * @bypass_val_on: Enabling value for control when using regmap set_bypass 238 + * @bypass_val_off: Disabling value for control when using regmap set_bypass 235 239 * 236 240 * @enable_time: Time taken for initial enable of regulator (in uS). 237 241 */ ··· 267 263 unsigned int apply_bit; 268 264 unsigned int enable_reg; 269 265 unsigned int enable_mask; 266 + unsigned int enable_val; 267 + unsigned int disable_val; 270 268 bool enable_is_inverted; 271 269 unsigned int bypass_reg; 272 270 unsigned int bypass_mask; 271 + unsigned int bypass_val_on; 272 + unsigned int bypass_val_off; 273 273 274 274 unsigned int enable_time; 275 275 };