summaryrefslogtreecommitdiffstats
path: root/drivers/regulator/bd71837-regulator.c
diff options
context:
space:
mode:
authorMatti Vaittinen <matti.vaittinen@fi.rohmeurope.com>2018-09-14 10:33:11 +0200
committerMark Brown <broonie@kernel.org>2018-09-28 15:57:12 +0200
commita4bfc2c28a21f4d5274d813b20fd015a9dc9bcfa (patch)
tree305d8534d10d78ba820ea0168c1302af14c30c4c /drivers/regulator/bd71837-regulator.c
parentregulator/mfd: bd718xx: rename bd71837/bd71847 common instances (diff)
downloadlinux-a4bfc2c28a21f4d5274d813b20fd015a9dc9bcfa.tar.xz
linux-a4bfc2c28a21f4d5274d813b20fd015a9dc9bcfa.zip
regulator: bd718XX use pickable ranges
Few regulators in BD71837 and BD71847 can output voltages from different voltage ranges. Register interface is arranged so that used range is selected by toggling bits which are not next to actual voltage selection bits. Then the voltage inside selected range is determined by voltage selection bits (as usual). Support BD71837 and BD71847 selectible range voltages using new pickable ranges helpers. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator/bd71837-regulator.c')
-rw-r--r--drivers/regulator/bd71837-regulator.c153
1 files changed, 125 insertions, 28 deletions
diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index 8e89334f94d1..d2522d4e1505 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -78,6 +78,34 @@ static int bd718xx_set_voltage_sel_restricted(struct regulator_dev *rdev,
return regulator_set_voltage_sel_regmap(rdev, sel);
}
+static int bd718xx_set_voltage_sel_pickable_restricted(
+ struct regulator_dev *rdev, unsigned int sel)
+{
+ if (regulator_is_enabled_regmap(rdev))
+ return -EBUSY;
+
+ return regulator_set_voltage_sel_pickable_regmap(rdev, sel);
+}
+
+static struct regulator_ops bd718xx_pickable_range_ldo_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_pickable_linear_range,
+ .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
+ .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
+};
+
+static struct regulator_ops bd718xx_pickable_range_buck_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .list_voltage = regulator_list_voltage_pickable_linear_range,
+ .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted,
+ .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+};
+
static struct regulator_ops bd718xx_ldo_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@@ -139,24 +167,61 @@ static const struct regulator_linear_range bd718xx_dvs_buck_volts[] = {
/*
* BD71837 BUCK5
+ * 0.7V to 1.35V (range 0)
+ * and
+ * 0.675 to 1.325 (range 1)
+ */
+static const struct regulator_linear_range bd71837_buck5_volts[] = {
+ /* Ranges when VOLT_SEL bit is 0 */
+ REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
+ REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
+ REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
+ /* Ranges when VOLT_SEL bit is 1 */
+ REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
+ REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
+ REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
+};
+
+/*
+ * Range selector for first 3 linear ranges is 0x0
+ * and 0x1 for last 3 ranges.
+ */
+static const unsigned int bd71837_buck5_volt_range_sel[] = {
+ 0x0, 0x0, 0x0, 0x80, 0x80, 0x80
+};
+
+/*
* BD71847 BUCK3
- * 0.7V to 1.35V ()
*/
-static const struct regulator_linear_range bd718xx_1st_nodvs_buck_volts[] = {
+static const struct regulator_linear_range bd71847_buck3_volts[] = {
+ /* Ranges when VOLT_SEL bits are 00 */
REGULATOR_LINEAR_RANGE(700000, 0x00, 0x03, 100000),
REGULATOR_LINEAR_RANGE(1050000, 0x04, 0x05, 50000),
REGULATOR_LINEAR_RANGE(1200000, 0x06, 0x07, 150000),
+ /* Ranges when VOLT_SEL bits are 01 */
+ REGULATOR_LINEAR_RANGE(550000, 0x0, 0x7, 50000),
+ /* Ranges when VOLT_SEL bits are 11 */
+ REGULATOR_LINEAR_RANGE(675000, 0x0, 0x3, 100000),
+ REGULATOR_LINEAR_RANGE(1025000, 0x4, 0x5, 50000),
+ REGULATOR_LINEAR_RANGE(1175000, 0x6, 0x7, 150000),
+};
+
+static const unsigned int bd71847_buck3_volt_range_sel[] = {
+ 0x0, 0x0, 0x0, 0x40, 0x80, 0x80, 0x80
};
-static const struct regulator_linear_range bd71847_buck4_voltage_ranges[] = {
+static const struct regulator_linear_range bd71847_buck4_volts[] = {
REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+ REGULATOR_LINEAR_RANGE(2600000, 0x00, 0x03, 100000),
};
+static const unsigned int bd71847_buck4_volt_range_sel[] = { 0x0, 0x40 };
+
/*
* BUCK6
* 3.0V to 3.3V (step 100mV)
*/
-static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
+static const struct regulator_linear_range bd71837_buck6_volts[] = {
REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
};
@@ -190,8 +255,11 @@ static const struct regulator_linear_range bd718xx_4th_nodvs_buck_volts[] = {
*/
static const struct regulator_linear_range bd718xx_ldo1_volts[] = {
REGULATOR_LINEAR_RANGE(3000000, 0x00, 0x03, 100000),
+ REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
};
+static const unsigned int bd718xx_ldo1_volt_range_sel[] = { 0x0, 0x20 };
+
/*
* LDO2
* 0.8 or 0.9V
@@ -220,11 +288,22 @@ static const struct regulator_linear_range bd718xx_ldo4_volts[] = {
* LDO5 for BD71837
* 1.8 to 3.3V (100mV step)
*/
-static const struct regulator_linear_range bd718xx_ldo5_volts[] = {
+static const struct regulator_linear_range bd71837_ldo5_volts[] = {
REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
};
/*
+ * LDO5 for BD71837
+ * 1.8 to 3.3V (100mV step)
+ */
+static const struct regulator_linear_range bd71847_ldo5_volts[] = {
+ REGULATOR_LINEAR_RANGE(1800000, 0x00, 0x0F, 100000),
+ REGULATOR_LINEAR_RANGE(800000, 0x00, 0x0F, 100000),
+};
+
+static const unsigned int bd71847_ldo5_volt_range_sel[] = { 0x0, 0x20 };
+
+/*
* LDO6
* 0.9 to 1.8V (100mV step)
*/
@@ -332,14 +411,17 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK3"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK3,
- .ops = &bd718xx_buck_regulator_ops,
+ .ops = &bd718xx_pickable_range_buck_ops,
.type = REGULATOR_VOLTAGE,
- .n_voltages = BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM,
- .linear_ranges = bd718xx_1st_nodvs_buck_volts,
+ .n_voltages = BD71847_BUCK3_VOLTAGE_NUM,
+ .linear_ranges = bd71847_buck3_volts,
.n_linear_ranges =
- ARRAY_SIZE(bd718xx_1st_nodvs_buck_volts),
+ ARRAY_SIZE(bd71847_buck3_volts),
.vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
.vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
+ .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
+ .vsel_range_mask = BD71847_BUCK3_RANGE_MASK,
+ .linear_range_selectors = bd71847_buck3_volt_range_sel,
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
.enable_mask = BD718XX_BUCK_EN,
.owner = THIS_MODULE,
@@ -356,15 +438,18 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("BUCK4"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK4,
- .ops = &bd718xx_buck_regulator_ops,
+ .ops = &bd718xx_pickable_range_buck_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71847_BUCK4_VOLTAGE_NUM,
- .linear_ranges = bd71847_buck4_voltage_ranges,
+ .linear_ranges = bd71847_buck4_volts,
.n_linear_ranges =
- ARRAY_SIZE(bd71847_buck4_voltage_ranges),
+ ARRAY_SIZE(bd71847_buck4_volts),
.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
.vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
.vsel_mask = BD71847_BUCK4_MASK,
+ .vsel_range_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
+ .vsel_range_mask = BD71847_BUCK4_RANGE_MASK,
+ .linear_range_selectors = bd71847_buck4_volt_range_sel,
.enable_mask = BD718XX_BUCK_EN,
.owner = THIS_MODULE,
},
@@ -426,13 +511,16 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO1,
- .ops = &bd718xx_ldo_regulator_ops,
+ .ops = &bd718xx_pickable_range_ldo_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo1_volts,
.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
.vsel_reg = BD718XX_REG_LDO1_VOLT,
.vsel_mask = BD718XX_LDO1_MASK,
+ .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
+ .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
+ .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
.enable_reg = BD718XX_REG_LDO1_VOLT,
.enable_mask = BD718XX_LDO_EN,
.owner = THIS_MODULE,
@@ -517,13 +605,16 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
.of_match = of_match_ptr("LDO5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO5,
- .ops = &bd718xx_ldo_regulator_ops,
+ .ops = &bd718xx_pickable_range_ldo_ops,
.type = REGULATOR_VOLTAGE,
- .n_voltages = BD718XX_LDO5_VOLTAGE_NUM,
- .linear_ranges = bd718xx_ldo5_volts,
- .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo5_volts),
+ .n_voltages = BD71847_LDO5_VOLTAGE_NUM,
+ .linear_ranges = bd71847_ldo5_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd71847_ldo5_volts),
.vsel_reg = BD718XX_REG_LDO5_VOLT,
.vsel_mask = BD71847_LDO5_MASK,
+ .vsel_range_reg = BD718XX_REG_LDO5_VOLT,
+ .vsel_range_mask = BD71847_LDO5_RANGE_MASK,
+ .linear_range_selectors = bd71847_ldo5_volt_range_sel,
.enable_reg = BD718XX_REG_LDO5_VOLT,
.enable_mask = BD718XX_LDO_EN,
.owner = THIS_MODULE,
@@ -660,14 +751,17 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("BUCK5"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_BUCK5,
- .ops = &bd718xx_buck_regulator_ops,
+ .ops = &bd718xx_pickable_range_buck_ops,
.type = REGULATOR_VOLTAGE,
- .n_voltages = BD718XX_1ST_NODVS_BUCK_VOLTAGE_NUM,
- .linear_ranges = bd718xx_1st_nodvs_buck_volts,
+ .n_voltages = BD71837_BUCK5_VOLTAGE_NUM,
+ .linear_ranges = bd71837_buck5_volts,
.n_linear_ranges =
- ARRAY_SIZE(bd718xx_1st_nodvs_buck_volts),
+ ARRAY_SIZE(bd71837_buck5_volts),
.vsel_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
- .vsel_mask = BD718XX_1ST_NODVS_BUCK_MASK,
+ .vsel_mask = BD71837_BUCK5_MASK,
+ .vsel_range_reg = BD718XX_REG_1ST_NODVS_BUCK_VOLT,
+ .vsel_range_mask = BD71837_BUCK5_RANGE_MASK,
+ .linear_range_selectors = bd71837_buck5_volt_range_sel,
.enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL,
.enable_mask = BD718XX_BUCK_EN,
.owner = THIS_MODULE,
@@ -687,9 +781,9 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.ops = &bd718xx_buck_regulator_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD71837_BUCK6_VOLTAGE_NUM,
- .linear_ranges = bd71837_buck6_voltage_ranges,
+ .linear_ranges = bd71837_buck6_volts,
.n_linear_ranges =
- ARRAY_SIZE(bd71837_buck6_voltage_ranges),
+ ARRAY_SIZE(bd71837_buck6_volts),
.vsel_reg = BD718XX_REG_2ND_NODVS_BUCK_VOLT,
.vsel_mask = BD71837_BUCK6_MASK,
.enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL,
@@ -754,13 +848,16 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.of_match = of_match_ptr("LDO1"),
.regulators_node = of_match_ptr("regulators"),
.id = BD718XX_LDO1,
- .ops = &bd718xx_ldo_regulator_ops,
+ .ops = &bd718xx_pickable_range_ldo_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = BD718XX_LDO1_VOLTAGE_NUM,
.linear_ranges = bd718xx_ldo1_volts,
.n_linear_ranges = ARRAY_SIZE(bd718xx_ldo1_volts),
.vsel_reg = BD718XX_REG_LDO1_VOLT,
.vsel_mask = BD718XX_LDO1_MASK,
+ .vsel_range_reg = BD718XX_REG_LDO1_VOLT,
+ .vsel_range_mask = BD718XX_LDO1_RANGE_MASK,
+ .linear_range_selectors = bd718xx_ldo1_volt_range_sel,
.enable_reg = BD718XX_REG_LDO1_VOLT,
.enable_mask = BD718XX_LDO_EN,
.owner = THIS_MODULE,
@@ -847,9 +944,9 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
.id = BD718XX_LDO5,
.ops = &bd718xx_ldo_regulator_ops,
.type = REGULATOR_VOLTAGE,
- .n_voltages = BD718XX_LDO5_VOLTAGE_NUM,
- .linear_ranges = bd718xx_ldo5_volts,
- .n_linear_ranges = ARRAY_SIZE(bd718xx_ldo5_volts),
+ .n_voltages = BD71837_LDO5_VOLTAGE_NUM,
+ .linear_ranges = bd71837_ldo5_volts,
+ .n_linear_ranges = ARRAY_SIZE(bd71837_ldo5_volts),
/* LDO5 is supplied by buck6 */
.supply_name = "buck6",
.vsel_reg = BD718XX_REG_LDO5_VOLT,