diff options
Diffstat (limited to 'drivers/regulator/pfuze100-regulator.c')
-rw-r--r-- | drivers/regulator/pfuze100-regulator.c | 134 |
1 files changed, 125 insertions, 9 deletions
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index c879dff597ee..8cc8d1877c44 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #define PFUZE100_VGEN5VOL 0x70 | 56 | #define PFUZE100_VGEN5VOL 0x70 |
57 | #define PFUZE100_VGEN6VOL 0x71 | 57 | #define PFUZE100_VGEN6VOL 0x71 |
58 | 58 | ||
59 | enum chips { PFUZE100, PFUZE200 }; | 59 | enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 }; |
60 | 60 | ||
61 | struct pfuze_regulator { | 61 | struct pfuze_regulator { |
62 | struct regulator_desc desc; | 62 | struct regulator_desc desc; |
@@ -80,9 +80,18 @@ static const int pfuze100_vsnvs[] = { | |||
80 | 1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000, | 80 | 1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static const int pfuze3000_sw2lo[] = { | ||
84 | 1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, | ||
85 | }; | ||
86 | |||
87 | static const int pfuze3000_sw2hi[] = { | ||
88 | 2500000, 2800000, 2850000, 3000000, 3100000, 3150000, 3200000, 3300000, | ||
89 | }; | ||
90 | |||
83 | static const struct i2c_device_id pfuze_device_id[] = { | 91 | static const struct i2c_device_id pfuze_device_id[] = { |
84 | {.name = "pfuze100", .driver_data = PFUZE100}, | 92 | {.name = "pfuze100", .driver_data = PFUZE100}, |
85 | {.name = "pfuze200", .driver_data = PFUZE200}, | 93 | {.name = "pfuze200", .driver_data = PFUZE200}, |
94 | {.name = "pfuze3000", .driver_data = PFUZE3000}, | ||
86 | { } | 95 | { } |
87 | }; | 96 | }; |
88 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); | 97 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); |
@@ -90,6 +99,7 @@ MODULE_DEVICE_TABLE(i2c, pfuze_device_id); | |||
90 | static const struct of_device_id pfuze_dt_ids[] = { | 99 | static const struct of_device_id pfuze_dt_ids[] = { |
91 | { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, | 100 | { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, |
92 | { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, | 101 | { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, |
102 | { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000}, | ||
93 | { } | 103 | { } |
94 | }; | 104 | }; |
95 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); | 105 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); |
@@ -219,6 +229,60 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
219 | .stby_mask = 0x20, \ | 229 | .stby_mask = 0x20, \ |
220 | } | 230 | } |
221 | 231 | ||
232 | #define PFUZE3000_VCC_REG(_chip, _name, base, min, max, step) { \ | ||
233 | .desc = { \ | ||
234 | .name = #_name, \ | ||
235 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
236 | .ops = &pfuze100_ldo_regulator_ops, \ | ||
237 | .type = REGULATOR_VOLTAGE, \ | ||
238 | .id = _chip ## _ ## _name, \ | ||
239 | .owner = THIS_MODULE, \ | ||
240 | .min_uV = (min), \ | ||
241 | .uV_step = (step), \ | ||
242 | .vsel_reg = (base), \ | ||
243 | .vsel_mask = 0x3, \ | ||
244 | .enable_reg = (base), \ | ||
245 | .enable_mask = 0x10, \ | ||
246 | }, \ | ||
247 | .stby_reg = (base), \ | ||
248 | .stby_mask = 0x20, \ | ||
249 | } | ||
250 | |||
251 | |||
252 | #define PFUZE3000_SW2_REG(_chip, _name, base, min, max, step) { \ | ||
253 | .desc = { \ | ||
254 | .name = #_name,\ | ||
255 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
256 | .ops = &pfuze100_sw_regulator_ops, \ | ||
257 | .type = REGULATOR_VOLTAGE, \ | ||
258 | .id = _chip ## _ ## _name, \ | ||
259 | .owner = THIS_MODULE, \ | ||
260 | .min_uV = (min), \ | ||
261 | .uV_step = (step), \ | ||
262 | .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ | ||
263 | .vsel_mask = 0x7, \ | ||
264 | }, \ | ||
265 | .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ | ||
266 | .stby_mask = 0x7, \ | ||
267 | } | ||
268 | |||
269 | #define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \ | ||
270 | .desc = { \ | ||
271 | .name = #_name,\ | ||
272 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
273 | .ops = &pfuze100_sw_regulator_ops, \ | ||
274 | .type = REGULATOR_VOLTAGE, \ | ||
275 | .id = _chip ## _ ## _name, \ | ||
276 | .owner = THIS_MODULE, \ | ||
277 | .min_uV = (min), \ | ||
278 | .uV_step = (step), \ | ||
279 | .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ | ||
280 | .vsel_mask = 0xf, \ | ||
281 | }, \ | ||
282 | .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ | ||
283 | .stby_mask = 0xf, \ | ||
284 | } | ||
285 | |||
222 | /* PFUZE100 */ | 286 | /* PFUZE100 */ |
223 | static struct pfuze_regulator pfuze100_regulators[] = { | 287 | static struct pfuze_regulator pfuze100_regulators[] = { |
224 | PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), | 288 | PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), |
@@ -254,6 +318,22 @@ static struct pfuze_regulator pfuze200_regulators[] = { | |||
254 | PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | 318 | PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), |
255 | }; | 319 | }; |
256 | 320 | ||
321 | static struct pfuze_regulator pfuze3000_regulators[] = { | ||
322 | PFUZE100_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 700000, 1475000, 25000), | ||
323 | PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000), | ||
324 | PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), | ||
325 | PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), | ||
326 | PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst), | ||
327 | PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), | ||
328 | PFUZE100_FIXED_REG(PFUZE3000, VREFDDR, PFUZE100_VREFDDRCON, 750000), | ||
329 | PFUZE100_VGEN_REG(PFUZE3000, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000), | ||
330 | PFUZE100_VGEN_REG(PFUZE3000, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), | ||
331 | PFUZE3000_VCC_REG(PFUZE3000, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000), | ||
332 | PFUZE3000_VCC_REG(PFUZE3000, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000), | ||
333 | PFUZE100_VGEN_REG(PFUZE3000, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), | ||
334 | PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | ||
335 | }; | ||
336 | |||
257 | static struct pfuze_regulator *pfuze_regulators; | 337 | static struct pfuze_regulator *pfuze_regulators; |
258 | 338 | ||
259 | #ifdef CONFIG_OF | 339 | #ifdef CONFIG_OF |
@@ -294,6 +374,24 @@ static struct of_regulator_match pfuze200_matches[] = { | |||
294 | { .name = "vgen6", }, | 374 | { .name = "vgen6", }, |
295 | }; | 375 | }; |
296 | 376 | ||
377 | /* PFUZE3000 */ | ||
378 | static struct of_regulator_match pfuze3000_matches[] = { | ||
379 | |||
380 | { .name = "sw1a", }, | ||
381 | { .name = "sw1b", }, | ||
382 | { .name = "sw2", }, | ||
383 | { .name = "sw3", }, | ||
384 | { .name = "swbst", }, | ||
385 | { .name = "vsnvs", }, | ||
386 | { .name = "vrefddr", }, | ||
387 | { .name = "vldo1", }, | ||
388 | { .name = "vldo2", }, | ||
389 | { .name = "vccsd", }, | ||
390 | { .name = "v33", }, | ||
391 | { .name = "vldo3", }, | ||
392 | { .name = "vldo4", }, | ||
393 | }; | ||
394 | |||
297 | static struct of_regulator_match *pfuze_matches; | 395 | static struct of_regulator_match *pfuze_matches; |
298 | 396 | ||
299 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | 397 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) |
@@ -313,6 +411,11 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | |||
313 | } | 411 | } |
314 | 412 | ||
315 | switch (chip->chip_id) { | 413 | switch (chip->chip_id) { |
414 | case PFUZE3000: | ||
415 | pfuze_matches = pfuze3000_matches; | ||
416 | ret = of_regulator_match(dev, parent, pfuze3000_matches, | ||
417 | ARRAY_SIZE(pfuze3000_matches)); | ||
418 | break; | ||
316 | case PFUZE200: | 419 | case PFUZE200: |
317 | pfuze_matches = pfuze200_matches; | 420 | pfuze_matches = pfuze200_matches; |
318 | ret = of_regulator_match(dev, parent, pfuze200_matches, | 421 | ret = of_regulator_match(dev, parent, pfuze200_matches, |
@@ -378,7 +481,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip) | |||
378 | * as ID=8 in PFUZE100 | 481 | * as ID=8 in PFUZE100 |
379 | */ | 482 | */ |
380 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); | 483 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); |
381 | } else if ((value & 0x0f) != pfuze_chip->chip_id) { | 484 | } else if ((value & 0x0f) != pfuze_chip->chip_id && |
485 | (value & 0xf0) >> 4 != pfuze_chip->chip_id) { | ||
382 | /* device id NOT match with your setting */ | 486 | /* device id NOT match with your setting */ |
383 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); | 487 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); |
384 | return -ENODEV; | 488 | return -ENODEV; |
@@ -417,7 +521,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
417 | int i, ret; | 521 | int i, ret; |
418 | const struct of_device_id *match; | 522 | const struct of_device_id *match; |
419 | u32 regulator_num; | 523 | u32 regulator_num; |
420 | u32 sw_check_start, sw_check_end; | 524 | u32 sw_check_start, sw_check_end, sw_hi = 0x40; |
421 | 525 | ||
422 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), | 526 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), |
423 | GFP_KERNEL); | 527 | GFP_KERNEL); |
@@ -458,13 +562,19 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
458 | 562 | ||
459 | /* use the right regulators after identify the right device */ | 563 | /* use the right regulators after identify the right device */ |
460 | switch (pfuze_chip->chip_id) { | 564 | switch (pfuze_chip->chip_id) { |
565 | case PFUZE3000: | ||
566 | pfuze_regulators = pfuze3000_regulators; | ||
567 | regulator_num = ARRAY_SIZE(pfuze3000_regulators); | ||
568 | sw_check_start = PFUZE3000_SW2; | ||
569 | sw_check_end = PFUZE3000_SW2; | ||
570 | sw_hi = 1 << 3; | ||
571 | break; | ||
461 | case PFUZE200: | 572 | case PFUZE200: |
462 | pfuze_regulators = pfuze200_regulators; | 573 | pfuze_regulators = pfuze200_regulators; |
463 | regulator_num = ARRAY_SIZE(pfuze200_regulators); | 574 | regulator_num = ARRAY_SIZE(pfuze200_regulators); |
464 | sw_check_start = PFUZE200_SW2; | 575 | sw_check_start = PFUZE200_SW2; |
465 | sw_check_end = PFUZE200_SW3B; | 576 | sw_check_end = PFUZE200_SW3B; |
466 | break; | 577 | break; |
467 | |||
468 | case PFUZE100: | 578 | case PFUZE100: |
469 | default: | 579 | default: |
470 | pfuze_regulators = pfuze100_regulators; | 580 | pfuze_regulators = pfuze100_regulators; |
@@ -474,7 +584,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
474 | break; | 584 | break; |
475 | } | 585 | } |
476 | dev_info(&client->dev, "pfuze%s found.\n", | 586 | dev_info(&client->dev, "pfuze%s found.\n", |
477 | (pfuze_chip->chip_id == PFUZE100) ? "100" : "200"); | 587 | (pfuze_chip->chip_id == PFUZE100) ? "100" : |
588 | ((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000")); | ||
478 | 589 | ||
479 | memcpy(pfuze_chip->regulator_descs, pfuze_regulators, | 590 | memcpy(pfuze_chip->regulator_descs, pfuze_regulators, |
480 | sizeof(pfuze_chip->regulator_descs)); | 591 | sizeof(pfuze_chip->regulator_descs)); |
@@ -498,10 +609,15 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
498 | /* SW2~SW4 high bit check and modify the voltage value table */ | 609 | /* SW2~SW4 high bit check and modify the voltage value table */ |
499 | if (i >= sw_check_start && i <= sw_check_end) { | 610 | if (i >= sw_check_start && i <= sw_check_end) { |
500 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); | 611 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); |
501 | if (val & 0x40) { | 612 | if (val & sw_hi) { |
502 | desc->min_uV = 800000; | 613 | if (pfuze_chip->chip_id == PFUZE3000) { |
503 | desc->uV_step = 50000; | 614 | desc->volt_table = pfuze3000_sw2hi; |
504 | desc->n_voltages = 51; | 615 | desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi); |
616 | } else { | ||
617 | desc->min_uV = 800000; | ||
618 | desc->uV_step = 50000; | ||
619 | desc->n_voltages = 51; | ||
620 | } | ||
505 | } | 621 | } |
506 | } | 622 | } |
507 | 623 | ||