aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/s2mps11.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 14:44:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-03 14:44:48 -0400
commit312c76f1a3989b8d0c0c13fee765bb2c41f2d114 (patch)
treec3aeb04e87ad51cbf060a475c123b80d679cd33a /drivers/regulator/s2mps11.c
parente13cccfd86481bd4c0499577f44c570d334da79b (diff)
parent978371cbabb4cb7a47751049d72f06dc8348cab2 (diff)
Merge tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into next
Pull regulator updates from Mark Brown: "The bulk of the changes for this release are a few new drivers however there are a couple of noticable core changes and the usual stream of cleanups and fixes: - move disable of unused regulators later in init so it comes after deferred probe has iterated making startup smoother. - fixes to reference counting of the DT nodes for constraints from Charles Keepax. This has little practical impact since all real users of the regulator bindings use FDT which doesn't need the reference counting. - lots of cleanups, especially to the Samsung drivers. - support for Linear Technologies LTC3589, Texas Instruments TPS658640 and X-Powers AXP20x" * tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (64 commits) regulator: pbias: remove unnecessary OOM messages regulator: max8649: remove unnecessary OOM messages regulator: core: Fix the init of DT defined fixed regulators regulator: core: Disable unused regulators after deferred probing is done regulator: Don't disable unused regulators we don't have permission for regulator: axp20x: Use regulator_map_voltage_ascend for LDO4 regulator: use of_property_read_{bool|u32}() regulator: Fix regulator_get_{optional,exclusive}() documentation regulators: Add definition of regulator_set_voltage_time() for !CONFIG_REGULATOR regulator: arizona-ldo1: add missing #include regulator: pfuze100: Support enable/disable for fixed regulator regulator: ltc3589: Remove ltc3589_list_voltage_fixed function regulator: ltc3589: Fix module dependency regulator: tps6586x: Remove unused to_tps6586x_dev() function regulator: tps65218: Convert to use regulator_set_voltage_time_sel regulator: tps6586x: Add support for the TPS658640 regulator: tps6586x: Prepare supporting fixed regulators regulator: pfuze100: Don't allocate an invalid gpio regulator: pfuze100: Support SWB enable/disable regulator: fixed: use of_property_read_{bool|u32}() ...
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: