diff options
author | Matt Porter <mporter@linaro.org> | 2014-04-23 19:21:32 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2014-05-21 05:40:16 -0400 |
commit | c6466950e917890be3050171f6745ccb9d91d35f (patch) | |
tree | f4fc6c06108495bd2c33ecff68c065514e66a8cc /drivers/regulator/bcm590xx-regulator.c | |
parent | 9e1e726311830bc5b8b568d5178f6a52c357fb6e (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.c | 92 |
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 | ||
69 | struct bcm590xx_board { | 106 | struct 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 | ||
154 | struct bcm590xx_reg { | 197 | struct 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 | ||
269 | static 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 | ||
248 | static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( | 311 | static 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; |