Commit 3df4235a authored by Axel Lin's avatar Axel Lin Committed by Mark Brown

regulator: max77650: Convert MAX77651 SBB1 to pickable linear range

The pickable linear range is suitable for The MAX77651 SBB1.
According to MAX77651 TV_SBB1 Code Table:
Use BIT[1:0] as range selectors.
Use BIT[5:2] as selectors for each linear range.

The MAX77651 SBB1 supports up to selector 57, selector 58 ~ 63 are RSVD,
thus set n_voltage to 58.
Signed-off-by: default avatarAxel Lin <axel.lin@ingics.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 68ce3a44
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0) #define MAX77650_REGULATOR_V_LDO_MASK GENMASK(6, 0)
#define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0) #define MAX77650_REGULATOR_V_SBB_MASK GENMASK(5, 0)
#define MAX77651_REGULATOR_V_SBB1_MASK GENMASK(5, 2)
#define MAX77651_REGULATOR_V_SBB1_RANGE_MASK GENMASK(1, 0)
#define MAX77650_REGULATOR_AD_MASK BIT(3) #define MAX77650_REGULATOR_AD_MASK BIT(3)
#define MAX77650_REGULATOR_AD_DISABLED 0x00 #define MAX77650_REGULATOR_AD_DISABLED 0x00
...@@ -27,6 +29,8 @@ ...@@ -27,6 +29,8 @@
#define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6) #define MAX77650_REGULATOR_CURR_LIM_MASK GENMASK(7, 6)
static struct max77650_regulator_desc max77651_SBB1_desc;
enum { enum {
MAX77650_REGULATOR_ID_LDO = 0, MAX77650_REGULATOR_ID_LDO = 0,
MAX77650_REGULATOR_ID_SBB0, MAX77650_REGULATOR_ID_SBB0,
...@@ -41,43 +45,20 @@ struct max77650_regulator_desc { ...@@ -41,43 +45,20 @@ struct max77650_regulator_desc {
unsigned int regB; unsigned int regB;
}; };
static const unsigned int max77651_sbb1_regulator_volt_table[] = { static const unsigned int max77651_sbb1_volt_range_sel[] = {
2400000, 3200000, 4000000, 4800000, 0x0, 0x1, 0x2, 0x3
2450000, 3250000, 4050000, 4850000,
2500000, 3300000, 4100000, 4900000,
2550000, 3350000, 4150000, 4950000,
2600000, 3400000, 4200000, 5000000,
2650000, 3450000, 4250000, 5050000,
2700000, 3500000, 4300000, 5100000,
2750000, 3550000, 4350000, 5150000,
2800000, 3600000, 4400000, 5200000,
2850000, 3650000, 4450000, 5250000,
2900000, 3700000, 4500000, 0,
2950000, 3750000, 4550000, 0,
3000000, 3800000, 4600000, 0,
3050000, 3850000, 4650000, 0,
3100000, 3900000, 4700000, 0,
3150000, 3950000, 4750000, 0,
}; };
#define MAX77651_REGULATOR_SBB1_SEL_DEC(_val) \ static const struct regulator_linear_range max77651_sbb1_volt_ranges[] = {
(((_val & 0x3c) >> 2) | ((_val & 0x03) << 4)) /* range index 0 */
#define MAX77651_REGULATOR_SBB1_SEL_ENC(_val) \ REGULATOR_LINEAR_RANGE(2400000, 0x00, 0x0f, 50000),
(((_val & 0x30) >> 4) | ((_val & 0x0f) << 2)) /* range index 1 */
REGULATOR_LINEAR_RANGE(3200000, 0x00, 0x0f, 50000),
#define MAX77650_REGULATOR_SBB1_SEL_DECR(_val) \ /* range index 2 */
do { \ REGULATOR_LINEAR_RANGE(4000000, 0x00, 0x0f, 50000),
_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \ /* range index 3 */
_val--; \ REGULATOR_LINEAR_RANGE(4800000, 0x00, 0x09, 50000),
_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \ };
} while (0)
#define MAX77650_REGULATOR_SBB1_SEL_INCR(_val) \
do { \
_val = MAX77651_REGULATOR_SBB1_SEL_DEC(_val); \
_val++; \
_val = MAX77651_REGULATOR_SBB1_SEL_ENC(_val); \
} while (0)
static const unsigned int max77650_current_limit_table[] = { static const unsigned int max77650_current_limit_table[] = {
1000000, 866000, 707000, 500000, 1000000, 866000, 707000, 500000,
...@@ -130,6 +111,7 @@ static int max77650_regulator_disable(struct regulator_dev *rdev) ...@@ -130,6 +111,7 @@ static int max77650_regulator_disable(struct regulator_dev *rdev)
static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel) unsigned int sel)
{ {
struct max77650_regulator_desc *rdesc = rdev_get_drvdata(rdev);
int rv = 0, curr, diff; int rv = 0, curr, diff;
bool ascending; bool ascending;
...@@ -137,15 +119,24 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, ...@@ -137,15 +119,24 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
* If the regulator is disabled, we can program the desired * If the regulator is disabled, we can program the desired
* voltage right away. * voltage right away.
*/ */
if (!max77650_regulator_is_enabled(rdev)) if (!max77650_regulator_is_enabled(rdev)) {
return regulator_set_voltage_sel_regmap(rdev, sel); if (rdesc == &max77651_SBB1_desc)
return regulator_set_voltage_sel_pickable_regmap(rdev,
sel);
else
return regulator_set_voltage_sel_regmap(rdev, sel);
}
/* /*
* Otherwise we need to manually ramp the output voltage up/down * Otherwise we need to manually ramp the output voltage up/down
* one step at a time. * one step at a time.
*/ */
curr = regulator_get_voltage_sel_regmap(rdev); if (rdesc == &max77651_SBB1_desc)
curr = regulator_get_voltage_sel_pickable_regmap(rdev);
else
curr = regulator_get_voltage_sel_regmap(rdev);
if (curr < 0) if (curr < 0)
return curr; return curr;
...@@ -162,57 +153,18 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev, ...@@ -162,57 +153,18 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
* the selector equals 0. * the selector equals 0.
*/ */
for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) { for (ascending ? curr++ : curr--;; ascending ? curr++ : curr--) {
rv = regulator_set_voltage_sel_regmap(rdev, curr); if (rdesc == &max77651_SBB1_desc)
if (rv) rv = regulator_set_voltage_sel_pickable_regmap(rdev,
return rv; curr);
if (curr == sel)
break;
}
return 0;
}
/*
* Special case: non-linear voltage table for max77651 SBB1 - software
* must ensure the voltage is ramped in 50mV increments.
*/
static int max77651_regulator_sbb1_set_voltage_sel(struct regulator_dev *rdev,
unsigned int sel)
{
int rv = 0, curr, vcurr, vdest, vdiff;
/*
* If the regulator is disabled, we can program the desired
* voltage right away.
*/
if (!max77650_regulator_is_enabled(rdev))
return regulator_set_voltage_sel_regmap(rdev, sel);
curr = regulator_get_voltage_sel_regmap(rdev);
if (curr < 0)
return curr;
if (curr == sel)
return 0; /* Already there. */
vcurr = max77651_sbb1_regulator_volt_table[curr];
vdest = max77651_sbb1_regulator_volt_table[sel];
vdiff = vcurr - vdest;
for (;;) {
if (vdiff > 0)
MAX77650_REGULATOR_SBB1_SEL_DECR(curr);
else else
MAX77650_REGULATOR_SBB1_SEL_INCR(curr); rv = regulator_set_voltage_sel_regmap(rdev, curr);
rv = regulator_set_voltage_sel_regmap(rdev, curr);
if (rv) if (rv)
return rv; return rv;
if (curr == sel) if (curr == sel)
break; break;
}; }
return 0; return 0;
} }
...@@ -241,14 +193,14 @@ static const struct regulator_ops max77650_regulator_SBB_ops = { ...@@ -241,14 +193,14 @@ static const struct regulator_ops max77650_regulator_SBB_ops = {
.set_active_discharge = regulator_set_active_discharge_regmap, .set_active_discharge = regulator_set_active_discharge_regmap,
}; };
/* Special case for max77651 SBB1 - non-linear voltage mapping. */ /* Special case for max77651 SBB1 - pickable linear-range voltage mapping. */
static const struct regulator_ops max77651_SBB1_regulator_ops = { static const struct regulator_ops max77651_SBB1_regulator_ops = {
.is_enabled = max77650_regulator_is_enabled, .is_enabled = max77650_regulator_is_enabled,
.enable = max77650_regulator_enable, .enable = max77650_regulator_enable,
.disable = max77650_regulator_disable, .disable = max77650_regulator_disable,
.list_voltage = regulator_list_voltage_table, .list_voltage = regulator_list_voltage_pickable_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap,
.set_voltage_sel = max77651_regulator_sbb1_set_voltage_sel, .set_voltage_sel = max77650_regulator_set_voltage_sel,
.get_current_limit = regulator_get_current_limit_regmap, .get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap, .set_current_limit = regulator_set_current_limit_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap, .set_active_discharge = regulator_set_active_discharge_regmap,
...@@ -345,9 +297,13 @@ static struct max77650_regulator_desc max77651_SBB1_desc = { ...@@ -345,9 +297,13 @@ static struct max77650_regulator_desc max77651_SBB1_desc = {
.supply_name = "in-sbb1", .supply_name = "in-sbb1",
.id = MAX77650_REGULATOR_ID_SBB1, .id = MAX77650_REGULATOR_ID_SBB1,
.ops = &max77651_SBB1_regulator_ops, .ops = &max77651_SBB1_regulator_ops,
.volt_table = max77651_sbb1_regulator_volt_table, .linear_range_selectors = max77651_sbb1_volt_range_sel,
.n_voltages = ARRAY_SIZE(max77651_sbb1_regulator_volt_table), .linear_ranges = max77651_sbb1_volt_ranges,
.vsel_mask = MAX77650_REGULATOR_V_SBB_MASK, .n_linear_ranges = ARRAY_SIZE(max77651_sbb1_volt_ranges),
.n_voltages = 58,
.vsel_range_mask = MAX77651_REGULATOR_V_SBB1_RANGE_MASK,
.vsel_range_reg = MAX77650_REG_CNFG_SBB1_A,
.vsel_mask = MAX77651_REGULATOR_V_SBB1_MASK,
.vsel_reg = MAX77650_REG_CNFG_SBB1_A, .vsel_reg = MAX77650_REG_CNFG_SBB1_A,
.active_discharge_off = MAX77650_REGULATOR_AD_DISABLED, .active_discharge_off = MAX77650_REGULATOR_AD_DISABLED,
.active_discharge_on = MAX77650_REGULATOR_AD_ENABLED, .active_discharge_on = MAX77650_REGULATOR_AD_ENABLED,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment