1 From 08284f19c7cfdf84332c8098204f6e7fad368308 Mon Sep 17 00:00:00 2001
2 From: Robin Gong <b38343@freescale.com>
3 Date: Tue, 4 Mar 2014 17:40:36 +0800
4 Subject: [PATCH 03/10] regulator: pfuze100: add pfuze200 support
5 Organization: O.S. Systems Software LTDA.
7 support pfuze200 chip which remove SW1C and SW4 based on pfuze100.
9 Signed-off-by: Robin Gong <b38343@freescale.com>
10 Signed-off-by: Mark Brown <broonie@linaro.org>
11 (cherry picked from commit f2518480c7b744296a5587990a54e3a284d932b8)
15 drivers/regulator/pfuze100-regulator.c
16 (cherry picked from commit f9e62732cfb59ff68fed303bbbb3913d2f1002bf)
18 Upstream-Status: Pending
20 .../devicetree/bindings/regulator/pfuze100.txt | 96 ++++++++++-
21 drivers/regulator/pfuze100-regulator.c | 181 ++++++++++++++++-----
22 include/linux/regulator/pfuze100.h | 14 ++
23 3 files changed, 245 insertions(+), 46 deletions(-)
25 diff --git a/Documentation/devicetree/bindings/regulator/pfuze100.txt b/Documentation/devicetree/bindings/regulator/pfuze100.txt
26 index fc989b2..34ef5d1 100644
27 --- a/Documentation/devicetree/bindings/regulator/pfuze100.txt
28 +++ b/Documentation/devicetree/bindings/regulator/pfuze100.txt
30 PFUZE100 family of regulators
33 -- compatible: "fsl,pfuze100"
34 +- compatible: "fsl,pfuze100" or "fsl,pfuze200"
35 - reg: I2C slave address
38 @@ -10,11 +10,14 @@ Required child node:
39 Documentation/devicetree/bindings/regulator/regulator.txt.
41 The valid names for regulators are:
43 sw1ab,sw1c,sw2,sw3a,sw3b,sw4,swbst,vsnvs,vrefddr,vgen1~vgen6
45 + sw1ab,sw2,sw3a,sw3b,swbst,vsnvs,vrefddr,vgen1~vgen6
47 Each regulator is defined using the standard binding for regulators.
53 compatible = "fsl,pfuze100";
54 @@ -113,3 +116,92 @@ Example:
63 + compatible = "fsl,pfuze200";
68 + regulator-min-microvolt = <300000>;
69 + regulator-max-microvolt = <1875000>;
71 + regulator-always-on;
72 + regulator-ramp-delay = <6250>;
76 + regulator-min-microvolt = <800000>;
77 + regulator-max-microvolt = <3300000>;
79 + regulator-always-on;
83 + regulator-min-microvolt = <400000>;
84 + regulator-max-microvolt = <1975000>;
86 + regulator-always-on;
90 + regulator-min-microvolt = <400000>;
91 + regulator-max-microvolt = <1975000>;
93 + regulator-always-on;
97 + regulator-min-microvolt = <5000000>;
98 + regulator-max-microvolt = <5150000>;
102 + regulator-min-microvolt = <1000000>;
103 + regulator-max-microvolt = <3000000>;
105 + regulator-always-on;
108 + vref_reg: vrefddr {
110 + regulator-always-on;
114 + regulator-min-microvolt = <800000>;
115 + regulator-max-microvolt = <1550000>;
119 + regulator-min-microvolt = <800000>;
120 + regulator-max-microvolt = <1550000>;
124 + regulator-min-microvolt = <1800000>;
125 + regulator-max-microvolt = <3300000>;
129 + regulator-min-microvolt = <1800000>;
130 + regulator-max-microvolt = <3300000>;
131 + regulator-always-on;
135 + regulator-min-microvolt = <1800000>;
136 + regulator-max-microvolt = <3300000>;
137 + regulator-always-on;
141 + regulator-min-microvolt = <1800000>;
142 + regulator-max-microvolt = <3300000>;
143 + regulator-always-on;
147 diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
148 index 565a631..35b1de1 100644
149 --- a/drivers/regulator/pfuze100-regulator.c
150 +++ b/drivers/regulator/pfuze100-regulator.c
152 #define PFUZE100_VGEN5VOL 0x70
153 #define PFUZE100_VGEN6VOL 0x71
155 +enum chips {PFUZE100, PFUZE200, PFUZE_NUM};
157 struct pfuze_regulator {
158 struct regulator_desc desc;
159 unsigned char stby_reg;
160 @@ -63,6 +65,7 @@ struct pfuze_regulator {
165 struct regmap *regmap;
167 struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR];
168 @@ -77,15 +80,15 @@ static const int pfuze100_vsnvs[] = {
169 1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000,
172 -static const struct i2c_device_id pfuze_device_id[] = {
173 - {.name = "pfuze100"},
175 +static const struct i2c_device_id pfuze_device_id[PFUZE_NUM] = {
176 + {.name = "pfuze100", .driver_data = PFUZE100},
177 + {.name = "pfuze200", .driver_data = PFUZE200},
179 MODULE_DEVICE_TABLE(i2c, pfuze_device_id);
181 -static const struct of_device_id pfuze_dt_ids[] = {
182 - { .compatible = "fsl,pfuze100" },
184 +static const struct of_device_id pfuze_dt_ids[PFUZE_NUM] = {
185 + { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100},
186 + { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200},
188 MODULE_DEVICE_TABLE(of, pfuze_dt_ids);
190 @@ -139,14 +142,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
194 -#define PFUZE100_FIXED_REG(_name, base, voltage) \
195 - [PFUZE100_ ## _name] = { \
196 +#define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \
197 + [_chip ## _ ## _name] = { \
201 .ops = &pfuze100_fixed_regulator_ops, \
202 .type = REGULATOR_VOLTAGE, \
203 - .id = PFUZE100_ ## _name, \
204 + .id = _chip ## _ ## _name, \
205 .owner = THIS_MODULE, \
206 .min_uV = (voltage), \
207 .enable_reg = (base), \
208 @@ -154,14 +157,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
212 -#define PFUZE100_SW_REG(_name, base, min, max, step) \
213 - [PFUZE100_ ## _name] = { \
214 +#define PFUZE100_SW_REG(_chip, _name, base, min, max, step) \
215 + [_chip ## _ ## _name] = { \
218 .n_voltages = ((max) - (min)) / (step) + 1, \
219 .ops = &pfuze100_sw_regulator_ops, \
220 .type = REGULATOR_VOLTAGE, \
221 - .id = PFUZE100_ ## _name, \
222 + .id = _chip ## _ ## _name, \
223 .owner = THIS_MODULE, \
226 @@ -172,14 +175,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
230 -#define PFUZE100_SWB_REG(_name, base, mask, voltages) \
231 - [PFUZE100_ ## _name] = { \
232 +#define PFUZE100_SWB_REG(_chip, _name, base, mask, voltages) \
233 + [_chip ## _ ## _name] = { \
236 .n_voltages = ARRAY_SIZE(voltages), \
237 .ops = &pfuze100_swb_regulator_ops, \
238 .type = REGULATOR_VOLTAGE, \
239 - .id = PFUZE100_ ## _name, \
240 + .id = _chip ## _ ## _name, \
241 .owner = THIS_MODULE, \
242 .volt_table = voltages, \
243 .vsel_reg = (base), \
244 @@ -187,14 +190,14 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
248 -#define PFUZE100_VGEN_REG(_name, base, min, max, step) \
249 - [PFUZE100_ ## _name] = { \
250 +#define PFUZE100_VGEN_REG(_chip, _name, base, min, max, step) \
251 + [_chip ## _ ## _name] = { \
254 .n_voltages = ((max) - (min)) / (step) + 1, \
255 .ops = &pfuze100_ldo_regulator_ops, \
256 .type = REGULATOR_VOLTAGE, \
257 - .id = PFUZE100_ ## _name, \
258 + .id = _chip ## _ ## _name, \
259 .owner = THIS_MODULE, \
262 @@ -207,25 +210,45 @@ static struct regulator_ops pfuze100_swb_regulator_ops = {
267 static struct pfuze_regulator pfuze100_regulators[] = {
268 - PFUZE100_SW_REG(SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
269 - PFUZE100_SW_REG(SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000),
270 - PFUZE100_SW_REG(SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
271 - PFUZE100_SW_REG(SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
272 - PFUZE100_SW_REG(SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
273 - PFUZE100_SW_REG(SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000),
274 - PFUZE100_SWB_REG(SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
275 - PFUZE100_SWB_REG(VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
276 - PFUZE100_FIXED_REG(VREFDDR, PFUZE100_VREFDDRCON, 750000),
277 - PFUZE100_VGEN_REG(VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
278 - PFUZE100_VGEN_REG(VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
279 - PFUZE100_VGEN_REG(VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
280 - PFUZE100_VGEN_REG(VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
281 - PFUZE100_VGEN_REG(VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
282 - PFUZE100_VGEN_REG(VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
283 + PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
284 + PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000),
285 + PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
286 + PFUZE100_SW_REG(PFUZE100, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
287 + PFUZE100_SW_REG(PFUZE100, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
288 + PFUZE100_SW_REG(PFUZE100, SW4, PFUZE100_SW4VOL, 400000, 1975000, 25000),
289 + PFUZE100_SWB_REG(PFUZE100, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
290 + PFUZE100_SWB_REG(PFUZE100, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
291 + PFUZE100_FIXED_REG(PFUZE100, VREFDDR, PFUZE100_VREFDDRCON, 750000),
292 + PFUZE100_VGEN_REG(PFUZE100, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
293 + PFUZE100_VGEN_REG(PFUZE100, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
294 + PFUZE100_VGEN_REG(PFUZE100, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
295 + PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
296 + PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
297 + PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
300 +static struct pfuze_regulator pfuze200_regulators[] = {
301 + PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000),
302 + PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000),
303 + PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000),
304 + PFUZE100_SW_REG(PFUZE200, SW3B, PFUZE100_SW3BVOL, 400000, 1975000, 25000),
305 + PFUZE100_SWB_REG(PFUZE200, SWBST, PFUZE100_SWBSTCON1, 0x3 , pfuze100_swbst),
306 + PFUZE100_SWB_REG(PFUZE200, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs),
307 + PFUZE100_FIXED_REG(PFUZE200, VREFDDR, PFUZE100_VREFDDRCON, 750000),
308 + PFUZE100_VGEN_REG(PFUZE200, VGEN1, PFUZE100_VGEN1VOL, 800000, 1550000, 50000),
309 + PFUZE100_VGEN_REG(PFUZE200, VGEN2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000),
310 + PFUZE100_VGEN_REG(PFUZE200, VGEN3, PFUZE100_VGEN3VOL, 1800000, 3300000, 100000),
311 + PFUZE100_VGEN_REG(PFUZE200, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000),
312 + PFUZE100_VGEN_REG(PFUZE200, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000),
313 + PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000),
316 +static struct pfuze_regulator *pfuze_regulators;
320 static struct of_regulator_match pfuze100_matches[] = {
321 { .name = "sw1ab", },
323 @@ -244,6 +267,26 @@ static struct of_regulator_match pfuze100_matches[] = {
324 { .name = "vgen6", },
328 +static struct of_regulator_match pfuze200_matches[] = {
330 + { .name = "sw1ab", },
331 + { .name = "sw2", },
332 + { .name = "sw3a", },
333 + { .name = "sw3b", },
334 + { .name = "swbst", },
335 + { .name = "vsnvs", },
336 + { .name = "vrefddr", },
337 + { .name = "vgen1", },
338 + { .name = "vgen2", },
339 + { .name = "vgen3", },
340 + { .name = "vgen4", },
341 + { .name = "vgen5", },
342 + { .name = "vgen6", },
345 +static struct of_regulator_match *pfuze_matches;
347 static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
349 struct device *dev = chip->dev;
350 @@ -260,8 +303,20 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
354 - ret = of_regulator_match(dev, parent, pfuze100_matches,
355 - ARRAY_SIZE(pfuze100_matches));
356 + switch (chip->chip_id) {
358 + pfuze_matches = pfuze200_matches;
359 + ret = of_regulator_match(dev, parent, pfuze200_matches,
360 + ARRAY_SIZE(pfuze200_matches));
365 + pfuze_matches = pfuze100_matches;
366 + ret = of_regulator_match(dev, parent, pfuze100_matches,
367 + ARRAY_SIZE(pfuze100_matches));
373 @@ -275,12 +330,12 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
375 static inline struct regulator_init_data *match_init_data(int index)
377 - return pfuze100_matches[index].init_data;
378 + return pfuze_matches[index].init_data;
381 static inline struct device_node *match_of_node(int index)
383 - return pfuze100_matches[index].of_node;
384 + return pfuze_matches[index].of_node;
387 static int pfuze_parse_regulators_dt(struct pfuze_chip *chip)
388 @@ -308,7 +363,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
392 - if (value & 0x0f) {
393 + if ((value & 0x0f) != pfuze_chip->chip_id) {
394 + /* device id NOT match with your setting */
395 dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
398 @@ -344,17 +400,31 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
399 dev_get_platdata(&client->dev);
400 struct regulator_config config = { };
402 + const struct of_device_id *match;
404 + u32 sw_check_start, sw_check_end;
406 pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip),
411 - i2c_set_clientdata(client, pfuze_chip);
413 - memcpy(pfuze_chip->regulator_descs, pfuze100_regulators,
414 - sizeof(pfuze_chip->regulator_descs));
415 + if (client->dev.of_node) {
416 + match = of_match_device(of_match_ptr(pfuze_dt_ids),
419 + dev_err(&client->dev, "Error: No device match found\n");
422 + pfuze_chip->chip_id = (int)(long)match->data;
424 + pfuze_chip->chip_id = id->driver_data;
426 + dev_err(&client->dev, "No dts match or id table match found\n");
430 + i2c_set_clientdata(client, pfuze_chip);
431 pfuze_chip->dev = &client->dev;
433 pfuze_chip->regmap = devm_regmap_init_i2c(client, &pfuze_regmap_config);
434 @@ -371,11 +441,34 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
438 + /* use the right regulators after identify the right device */
439 + switch (pfuze_chip->chip_id) {
441 + pfuze_regulators = pfuze200_regulators;
442 + regulator_num = ARRAY_SIZE(pfuze200_regulators);
443 + sw_check_start = PFUZE200_SW2;
444 + sw_check_end = PFUZE200_SW3B;
449 + pfuze_regulators = pfuze100_regulators;
450 + regulator_num = ARRAY_SIZE(pfuze100_regulators);
451 + sw_check_start = PFUZE100_SW2;
452 + sw_check_end = PFUZE100_SW4;
455 + dev_info(&client->dev, "pfuze%s found.\n",
456 + (pfuze_chip->chip_id == PFUZE100) ? "100" : "200");
458 + memcpy(pfuze_chip->regulator_descs, pfuze_regulators,
459 + sizeof(pfuze_chip->regulator_descs));
461 ret = pfuze_parse_regulators_dt(pfuze_chip);
465 - for (i = 0; i < PFUZE100_MAX_REGULATOR; i++) {
466 + for (i = 0; i < regulator_num; i++) {
467 struct regulator_init_data *init_data;
468 struct regulator_desc *desc;
470 @@ -388,7 +481,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
471 init_data = match_init_data(i);
473 /* SW2~SW4 high bit check and modify the voltage value table */
474 - if (i > PFUZE100_SW1C && i < PFUZE100_SWBST) {
475 + if (i >= sw_check_start && i <= sw_check_end) {
476 regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val);
478 desc->min_uV = 800000;
479 diff --git a/include/linux/regulator/pfuze100.h b/include/linux/regulator/pfuze100.h
480 index 65d550b..364f7a7 100644
481 --- a/include/linux/regulator/pfuze100.h
482 +++ b/include/linux/regulator/pfuze100.h
484 #define PFUZE100_VGEN6 14
485 #define PFUZE100_MAX_REGULATOR 15
487 +#define PFUZE200_SW1AB 0
488 +#define PFUZE200_SW2 1
489 +#define PFUZE200_SW3A 2
490 +#define PFUZE200_SW3B 3
491 +#define PFUZE200_SWBST 4
492 +#define PFUZE200_VSNVS 5
493 +#define PFUZE200_VREFDDR 6
494 +#define PFUZE200_VGEN1 7
495 +#define PFUZE200_VGEN2 8
496 +#define PFUZE200_VGEN3 9
497 +#define PFUZE200_VGEN4 10
498 +#define PFUZE200_VGEN5 11
499 +#define PFUZE200_VGEN6 12
501 struct regulator_init_data;
503 struct pfuze_regulator_platform_data {