aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/s2mps11.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/s2mps11.c')
-rw-r--r--drivers/regulator/s2mps11.c113
1 files changed, 96 insertions, 17 deletions
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index e713c162fbd4..02e2fb2fca66 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -27,6 +27,7 @@
27#include <linux/regulator/driver.h> 27#include <linux/regulator/driver.h>
28#include <linux/regulator/machine.h> 28#include <linux/regulator/machine.h>
29#include <linux/regulator/of_regulator.h> 29#include <linux/regulator/of_regulator.h>
30#include <linux/of_gpio.h>
30#include <linux/mfd/samsung/core.h> 31#include <linux/mfd/samsung/core.h>
31#include <linux/mfd/samsung/s2mps11.h> 32#include <linux/mfd/samsung/s2mps11.h>
32#include <linux/mfd/samsung/s2mps14.h> 33#include <linux/mfd/samsung/s2mps14.h>
@@ -44,6 +45,8 @@ struct s2mps11_info {
44 * was enabled. 45 * was enabled.
45 */ 46 */
46 unsigned int s2mps14_suspend_state:30; 47 unsigned int s2mps14_suspend_state:30;
48 /* Array of size rdev_num with GPIO-s for external sleep control */
49 int *ext_control_gpio;
47}; 50};
48 51
49static int get_ramp_delay(int ramp_delay) 52static int get_ramp_delay(int ramp_delay)
@@ -202,11 +205,16 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
202 if (!ramp_enable) 205 if (!ramp_enable)
203 goto ramp_disable; 206 goto ramp_disable;
204 207
205 ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP, 208 /* Ramp delay can be enabled/disabled only for buck[2346] */
206 1 << enable_shift, 1 << enable_shift); 209 if ((rdev_get_id(rdev) >= S2MPS11_BUCK2 &&
207 if (ret) { 210 rdev_get_id(rdev) <= S2MPS11_BUCK4) ||
208 dev_err(&rdev->dev, "failed to enable ramp rate\n"); 211 rdev_get_id(rdev) == S2MPS11_BUCK6) {
209 return ret; 212 ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP,
213 1 << enable_shift, 1 << enable_shift);
214 if (ret) {
215 dev_err(&rdev->dev, "failed to enable ramp rate\n");
216 return ret;
217 }
210 } 218 }
211 219
212 ramp_val = get_ramp_delay(ramp_delay); 220 ramp_val = get_ramp_delay(ramp_delay);
@@ -409,6 +417,8 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
409 417
410 if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) 418 if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
411 val = S2MPS14_ENABLE_SUSPEND; 419 val = S2MPS14_ENABLE_SUSPEND;
420 else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)]))
421 val = S2MPS14_ENABLE_EXT_CONTROL;
412 else 422 else
413 val = rdev->desc->enable_mask; 423 val = rdev->desc->enable_mask;
414 424
@@ -565,12 +575,61 @@ static const struct regulator_desc s2mps14_regulators[] = {
565 regulator_desc_s2mps14_buck1235(5), 575 regulator_desc_s2mps14_buck1235(5),
566}; 576};
567 577
578static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11,
579 struct regulator_dev *rdev)
580{
581 return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
582 rdev->desc->enable_mask, S2MPS14_ENABLE_EXT_CONTROL);
583}
584
585static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev,
586 struct of_regulator_match *rdata, struct s2mps11_info *s2mps11)
587{
588 int *gpio = s2mps11->ext_control_gpio;
589 unsigned int i;
590 unsigned int valid_regulators[3] = { S2MPS14_LDO10, S2MPS14_LDO11,
591 S2MPS14_LDO12 };
592
593 for (i = 0; i < ARRAY_SIZE(valid_regulators); i++) {
594 unsigned int reg = valid_regulators[i];
595
596 if (!rdata[reg].init_data || !rdata[reg].of_node)
597 continue;
598
599 gpio[reg] = of_get_named_gpio(rdata[reg].of_node,
600 "samsung,ext-control-gpios", 0);
601 if (gpio_is_valid(gpio[reg]))
602 dev_dbg(&pdev->dev, "Using GPIO %d for ext-control over %d/%s\n",
603 gpio[reg], reg, rdata[reg].name);
604 }
605}
606
607static int s2mps11_pmic_dt_parse(struct platform_device *pdev,
608 struct of_regulator_match *rdata, struct s2mps11_info *s2mps11,
609 enum sec_device_type dev_type)
610{
611 struct device_node *reg_np;
612
613 reg_np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
614 if (!reg_np) {
615 dev_err(&pdev->dev, "could not find regulators sub-node\n");
616 return -EINVAL;
617 }
618
619 of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num);
620 if (dev_type == S2MPS14X)
621 s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11);
622
623 of_node_put(reg_np);
624
625 return 0;
626}
627
568static int s2mps11_pmic_probe(struct platform_device *pdev) 628static int s2mps11_pmic_probe(struct platform_device *pdev)
569{ 629{
570 struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 630 struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
571 struct sec_platform_data *pdata = iodev->pdata; 631 struct sec_platform_data *pdata = NULL;
572 struct of_regulator_match *rdata = NULL; 632 struct of_regulator_match *rdata = NULL;
573 struct device_node *reg_np = NULL;
574 struct regulator_config config = { }; 633 struct regulator_config config = { };
575 struct s2mps11_info *s2mps11; 634 struct s2mps11_info *s2mps11;
576 int i, ret = 0; 635 int i, ret = 0;
@@ -597,8 +656,21 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
597 return -EINVAL; 656 return -EINVAL;
598 }; 657 };
599 658
659 s2mps11->ext_control_gpio = devm_kzalloc(&pdev->dev,
660 sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num,
661 GFP_KERNEL);
662 if (!s2mps11->ext_control_gpio)
663 return -ENOMEM;
664 /*
665 * 0 is a valid GPIO so initialize all GPIO-s to negative value
666 * to indicate that external control won't be used for this regulator.
667 */
668 for (i = 0; i < s2mps11->rdev_num; i++)
669 s2mps11->ext_control_gpio[i] = -EINVAL;
670
600 if (!iodev->dev->of_node) { 671 if (!iodev->dev->of_node) {
601 if (pdata) { 672 if (iodev->pdata) {
673 pdata = iodev->pdata;
602 goto common_reg; 674 goto common_reg;
603 } else { 675 } else {
604 dev_err(pdev->dev.parent, 676 dev_err(pdev->dev.parent,
@@ -614,15 +686,9 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
614 for (i = 0; i < s2mps11->rdev_num; i++) 686 for (i = 0; i < s2mps11->rdev_num; i++)
615 rdata[i].name = regulators[i].name; 687 rdata[i].name = regulators[i].name;
616 688
617 reg_np = of_get_child_by_name(iodev->dev->of_node, "regulators"); 689 ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type);
618 if (!reg_np) { 690 if (ret)
619 dev_err(&pdev->dev, "could not find regulators sub-node\n");
620 ret = -EINVAL;
621 goto out; 691 goto out;
622 }
623
624 of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num);
625 of_node_put(reg_np);
626 692
627common_reg: 693common_reg:
628 platform_set_drvdata(pdev, s2mps11); 694 platform_set_drvdata(pdev, s2mps11);
@@ -630,16 +696,18 @@ common_reg:
630 config.dev = &pdev->dev; 696 config.dev = &pdev->dev;
631 config.regmap = iodev->regmap_pmic; 697 config.regmap = iodev->regmap_pmic;
632 config.driver_data = s2mps11; 698 config.driver_data = s2mps11;
699 config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH;
633 for (i = 0; i < s2mps11->rdev_num; i++) { 700 for (i = 0; i < s2mps11->rdev_num; i++) {
634 struct regulator_dev *regulator; 701 struct regulator_dev *regulator;
635 702
636 if (!reg_np) { 703 if (pdata) {
637 config.init_data = pdata->regulators[i].initdata; 704 config.init_data = pdata->regulators[i].initdata;
638 config.of_node = pdata->regulators[i].reg_node; 705 config.of_node = pdata->regulators[i].reg_node;
639 } else { 706 } else {
640 config.init_data = rdata[i].init_data; 707 config.init_data = rdata[i].init_data;
641 config.of_node = rdata[i].of_node; 708 config.of_node = rdata[i].of_node;
642 } 709 }
710 config.ena_gpio = s2mps11->ext_control_gpio[i];
643 711
644 regulator = devm_regulator_register(&pdev->dev, 712 regulator = devm_regulator_register(&pdev->dev,
645 &regulators[i], &config); 713 &regulators[i], &config);
@@ -649,6 +717,17 @@ common_reg:
649 i); 717 i);
650 goto out; 718 goto out;
651 } 719 }
720
721 if (gpio_is_valid(s2mps11->ext_control_gpio[i])) {
722 ret = s2mps14_pmic_enable_ext_control(s2mps11,
723 regulator);
724 if (ret < 0) {
725 dev_err(&pdev->dev,
726 "failed to enable GPIO control over %s: %d\n",
727 regulator->desc->name, ret);
728 goto out;
729 }
730 }
652 } 731 }
653 732
654out: 733out: