aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
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/mfd
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/mfd')
-rw-r--r--drivers/mfd/arizona-core.c41
-rw-r--r--drivers/mfd/bcm590xx.c60
-rw-r--r--drivers/mfd/tps65090.c41
-rw-r--r--drivers/mfd/tps6586x.c4
4 files changed, 99 insertions, 47 deletions
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 1c3ae57082ed..07e6e27be23c 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -508,19 +508,31 @@ int arizona_of_get_type(struct device *dev)
508} 508}
509EXPORT_SYMBOL_GPL(arizona_of_get_type); 509EXPORT_SYMBOL_GPL(arizona_of_get_type);
510 510
511int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
512 bool mandatory)
513{
514 int gpio;
515
516 gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
517 if (gpio < 0) {
518 if (mandatory)
519 dev_err(arizona->dev,
520 "Mandatory DT gpio %s missing/malformed: %d\n",
521 prop, gpio);
522
523 gpio = 0;
524 }
525
526 return gpio;
527}
528EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
529
511static int arizona_of_get_core_pdata(struct arizona *arizona) 530static int arizona_of_get_core_pdata(struct arizona *arizona)
512{ 531{
532 struct arizona_pdata *pdata = &arizona->pdata;
513 int ret, i; 533 int ret, i;
514 534
515 arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node, 535 pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
516 "wlf,reset", 0);
517 if (arizona->pdata.reset < 0)
518 arizona->pdata.reset = 0;
519
520 arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
521 "wlf,ldoena", 0);
522 if (arizona->pdata.ldoena < 0)
523 arizona->pdata.ldoena = 0;
524 536
525 ret = of_property_read_u32_array(arizona->dev->of_node, 537 ret = of_property_read_u32_array(arizona->dev->of_node,
526 "wlf,gpio-defaults", 538 "wlf,gpio-defaults",
@@ -652,6 +664,9 @@ int arizona_dev_init(struct arizona *arizona)
652 return -EINVAL; 664 return -EINVAL;
653 } 665 }
654 666
667 /* Mark DCVDD as external, LDO1 driver will clear if internal */
668 arizona->external_dcvdd = true;
669
655 ret = mfd_add_devices(arizona->dev, -1, early_devs, 670 ret = mfd_add_devices(arizona->dev, -1, early_devs,
656 ARRAY_SIZE(early_devs), NULL, 0, NULL); 671 ARRAY_SIZE(early_devs), NULL, 0, NULL);
657 if (ret != 0) { 672 if (ret != 0) {
@@ -851,14 +866,6 @@ int arizona_dev_init(struct arizona *arizona)
851 arizona->pdata.gpio_defaults[i]); 866 arizona->pdata.gpio_defaults[i]);
852 } 867 }
853 868
854 /*
855 * LDO1 can only be used to supply DCVDD so if it has no
856 * consumers then DCVDD is supplied externally.
857 */
858 if (arizona->pdata.ldo1 &&
859 arizona->pdata.ldo1->num_consumer_supplies == 0)
860 arizona->external_dcvdd = true;
861
862 pm_runtime_set_autosuspend_delay(arizona->dev, 100); 869 pm_runtime_set_autosuspend_delay(arizona->dev, 100);
863 pm_runtime_use_autosuspend(arizona->dev); 870 pm_runtime_use_autosuspend(arizona->dev);
864 pm_runtime_enable(arizona->dev); 871 pm_runtime_enable(arizona->dev);
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
index e9a33c79431b..43cba1a1973c 100644
--- a/drivers/mfd/bcm590xx.c
+++ b/drivers/mfd/bcm590xx.c
@@ -28,39 +28,71 @@ static const struct mfd_cell bcm590xx_devs[] = {
28 }, 28 },
29}; 29};
30 30
31static const struct regmap_config bcm590xx_regmap_config = { 31static const struct regmap_config bcm590xx_regmap_config_pri = {
32 .reg_bits = 8, 32 .reg_bits = 8,
33 .val_bits = 8, 33 .val_bits = 8,
34 .max_register = BCM590XX_MAX_REGISTER, 34 .max_register = BCM590XX_MAX_REGISTER_PRI,
35 .cache_type = REGCACHE_RBTREE, 35 .cache_type = REGCACHE_RBTREE,
36}; 36};
37 37
38static int bcm590xx_i2c_probe(struct i2c_client *i2c, 38static const struct regmap_config bcm590xx_regmap_config_sec = {
39 .reg_bits = 8,
40 .val_bits = 8,
41 .max_register = BCM590XX_MAX_REGISTER_SEC,
42 .cache_type = REGCACHE_RBTREE,
43};
44
45static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
39 const struct i2c_device_id *id) 46 const struct i2c_device_id *id)
40{ 47{
41 struct bcm590xx *bcm590xx; 48 struct bcm590xx *bcm590xx;
42 int ret; 49 int ret;
43 50
44 bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL); 51 bcm590xx = devm_kzalloc(&i2c_pri->dev, sizeof(*bcm590xx), GFP_KERNEL);
45 if (!bcm590xx) 52 if (!bcm590xx)
46 return -ENOMEM; 53 return -ENOMEM;
47 54
48 i2c_set_clientdata(i2c, bcm590xx); 55 i2c_set_clientdata(i2c_pri, bcm590xx);
49 bcm590xx->dev = &i2c->dev; 56 bcm590xx->dev = &i2c_pri->dev;
50 bcm590xx->i2c_client = i2c; 57 bcm590xx->i2c_pri = i2c_pri;
51 58
52 bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config); 59 bcm590xx->regmap_pri = devm_regmap_init_i2c(i2c_pri,
53 if (IS_ERR(bcm590xx->regmap)) { 60 &bcm590xx_regmap_config_pri);
54 ret = PTR_ERR(bcm590xx->regmap); 61 if (IS_ERR(bcm590xx->regmap_pri)) {
55 dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); 62 ret = PTR_ERR(bcm590xx->regmap_pri);
63 dev_err(&i2c_pri->dev, "primary regmap init failed: %d\n", ret);
56 return ret; 64 return ret;
57 } 65 }
58 66
59 ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs, 67 /* Secondary I2C slave address is the base address with A(2) asserted */
68 bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter,
69 i2c_pri->addr | BIT(2));
70 if (IS_ERR_OR_NULL(bcm590xx->i2c_sec)) {
71 dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n");
72 return -ENODEV;
73 }
74 i2c_set_clientdata(bcm590xx->i2c_sec, bcm590xx);
75
76 bcm590xx->regmap_sec = devm_regmap_init_i2c(bcm590xx->i2c_sec,
77 &bcm590xx_regmap_config_sec);
78 if (IS_ERR(bcm590xx->regmap_sec)) {
79 ret = PTR_ERR(bcm590xx->regmap_sec);
80 dev_err(&bcm590xx->i2c_sec->dev,
81 "secondary regmap init failed: %d\n", ret);
82 goto err;
83 }
84
85 ret = mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
60 ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL); 86 ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
61 if (ret < 0) 87 if (ret < 0) {
62 dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret); 88 dev_err(&i2c_pri->dev, "failed to add sub-devices: %d\n", ret);
89 goto err;
90 }
91
92 return 0;
63 93
94err:
95 i2c_unregister_device(bcm590xx->i2c_sec);
64 return ret; 96 return ret;
65} 97}
66 98
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index ba1a25d758c1..1c3e6e2efe41 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -32,14 +32,6 @@
32#define NUM_INT_REG 2 32#define NUM_INT_REG 2
33#define TOTAL_NUM_REG 0x18 33#define TOTAL_NUM_REG 0x18
34 34
35/* interrupt status registers */
36#define TPS65090_INT_STS 0x0
37#define TPS65090_INT_STS2 0x1
38
39/* interrupt mask registers */
40#define TPS65090_INT_MSK 0x2
41#define TPS65090_INT_MSK2 0x3
42
43#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1 35#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1
44#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2 36#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2
45#define TPS65090_INT1_MASK_BAT_STATUS_CHANGE 3 37#define TPS65090_INT1_MASK_BAT_STATUS_CHANGE 3
@@ -64,11 +56,16 @@ static struct resource charger_resources[] = {
64 } 56 }
65}; 57};
66 58
67static const struct mfd_cell tps65090s[] = { 59enum tps65090_cells {
68 { 60 PMIC = 0,
61 CHARGER = 1,
62};
63
64static struct mfd_cell tps65090s[] = {
65 [PMIC] = {
69 .name = "tps65090-pmic", 66 .name = "tps65090-pmic",
70 }, 67 },
71 { 68 [CHARGER] = {
72 .name = "tps65090-charger", 69 .name = "tps65090-charger",
73 .num_resources = ARRAY_SIZE(charger_resources), 70 .num_resources = ARRAY_SIZE(charger_resources),
74 .resources = &charger_resources[0], 71 .resources = &charger_resources[0],
@@ -139,17 +136,26 @@ static struct regmap_irq_chip tps65090_irq_chip = {
139 .irqs = tps65090_irqs, 136 .irqs = tps65090_irqs,
140 .num_irqs = ARRAY_SIZE(tps65090_irqs), 137 .num_irqs = ARRAY_SIZE(tps65090_irqs),
141 .num_regs = NUM_INT_REG, 138 .num_regs = NUM_INT_REG,
142 .status_base = TPS65090_INT_STS, 139 .status_base = TPS65090_REG_INTR_STS,
143 .mask_base = TPS65090_INT_MSK, 140 .mask_base = TPS65090_REG_INTR_MASK,
144 .mask_invert = true, 141 .mask_invert = true,
145}; 142};
146 143
147static bool is_volatile_reg(struct device *dev, unsigned int reg) 144static bool is_volatile_reg(struct device *dev, unsigned int reg)
148{ 145{
149 if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS2)) 146 /* Nearly all registers have status bits mixed in, except a few */
150 return true; 147 switch (reg) {
151 else 148 case TPS65090_REG_INTR_MASK:
149 case TPS65090_REG_INTR_MASK2:
150 case TPS65090_REG_CG_CTRL0:
151 case TPS65090_REG_CG_CTRL1:
152 case TPS65090_REG_CG_CTRL2:
153 case TPS65090_REG_CG_CTRL3:
154 case TPS65090_REG_CG_CTRL4:
155 case TPS65090_REG_CG_CTRL5:
152 return false; 156 return false;
157 }
158 return true;
153} 159}
154 160
155static const struct regmap_config tps65090_regmap_config = { 161static const struct regmap_config tps65090_regmap_config = {
@@ -211,6 +217,9 @@ static int tps65090_i2c_probe(struct i2c_client *client,
211 "IRQ init failed with err: %d\n", ret); 217 "IRQ init failed with err: %d\n", ret);
212 return ret; 218 return ret;
213 } 219 }
220 } else {
221 /* Don't tell children they have an IRQ that'll never fire */
222 tps65090s[CHARGER].num_resources = 0;
214 } 223 }
215 224
216 ret = mfd_add_devices(tps65090->dev, -1, tps65090s, 225 ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index bbd54414a75d..835e5549ecdd 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -495,6 +495,10 @@ static void tps6586x_print_version(struct i2c_client *client, int version)
495 case TPS658623: 495 case TPS658623:
496 name = "TPS658623"; 496 name = "TPS658623";
497 break; 497 break;
498 case TPS658640:
499 case TPS658640v2:
500 name = "TPS658640";
501 break;
498 case TPS658643: 502 case TPS658643:
499 name = "TPS658643"; 503 name = "TPS658643";
500 break; 504 break;