Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: rk808: fixed the overshoot when adjust voltage

There is a overshoot in DCDC1/DCDC2, we have 2 method to workaround:
1st is use dvs pin to switch the voltage between value in BUCKn_ON_VSEL
and BUCKn_DVS_VSEL. If DVS pin is inactive, the voltage of DCDC1/DCDC2
are controlled by BUCKn_ON_VSEL, when we pull dvs1/dvs2 pin to active,
they would be controlled by BUCKn_DVS_VSEL. In this case, the ramp rate
is same as the value programmed in BUCKn_RATE, and the fastest rate is
10mv/us.
2nd method is gradual adjustment, adjust the voltage to a target value
step by step via i2c, each step is set to 100 mA. If you write the
voltage directly using an i2c write the rk808 will always ramp as fast
as it possibly can, about 100mv/us.

Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Chris Zhong and committed by
Mark Brown
bad47ad2 0ec5f8bd

+207 -12
+207 -12
drivers/regulator/rk808-regulator.c
··· 16 16 * more details. 17 17 */ 18 18 19 - #include <linux/module.h> 19 + #include <linux/delay.h> 20 + #include <linux/gpio.h> 20 21 #include <linux/i2c.h> 21 - #include <linux/mfd/rk808.h> 22 + #include <linux/module.h> 22 23 #include <linux/of_device.h> 24 + #include <linux/of_gpio.h> 25 + #include <linux/mfd/rk808.h> 23 26 #include <linux/regulator/driver.h> 24 27 #include <linux/regulator/of_regulator.h> 25 28 ··· 39 36 #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) 40 37 #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) 41 38 39 + #define RK808_DVS2_POL BIT(2) 40 + #define RK808_DVS1_POL BIT(1) 41 + 42 42 /* Offset from XXX_ON_VSEL to XXX_SLP_VSEL */ 43 43 #define RK808_SLP_REG_OFFSET 1 44 44 45 + /* Offset from XXX_ON_VSEL to XXX_DVS_VSEL */ 46 + #define RK808_DVS_REG_OFFSET 2 47 + 45 48 /* Offset from XXX_EN_REG to SLEEP_SET_OFF_XXX */ 46 49 #define RK808_SLP_SET_OFF_REG_OFFSET 2 50 + 51 + /* max steps for increase voltage of Buck1/2, equal 100mv*/ 52 + #define MAX_STEPS_ONE_TIME 8 53 + 54 + struct rk808_regulator_data { 55 + struct gpio_desc *dvs_gpio[2]; 56 + }; 47 57 48 58 static const int rk808_buck_config_regs[] = { 49 59 RK808_BUCK1_CONFIG_REG, ··· 85 69 static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = { 86 70 REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000), 87 71 }; 72 + 73 + static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev) 74 + { 75 + struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev); 76 + int id = rdev->desc->id - RK808_ID_DCDC1; 77 + struct gpio_desc *gpio = pdata->dvs_gpio[id]; 78 + unsigned int val; 79 + int ret; 80 + 81 + if (IS_ERR(gpio) || gpiod_get_value(gpio) == 0) 82 + return regulator_get_voltage_sel_regmap(rdev); 83 + 84 + ret = regmap_read(rdev->regmap, 85 + rdev->desc->vsel_reg + RK808_DVS_REG_OFFSET, 86 + &val); 87 + if (ret != 0) 88 + return ret; 89 + 90 + val &= rdev->desc->vsel_mask; 91 + val >>= ffs(rdev->desc->vsel_mask) - 1; 92 + 93 + return val; 94 + } 95 + 96 + static int rk808_buck1_2_i2c_set_voltage_sel(struct regulator_dev *rdev, 97 + unsigned sel) 98 + { 99 + int ret, delta_sel; 100 + unsigned int old_sel, tmp, val, mask = rdev->desc->vsel_mask; 101 + 102 + ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); 103 + if (ret != 0) 104 + return ret; 105 + 106 + tmp = val & ~mask; 107 + old_sel = val & mask; 108 + old_sel >>= ffs(mask) - 1; 109 + delta_sel = sel - old_sel; 110 + 111 + /* 112 + * If directly modify the register to change the voltage, we will face 113 + * the risk of overshoot. Put it into a multi-step, can effectively 114 + * avoid this problem, a step is 100mv here. 115 + */ 116 + while (delta_sel > MAX_STEPS_ONE_TIME) { 117 + old_sel += MAX_STEPS_ONE_TIME; 118 + val = old_sel << (ffs(mask) - 1); 119 + val |= tmp; 120 + 121 + /* 122 + * i2c is 400kHz (2.5us per bit) and we must transmit _at least_ 123 + * 3 bytes (24 bits) plus start and stop so 26 bits. So we've 124 + * got more than 65 us between each voltage change and thus 125 + * won't ramp faster than ~1500 uV / us. 126 + */ 127 + ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, val); 128 + delta_sel = sel - old_sel; 129 + } 130 + 131 + sel <<= ffs(mask) - 1; 132 + val = tmp | sel; 133 + ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, val); 134 + 135 + /* 136 + * When we change the voltage register directly, the ramp rate is about 137 + * 100000uv/us, wait 1us to make sure the target voltage to be stable, 138 + * so we needn't wait extra time after that. 139 + */ 140 + udelay(1); 141 + 142 + return ret; 143 + } 144 + 145 + static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev, 146 + unsigned sel) 147 + { 148 + struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev); 149 + int id = rdev->desc->id - RK808_ID_DCDC1; 150 + struct gpio_desc *gpio = pdata->dvs_gpio[id]; 151 + unsigned int reg = rdev->desc->vsel_reg; 152 + unsigned old_sel; 153 + int ret, gpio_level; 154 + 155 + if (IS_ERR(gpio)) 156 + return rk808_buck1_2_i2c_set_voltage_sel(rdev, sel); 157 + 158 + gpio_level = gpiod_get_value(gpio); 159 + if (gpio_level == 0) { 160 + reg += RK808_DVS_REG_OFFSET; 161 + ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &old_sel); 162 + } else { 163 + ret = regmap_read(rdev->regmap, 164 + reg + RK808_DVS_REG_OFFSET, 165 + &old_sel); 166 + } 167 + 168 + if (ret != 0) 169 + return ret; 170 + 171 + sel <<= ffs(rdev->desc->vsel_mask) - 1; 172 + sel |= old_sel & ~rdev->desc->vsel_mask; 173 + 174 + ret = regmap_write(rdev->regmap, reg, sel); 175 + if (ret) 176 + return ret; 177 + 178 + gpiod_set_value(gpio, !gpio_level); 179 + 180 + return ret; 181 + } 182 + 183 + static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev, 184 + unsigned int old_selector, 185 + unsigned int new_selector) 186 + { 187 + struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev); 188 + int id = rdev->desc->id - RK808_ID_DCDC1; 189 + struct gpio_desc *gpio = pdata->dvs_gpio[id]; 190 + 191 + /* if there is no dvs1/2 pin, we don't need wait extra time here. */ 192 + if (IS_ERR(gpio)) 193 + return 0; 194 + 195 + return regulator_set_voltage_time_sel(rdev, old_selector, new_selector); 196 + } 88 197 89 198 static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) 90 199 { ··· 278 137 static struct regulator_ops rk808_buck1_2_ops = { 279 138 .list_voltage = regulator_list_voltage_linear_range, 280 139 .map_voltage = regulator_map_voltage_linear_range, 281 - .get_voltage_sel = regulator_get_voltage_sel_regmap, 282 - .set_voltage_sel = regulator_set_voltage_sel_regmap, 140 + .get_voltage_sel = rk808_buck1_2_get_voltage_sel_regmap, 141 + .set_voltage_sel = rk808_buck1_2_set_voltage_sel, 142 + .set_voltage_time_sel = rk808_buck1_2_set_voltage_time_sel, 283 143 .enable = regulator_enable_regmap, 284 144 .disable = regulator_disable_regmap, 285 145 .is_enabled = regulator_is_enabled_regmap, ··· 522 380 [RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" }, 523 381 }; 524 382 383 + static int rk808_regulator_dt_parse_pdata(struct device *dev, 384 + struct device *client_dev, 385 + struct regmap *map, 386 + struct rk808_regulator_data *pdata) 387 + { 388 + struct device_node *np; 389 + int tmp, ret, i; 390 + 391 + np = of_get_child_by_name(client_dev->of_node, "regulators"); 392 + if (!np) 393 + return -ENXIO; 394 + 395 + ret = of_regulator_match(dev, np, rk808_reg_matches, 396 + RK808_NUM_REGULATORS); 397 + if (ret < 0) 398 + goto dt_parse_end; 399 + 400 + for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) { 401 + pdata->dvs_gpio[i] = gpiod_get_index(client_dev, "dvs", i); 402 + if (IS_ERR(pdata->dvs_gpio[i])) { 403 + dev_warn(dev, "there is no dvs%d gpio\n", i); 404 + continue; 405 + } 406 + 407 + gpiod_direction_output(pdata->dvs_gpio[i], 0); 408 + 409 + tmp = i ? RK808_DVS2_POL : RK808_DVS1_POL; 410 + ret = regmap_update_bits(map, RK808_IO_POL_REG, tmp, 411 + gpiod_is_active_low(pdata->dvs_gpio[i]) ? 412 + 0 : tmp); 413 + } 414 + 415 + dt_parse_end: 416 + of_node_put(np); 417 + return ret; 418 + } 419 + 420 + static int rk808_regulator_remove(struct platform_device *pdev) 421 + { 422 + struct rk808_regulator_data *pdata = platform_get_drvdata(pdev); 423 + int i; 424 + 425 + for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) { 426 + if (!IS_ERR(pdata->dvs_gpio[i])) 427 + gpiod_put(pdata->dvs_gpio[i]); 428 + } 429 + 430 + return 0; 431 + } 432 + 525 433 static int rk808_regulator_probe(struct platform_device *pdev) 526 434 { 527 435 struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); 528 436 struct i2c_client *client = rk808->i2c; 529 - struct device_node *reg_np; 530 437 struct regulator_config config = {}; 531 438 struct regulator_dev *rk808_rdev; 439 + struct rk808_regulator_data *pdata; 532 440 int ret, i; 533 441 534 - reg_np = of_get_child_by_name(client->dev.of_node, "regulators"); 535 - if (!reg_np) 536 - return -ENXIO; 442 + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 443 + if (!pdata) 444 + return -ENOMEM; 537 445 538 - ret = of_regulator_match(&pdev->dev, reg_np, rk808_reg_matches, 539 - RK808_NUM_REGULATORS); 540 - of_node_put(reg_np); 446 + ret = rk808_regulator_dt_parse_pdata(&pdev->dev, &client->dev, 447 + rk808->regmap, pdata); 541 448 if (ret < 0) 542 449 return ret; 450 + 451 + platform_set_drvdata(pdev, pdata); 543 452 544 453 /* Instantiate the regulators */ 545 454 for (i = 0; i < RK808_NUM_REGULATORS; i++) { ··· 599 406 continue; 600 407 601 408 config.dev = &client->dev; 602 - config.driver_data = rk808; 409 + config.driver_data = pdata; 603 410 config.regmap = rk808->regmap; 604 411 config.of_node = rk808_reg_matches[i].of_node; 605 412 config.init_data = rk808_reg_matches[i].init_data; ··· 618 425 619 426 static struct platform_driver rk808_regulator_driver = { 620 427 .probe = rk808_regulator_probe, 428 + .remove = rk808_regulator_remove, 621 429 .driver = { 622 430 .name = "rk808-regulator", 431 + .owner = THIS_MODULE, 623 432 }, 624 433 }; 625 434