1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

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: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Axel Lin 2019-03-25 21:55:57 +08:00 committed by Mark Brown
parent 68ce3a4461
commit 3df4235ac4
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0

View file

@ -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 @@
#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 {
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)
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,
* 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,7 +153,12 @@ 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)
rv = regulator_set_voltage_sel_pickable_regmap(rdev,
curr);
else
rv = regulator_set_voltage_sel_regmap(rdev, curr);
if (rv) if (rv)
return rv; return rv;
@ -173,50 +169,6 @@ static int max77650_regulator_set_voltage_sel(struct regulator_dev *rdev,
return 0; 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
MAX77650_REGULATOR_SBB1_SEL_INCR(curr);
rv = regulator_set_voltage_sel_regmap(rdev, curr);
if (rv)
return rv;
if (curr == sel)
break;
};
return 0;
}
static const struct regulator_ops max77650_regulator_LDO_ops = { static const struct regulator_ops max77650_regulator_LDO_ops = {
.is_enabled = max77650_regulator_is_enabled, .is_enabled = max77650_regulator_is_enabled,
.enable = max77650_regulator_enable, .enable = max77650_regulator_enable,
@ -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 = {
.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,