diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 11:44:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-03 11:44:48 -0700 |
commit | 312c76f1a3989b8d0c0c13fee765bb2c41f2d114 (patch) | |
tree | c3aeb04e87ad51cbf060a475c123b80d679cd33a /drivers/regulator/palmas-regulator.c | |
parent | e13cccfd86481bd4c0499577f44c570d334da79b (diff) | |
parent | 978371cbabb4cb7a47751049d72f06dc8348cab2 (diff) |
Merge tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into next
Pull regulator updates from Mark Brown:
"The bulk of the changes for this release are a few new drivers however
there are a couple of noticable core changes and the usual stream of
cleanups and fixes:
- move disable of unused regulators later in init so it comes after
deferred probe has iterated making startup smoother.
- fixes to reference counting of the DT nodes for constraints from
Charles Keepax. This has little practical impact since all real
users of the regulator bindings use FDT which doesn't need the
reference counting.
- lots of cleanups, especially to the Samsung drivers.
- support for Linear Technologies LTC3589, Texas Instruments
TPS658640 and X-Powers AXP20x"
* tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (64 commits)
regulator: pbias: remove unnecessary OOM messages
regulator: max8649: remove unnecessary OOM messages
regulator: core: Fix the init of DT defined fixed regulators
regulator: core: Disable unused regulators after deferred probing is done
regulator: Don't disable unused regulators we don't have permission for
regulator: axp20x: Use regulator_map_voltage_ascend for LDO4
regulator: use of_property_read_{bool|u32}()
regulator: Fix regulator_get_{optional,exclusive}() documentation
regulators: Add definition of regulator_set_voltage_time() for !CONFIG_REGULATOR
regulator: arizona-ldo1: add missing #include
regulator: pfuze100: Support enable/disable for fixed regulator
regulator: ltc3589: Remove ltc3589_list_voltage_fixed function
regulator: ltc3589: Fix module dependency
regulator: tps6586x: Remove unused to_tps6586x_dev() function
regulator: tps65218: Convert to use regulator_set_voltage_time_sel
regulator: tps6586x: Add support for the TPS658640
regulator: tps6586x: Prepare supporting fixed regulators
regulator: pfuze100: Don't allocate an invalid gpio
regulator: pfuze100: Support SWB enable/disable
regulator: fixed: use of_property_read_{bool|u32}()
...
Diffstat (limited to 'drivers/regulator/palmas-regulator.c')
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 160 |
1 files changed, 27 insertions, 133 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 9c62b1d34685..864ed02ce4b7 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -36,6 +36,18 @@ struct regs_info { int sleep_id; }; +static const struct regulator_linear_range smps_low_ranges[] = { + REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0), + REGULATOR_LINEAR_RANGE(510000, 0x7, 0x79, 10000), + REGULATOR_LINEAR_RANGE(1650000, 0x7A, 0x7f, 0), +}; + +static const struct regulator_linear_range smps_high_ranges[] = { + REGULATOR_LINEAR_RANGE(1000000, 0x1, 0x6, 0), + REGULATOR_LINEAR_RANGE(1020000, 0x7, 0x79, 20000), + REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0), +}; + static const struct regs_info palmas_regs_info[] = { { .name = "SMPS12", @@ -280,54 +292,6 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); } -static int palmas_is_enabled_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= PALMAS_SMPS12_CTRL_STATUS_MASK; - reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT; - - return !!(reg); -} - -static int palmas_enable_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; - if (pmic->current_reg_mode[id]) - reg |= pmic->current_reg_mode[id]; - else - reg |= SMPS_CTRL_MODE_ON; - - palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); - - return 0; -} - -static int palmas_disable_smps(struct regulator_dev *dev) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - unsigned int reg; - - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); - - reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; - - palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); - - return 0; -} - static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) { struct palmas_pmic *pmic = rdev_get_drvdata(dev); @@ -382,81 +346,6 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev) return 0; } -static int palmas_list_voltage_smps(struct regulator_dev *dev, - unsigned selector) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(dev); - int id = rdev_get_id(dev); - int mult = 1; - - /* Read the multiplier set in VSEL register to return - * the correct voltage. - */ - if (pmic->range[id]) - mult = 2; - - if (selector == 0) - return 0; - else if (selector < 6) - return 500000 * mult; - else - /* Voltage is linear mapping starting from selector 6, - * volt = (0.49V + ((selector - 5) * 0.01V)) * RANGE - * RANGE is either x1 or x2 - */ - return (490000 + ((selector - 5) * 10000)) * mult; -} - -static int palmas_map_voltage_smps(struct regulator_dev *rdev, - int min_uV, int max_uV) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); - int ret, voltage; - - if (min_uV == 0) - return 0; - - if (pmic->range[id]) { /* RANGE is x2 */ - if (min_uV < 1000000) - min_uV = 1000000; - ret = DIV_ROUND_UP(min_uV - 1000000, 20000) + 6; - } else { /* RANGE is x1 */ - if (min_uV < 500000) - min_uV = 500000; - ret = DIV_ROUND_UP(min_uV - 500000, 10000) + 6; - } - - /* Map back into a voltage to verify we're still in bounds */ - voltage = palmas_list_voltage_smps(rdev, ret); - if (voltage < min_uV || voltage > max_uV) - return -EINVAL; - - return ret; -} - -static int palma_smps_set_voltage_smps_time_sel(struct regulator_dev *rdev, - unsigned int old_selector, unsigned int new_selector) -{ - struct palmas_pmic *pmic = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); - int old_uv, new_uv; - unsigned int ramp_delay = pmic->ramp_delay[id]; - - if (!ramp_delay) - return 0; - - old_uv = palmas_list_voltage_smps(rdev, old_selector); - if (old_uv < 0) - return old_uv; - - new_uv = palmas_list_voltage_smps(rdev, new_selector); - if (new_uv < 0) - return new_uv; - - return DIV_ROUND_UP(abs(old_uv - new_uv), ramp_delay); -} - static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { @@ -493,16 +382,16 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, } static struct regulator_ops palmas_ops_smps = { - .is_enabled = palmas_is_enabled_smps, - .enable = palmas_enable_smps, - .disable = palmas_disable_smps, + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, .set_mode = palmas_set_mode_smps, .get_mode = palmas_get_mode_smps, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = palmas_list_voltage_smps, - .map_voltage = palmas_map_voltage_smps, - .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_ramp_delay = palmas_smps_set_ramp_delay, }; @@ -511,9 +400,9 @@ static struct regulator_ops palmas_ops_ext_control_smps = { .get_mode = palmas_get_mode_smps, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .list_voltage = palmas_list_voltage_smps, - .map_voltage = palmas_map_voltage_smps, - .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_ramp_delay = palmas_smps_set_ramp_delay, }; @@ -1042,12 +931,17 @@ static int palmas_regulators_probe(struct platform_device *pdev) * ranges. Read the current smps mode for later use. */ addr = palmas_regs_info[id].vsel_addr; + pmic->desc[id].n_linear_ranges = 3; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) pmic->range[id] = 1; + if (pmic->range[id]) + pmic->desc[id].linear_ranges = smps_high_ranges; + else + pmic->desc[id].linear_ranges = smps_low_ranges; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = @@ -1199,7 +1093,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) return 0; } -static struct of_device_id of_palmas_match_tbl[] = { +static const struct of_device_id of_palmas_match_tbl[] = { { .compatible = "ti,palmas-pmic", }, { .compatible = "ti,twl6035-pmic", }, { .compatible = "ti,twl6036-pmic", }, |