aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/bcm590xx-regulator.c
diff options
context:
space:
mode:
authorMatt Porter <mporter@linaro.org>2014-04-23 19:21:32 -0400
committerLee Jones <lee.jones@linaro.org>2014-05-21 05:40:16 -0400
commitc6466950e917890be3050171f6745ccb9d91d35f (patch)
treef4fc6c06108495bd2c33ecff68c065514e66a8cc /drivers/regulator/bcm590xx-regulator.c
parent9e1e726311830bc5b8b568d5178f6a52c357fb6e (diff)
regulator: bcm590xx: Add support for regulators on secondary I2C slave
The bcm590xx MFD driver now exposes a secondary regmap descriptor making the registers for regulators on the secondary I2C slave address available. Add support for GPLDO1-6 and VBUS regulators found within this register range. Signed-off-by: Matt Porter <mporter@linaro.org> Acked-by: Mark Brown <broonie@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/regulator/bcm590xx-regulator.c')
-rw-r--r--drivers/regulator/bcm590xx-regulator.c92
1 files changed, 82 insertions, 10 deletions
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c
index c3750c5b382b..57544e254a78 100644
--- a/drivers/regulator/bcm590xx-regulator.c
+++ b/drivers/regulator/bcm590xx-regulator.c
@@ -22,7 +22,7 @@
22#include <linux/regulator/of_regulator.h> 22#include <linux/regulator/of_regulator.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24 24
25/* Register defs */ 25/* I2C slave 0 registers */
26#define BCM590XX_RFLDOPMCTRL1 0x60 26#define BCM590XX_RFLDOPMCTRL1 0x60
27#define BCM590XX_IOSR1PMCTRL1 0x7a 27#define BCM590XX_IOSR1PMCTRL1 0x7a
28#define BCM590XX_IOSR2PMCTRL1 0x7c 28#define BCM590XX_IOSR2PMCTRL1 0x7c
@@ -31,13 +31,34 @@
31#define BCM590XX_SDSR2PMCTRL1 0x86 31#define BCM590XX_SDSR2PMCTRL1 0x86
32#define BCM590XX_MSRPMCTRL1 0x8a 32#define BCM590XX_MSRPMCTRL1 0x8a
33#define BCM590XX_VSRPMCTRL1 0x8e 33#define BCM590XX_VSRPMCTRL1 0x8e
34#define BCM590XX_REG_ENABLE BIT(7)
35
36#define BCM590XX_RFLDOCTRL 0x96 34#define BCM590XX_RFLDOCTRL 0x96
37#define BCM590XX_CSRVOUT1 0xc0 35#define BCM590XX_CSRVOUT1 0xc0
36
37/* I2C slave 1 registers */
38#define BCM590XX_GPLDO5PMCTRL1 0x16
39#define BCM590XX_GPLDO6PMCTRL1 0x18
40#define BCM590XX_GPLDO1CTRL 0x1a
41#define BCM590XX_GPLDO2CTRL 0x1b
42#define BCM590XX_GPLDO3CTRL 0x1c
43#define BCM590XX_GPLDO4CTRL 0x1d
44#define BCM590XX_GPLDO5CTRL 0x1e
45#define BCM590XX_GPLDO6CTRL 0x1f
46#define BCM590XX_OTG_CTRL 0x40
47#define BCM590XX_GPLDO1PMCTRL1 0x57
48#define BCM590XX_GPLDO2PMCTRL1 0x59
49#define BCM590XX_GPLDO3PMCTRL1 0x5b
50#define BCM590XX_GPLDO4PMCTRL1 0x5d
51
52#define BCM590XX_REG_ENABLE BIT(7)
53#define BCM590XX_VBUS_ENABLE BIT(2)
38#define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3) 54#define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3)
39#define BCM590XX_SR_VSEL_MASK GENMASK(5, 0) 55#define BCM590XX_SR_VSEL_MASK GENMASK(5, 0)
40 56
57/*
58 * RFLDO to VSR regulators are
59 * accessed via I2C slave 0
60 */
61
41/* LDO regulator IDs */ 62/* LDO regulator IDs */
42#define BCM590XX_REG_RFLDO 0 63#define BCM590XX_REG_RFLDO 0
43#define BCM590XX_REG_CAMLDO1 1 64#define BCM590XX_REG_CAMLDO1 1
@@ -62,9 +83,25 @@
62#define BCM590XX_REG_SDSR2 18 83#define BCM590XX_REG_SDSR2 18
63#define BCM590XX_REG_VSR 19 84#define BCM590XX_REG_VSR 19
64 85
65#define BCM590XX_NUM_REGS 20 86/*
87 * GPLDO1 to VBUS regulators are
88 * accessed via I2C slave 1
89 */
90
91#define BCM590XX_REG_GPLDO1 20
92#define BCM590XX_REG_GPLDO2 21
93#define BCM590XX_REG_GPLDO3 22
94#define BCM590XX_REG_GPLDO4 23
95#define BCM590XX_REG_GPLDO5 24
96#define BCM590XX_REG_GPLDO6 25
97#define BCM590XX_REG_VBUS 26
98
99#define BCM590XX_NUM_REGS 27
66 100
67#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR) 101#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR)
102#define BCM590XX_REG_IS_GPLDO(n) \
103 ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
104#define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS)
68 105
69struct bcm590xx_board { 106struct bcm590xx_board {
70 struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS]; 107 struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS];
@@ -149,6 +186,12 @@ static struct bcm590xx_info bcm590xx_regs[] = {
149 BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges), 186 BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges),
150 BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges), 187 BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges),
151 BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges), 188 BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges),
189 BCM590XX_REG_TABLE(gpldo1, ldo_a_table),
190 BCM590XX_REG_TABLE(gpldo2, ldo_a_table),
191 BCM590XX_REG_TABLE(gpldo3, ldo_a_table),
192 BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
193 BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
194 BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
152}; 195};
153 196
154struct bcm590xx_reg { 197struct bcm590xx_reg {
@@ -161,6 +204,8 @@ static int bcm590xx_get_vsel_register(int id)
161{ 204{
162 if (BCM590XX_REG_IS_LDO(id)) 205 if (BCM590XX_REG_IS_LDO(id))
163 return BCM590XX_RFLDOCTRL + id; 206 return BCM590XX_RFLDOCTRL + id;
207 else if (BCM590XX_REG_IS_GPLDO(id))
208 return BCM590XX_GPLDO1CTRL + id;
164 else 209 else
165 return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3; 210 return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3;
166} 211}
@@ -171,6 +216,8 @@ static int bcm590xx_get_enable_register(int id)
171 216
172 if (BCM590XX_REG_IS_LDO(id)) 217 if (BCM590XX_REG_IS_LDO(id))
173 reg = BCM590XX_RFLDOPMCTRL1 + id * 2; 218 reg = BCM590XX_RFLDOPMCTRL1 + id * 2;
219 else if (BCM590XX_REG_IS_GPLDO(id))
220 reg = BCM590XX_GPLDO1PMCTRL1 + id * 2;
174 else 221 else
175 switch (id) { 222 switch (id) {
176 case BCM590XX_REG_CSR: 223 case BCM590XX_REG_CSR:
@@ -191,8 +238,11 @@ static int bcm590xx_get_enable_register(int id)
191 case BCM590XX_REG_SDSR2: 238 case BCM590XX_REG_SDSR2:
192 reg = BCM590XX_SDSR2PMCTRL1; 239 reg = BCM590XX_SDSR2PMCTRL1;
193 break; 240 break;
241 case BCM590XX_REG_VBUS:
242 reg = BCM590XX_OTG_CTRL;
194 }; 243 };
195 244
245
196 return reg; 246 return reg;
197} 247}
198 248
@@ -216,6 +266,12 @@ static struct regulator_ops bcm590xx_ops_dcdc = {
216 .map_voltage = regulator_map_voltage_linear_range, 266 .map_voltage = regulator_map_voltage_linear_range,
217}; 267};
218 268
269static struct regulator_ops bcm590xx_ops_vbus = {
270 .is_enabled = regulator_is_enabled_regmap,
271 .enable = regulator_enable_regmap,
272 .disable = regulator_disable_regmap,
273};
274
219#define BCM590XX_MATCH(_name, _id) \ 275#define BCM590XX_MATCH(_name, _id) \
220 { \ 276 { \
221 .name = #_name, \ 277 .name = #_name, \
@@ -243,6 +299,13 @@ static struct of_regulator_match bcm590xx_matches[] = {
243 BCM590XX_MATCH(sdsr1, SDSR1), 299 BCM590XX_MATCH(sdsr1, SDSR1),
244 BCM590XX_MATCH(sdsr2, SDSR2), 300 BCM590XX_MATCH(sdsr2, SDSR2),
245 BCM590XX_MATCH(vsr, VSR), 301 BCM590XX_MATCH(vsr, VSR),
302 BCM590XX_MATCH(gpldo1, GPLDO1),
303 BCM590XX_MATCH(gpldo2, GPLDO2),
304 BCM590XX_MATCH(gpldo3, GPLDO3),
305 BCM590XX_MATCH(gpldo4, GPLDO4),
306 BCM590XX_MATCH(gpldo5, GPLDO5),
307 BCM590XX_MATCH(gpldo6, GPLDO6),
308 BCM590XX_MATCH(vbus, VBUS),
246}; 309};
247 310
248static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( 311static struct bcm590xx_board *bcm590xx_parse_dt_reg_data(
@@ -353,17 +416,23 @@ static int bcm590xx_probe(struct platform_device *pdev)
353 pmu->desc[i].linear_ranges = info->linear_ranges; 416 pmu->desc[i].linear_ranges = info->linear_ranges;
354 pmu->desc[i].n_linear_ranges = info->n_linear_ranges; 417 pmu->desc[i].n_linear_ranges = info->n_linear_ranges;
355 418
356 if (BCM590XX_REG_IS_LDO(i)) { 419 if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) {
357 pmu->desc[i].ops = &bcm590xx_ops_ldo; 420 pmu->desc[i].ops = &bcm590xx_ops_ldo;
358 pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK; 421 pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK;
359 } else { 422 } else if (BCM590XX_REG_IS_VBUS(i))
423 pmu->desc[i].ops = &bcm590xx_ops_vbus;
424 else {
360 pmu->desc[i].ops = &bcm590xx_ops_dcdc; 425 pmu->desc[i].ops = &bcm590xx_ops_dcdc;
361 pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK; 426 pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK;
362 } 427 }
363 428
364 pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i); 429 if (BCM590XX_REG_IS_VBUS(i))
365 pmu->desc[i].enable_is_inverted = true; 430 pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE;
366 pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE; 431 else {
432 pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i);
433 pmu->desc[i].enable_is_inverted = true;
434 pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE;
435 }
367 pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i); 436 pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i);
368 pmu->desc[i].type = REGULATOR_VOLTAGE; 437 pmu->desc[i].type = REGULATOR_VOLTAGE;
369 pmu->desc[i].owner = THIS_MODULE; 438 pmu->desc[i].owner = THIS_MODULE;
@@ -371,7 +440,10 @@ static int bcm590xx_probe(struct platform_device *pdev)
371 config.dev = bcm590xx->dev; 440 config.dev = bcm590xx->dev;
372 config.init_data = reg_data; 441 config.init_data = reg_data;
373 config.driver_data = pmu; 442 config.driver_data = pmu;
374 config.regmap = bcm590xx->regmap; 443 if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
444 config.regmap = bcm590xx->regmap_sec;
445 else
446 config.regmap = bcm590xx->regmap_pri;
375 447
376 if (bcm590xx_reg_matches) 448 if (bcm590xx_reg_matches)
377 config.of_node = bcm590xx_reg_matches[i].of_node; 449 config.of_node = bcm590xx_reg_matches[i].of_node;