diff options
| -rw-r--r-- | drivers/regulator/s2mps11.c | 51 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/s2mps14.h | 2 |
2 files changed, 52 insertions, 1 deletions
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 65697b1a26c0..cdd8d4066121 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
| @@ -39,6 +39,11 @@ struct s2mps11_info { | |||
| 39 | int ramp_delay16; | 39 | int ramp_delay16; |
| 40 | int ramp_delay7810; | 40 | int ramp_delay7810; |
| 41 | int ramp_delay9; | 41 | int ramp_delay9; |
| 42 | /* | ||
| 43 | * One bit for each S2MPS14 regulator whether the suspend mode | ||
| 44 | * was enabled. | ||
| 45 | */ | ||
| 46 | unsigned int s2mps14_suspend_state:30; | ||
| 42 | }; | 47 | }; |
| 43 | 48 | ||
| 44 | static int get_ramp_delay(int ramp_delay) | 49 | static int get_ramp_delay(int ramp_delay) |
| @@ -399,15 +404,59 @@ static const struct regulator_desc s2mps11_regulators[] = { | |||
| 399 | regulator_desc_s2mps11_buck10, | 404 | regulator_desc_s2mps11_buck10, |
| 400 | }; | 405 | }; |
| 401 | 406 | ||
| 407 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | ||
| 408 | { | ||
| 409 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
| 410 | unsigned int val; | ||
| 411 | |||
| 412 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | ||
| 413 | val = S2MPS14_ENABLE_SUSPEND; | ||
| 414 | else | ||
| 415 | val = rdev->desc->enable_mask; | ||
| 416 | |||
| 417 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 418 | rdev->desc->enable_mask, val); | ||
| 419 | } | ||
| 420 | |||
| 421 | static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | ||
| 422 | { | ||
| 423 | int ret; | ||
| 424 | unsigned int val; | ||
| 425 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | ||
| 426 | |||
| 427 | /* LDO3 should be always on and does not support suspend mode */ | ||
| 428 | if (rdev_get_id(rdev) == S2MPS14_LDO3) | ||
| 429 | return 0; | ||
| 430 | |||
| 431 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); | ||
| 432 | if (ret < 0) | ||
| 433 | return ret; | ||
| 434 | |||
| 435 | s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev)); | ||
| 436 | /* | ||
| 437 | * Don't enable suspend mode if regulator is already disabled because | ||
| 438 | * this would effectively for a short time turn on the regulator after | ||
| 439 | * resuming. | ||
| 440 | * However we still want to toggle the suspend_state bit for regulator | ||
| 441 | * in case if it got enabled before suspending the system. | ||
| 442 | */ | ||
| 443 | if (!(val & rdev->desc->enable_mask)) | ||
| 444 | return 0; | ||
| 445 | |||
| 446 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | ||
| 447 | rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); | ||
| 448 | } | ||
| 449 | |||
| 402 | static struct regulator_ops s2mps14_reg_ops = { | 450 | static struct regulator_ops s2mps14_reg_ops = { |
| 403 | .list_voltage = regulator_list_voltage_linear, | 451 | .list_voltage = regulator_list_voltage_linear, |
| 404 | .map_voltage = regulator_map_voltage_linear, | 452 | .map_voltage = regulator_map_voltage_linear, |
| 405 | .is_enabled = regulator_is_enabled_regmap, | 453 | .is_enabled = regulator_is_enabled_regmap, |
| 406 | .enable = regulator_enable_regmap, | 454 | .enable = s2mps14_regulator_enable, |
| 407 | .disable = regulator_disable_regmap, | 455 | .disable = regulator_disable_regmap, |
| 408 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 456 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
| 409 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 457 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
| 410 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 458 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
| 459 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | ||
| 411 | }; | 460 | }; |
| 412 | 461 | ||
| 413 | #define regulator_desc_s2mps14_ldo1(num) { \ | 462 | #define regulator_desc_s2mps14_ldo1(num) { \ |
diff --git a/include/linux/mfd/samsung/s2mps14.h b/include/linux/mfd/samsung/s2mps14.h index ec1e0857ddde..4b449b8ac548 100644 --- a/include/linux/mfd/samsung/s2mps14.h +++ b/include/linux/mfd/samsung/s2mps14.h | |||
| @@ -146,6 +146,8 @@ enum s2mps14_regulators { | |||
| 146 | #define S2MPS14_BUCK_VSEL_MASK 0xFF | 146 | #define S2MPS14_BUCK_VSEL_MASK 0xFF |
| 147 | #define S2MPS14_ENABLE_MASK (0x03 << S2MPS14_ENABLE_SHIFT) | 147 | #define S2MPS14_ENABLE_MASK (0x03 << S2MPS14_ENABLE_SHIFT) |
| 148 | #define S2MPS14_ENABLE_SHIFT 6 | 148 | #define S2MPS14_ENABLE_SHIFT 6 |
| 149 | /* On/Off controlled by PWREN */ | ||
| 150 | #define S2MPS14_ENABLE_SUSPEND (0x01 << S2MPS14_ENABLE_SHIFT) | ||
| 149 | #define S2MPS14_LDO_N_VOLTAGES (S2MPS14_LDO_VSEL_MASK + 1) | 151 | #define S2MPS14_LDO_N_VOLTAGES (S2MPS14_LDO_VSEL_MASK + 1) |
| 150 | #define S2MPS14_BUCK_N_VOLTAGES (S2MPS14_BUCK_VSEL_MASK + 1) | 152 | #define S2MPS14_BUCK_N_VOLTAGES (S2MPS14_BUCK_VSEL_MASK + 1) |
| 151 | 153 | ||
