From ee6ad5a24575071b66bd37ffb2d8747a64fcb45f Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 29 Jul 2020 13:10:23 +0800 Subject: [PATCH] regulator: mp886x: support setting switch freq Both MP8867 and MP8869 support different switch frequency. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200729131023.77cc1dd2@xhacker Signed-off-by: Mark Brown --- drivers/regulator/mp886x.c | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index 1305bf217df1..97dc44c0d663 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -22,10 +22,14 @@ #define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT) #define MP886X_GO (1 << 6) #define MP886X_EN (1 << 7) +#define MP8869_SYSCNTLREG2 0x02 struct mp886x_cfg_info { const struct regulator_ops *rops; const int slew_rates[8]; + const int switch_freq[4]; + const u8 fs_reg; + const u8 fs_shift; }; struct mp886x_device_info { @@ -60,6 +64,24 @@ static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp) MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT); } +static void mp886x_set_switch_freq(struct mp886x_device_info *di, + struct regmap *regmap, + u32 freq) +{ + const struct mp886x_cfg_info *ci = di->ci; + int i; + + for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) { + if (freq == ci->switch_freq[i]) { + regmap_update_bits(regmap, ci->fs_reg, + 0x3 << ci->fs_shift, i << ci->fs_shift); + return; + } + } + + dev_err(di->dev, "invalid frequency %d\n", freq); +} + static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode) { switch (mode) { @@ -162,6 +184,14 @@ static const struct mp886x_cfg_info mp8869_ci = { 1250, 625, }, + .switch_freq = { + 500000, + 750000, + 1000000, + 1250000, + }, + .fs_reg = MP8869_SYSCNTLREG2, + .fs_shift = 4, }; static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) @@ -233,6 +263,14 @@ static const struct mp886x_cfg_info mp8867_ci = { 1000, 500, }, + .switch_freq = { + 500000, + 750000, + 1000000, + 1500000, + }, + .fs_reg = MP886X_SYSCNTLREG1, + .fs_shift = 1, }; static int mp886x_regulator_register(struct mp886x_device_info *di, @@ -273,6 +311,7 @@ static int mp886x_i2c_probe(struct i2c_client *client) struct mp886x_device_info *di; struct regulator_config config = { }; struct regmap *regmap; + u32 freq; int ret; di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL); @@ -310,6 +349,9 @@ static int mp886x_i2c_probe(struct i2c_client *client) config.driver_data = di; config.of_node = np; + if (!of_property_read_u32(np, "mps,switch-frequency", &freq)) + mp886x_set_switch_freq(di, regmap, freq); + ret = mp886x_regulator_register(di, &config); if (ret < 0) dev_err(dev, "Failed to register regulator!\n");