.. | .. |
---|
31 | 31 | |
---|
32 | 32 | #define PFUZE100_COINVOL 0x1a |
---|
33 | 33 | #define PFUZE100_SW1ABVOL 0x20 |
---|
| 34 | +#define PFUZE100_SW1ABMODE 0x23 |
---|
34 | 35 | #define PFUZE100_SW1CVOL 0x2e |
---|
| 36 | +#define PFUZE100_SW1CMODE 0x31 |
---|
35 | 37 | #define PFUZE100_SW2VOL 0x35 |
---|
| 38 | +#define PFUZE100_SW2MODE 0x38 |
---|
36 | 39 | #define PFUZE100_SW3AVOL 0x3c |
---|
| 40 | +#define PFUZE100_SW3AMODE 0x3f |
---|
37 | 41 | #define PFUZE100_SW3BVOL 0x43 |
---|
| 42 | +#define PFUZE100_SW3BMODE 0x46 |
---|
38 | 43 | #define PFUZE100_SW4VOL 0x4a |
---|
| 44 | +#define PFUZE100_SW4MODE 0x4d |
---|
39 | 45 | #define PFUZE100_SWBSTCON1 0x66 |
---|
40 | 46 | #define PFUZE100_VREFDDRCON 0x6a |
---|
41 | 47 | #define PFUZE100_VSNVSVOL 0x6b |
---|
.. | .. |
---|
45 | 51 | #define PFUZE100_VGEN4VOL 0x6f |
---|
46 | 52 | #define PFUZE100_VGEN5VOL 0x70 |
---|
47 | 53 | #define PFUZE100_VGEN6VOL 0x71 |
---|
| 54 | + |
---|
| 55 | +#define PFUZE100_SWxMODE_MASK 0xf |
---|
| 56 | +#define PFUZE100_SWxMODE_APS_APS 0x8 |
---|
| 57 | +#define PFUZE100_SWxMODE_APS_OFF 0x4 |
---|
| 58 | + |
---|
| 59 | +#define PFUZE100_VGENxLPWR BIT(6) |
---|
| 60 | +#define PFUZE100_VGENxSTBY BIT(5) |
---|
48 | 61 | |
---|
49 | 62 | enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3, PFUZE3001 = 0x31, }; |
---|
50 | 63 | |
---|
.. | .. |
---|
115 | 128 | struct pfuze_chip *pfuze100 = rdev_get_drvdata(rdev); |
---|
116 | 129 | int id = rdev_get_id(rdev); |
---|
117 | 130 | bool reg_has_ramp_delay; |
---|
118 | | - unsigned int ramp_bits; |
---|
| 131 | + unsigned int ramp_bits = 0; |
---|
119 | 132 | int ret; |
---|
120 | 133 | |
---|
121 | 134 | switch (pfuze100->chip_id) { |
---|
.. | .. |
---|
136 | 149 | } |
---|
137 | 150 | |
---|
138 | 151 | if (reg_has_ramp_delay) { |
---|
139 | | - ramp_delay = 12500 / ramp_delay; |
---|
140 | | - ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); |
---|
| 152 | + if (ramp_delay > 0) { |
---|
| 153 | + ramp_delay = 12500 / ramp_delay; |
---|
| 154 | + ramp_bits = (ramp_delay >> 1) - (ramp_delay >> 3); |
---|
| 155 | + } |
---|
| 156 | + |
---|
141 | 157 | ret = regmap_update_bits(pfuze100->regmap, |
---|
142 | 158 | rdev->desc->vsel_reg + 4, |
---|
143 | 159 | 0xc0, ramp_bits << 6); |
---|
.. | .. |
---|
375 | 391 | PFUZE100_VGEN_REG(PFUZE100, VGEN4, PFUZE100_VGEN4VOL, 1800000, 3300000, 100000), |
---|
376 | 392 | PFUZE100_VGEN_REG(PFUZE100, VGEN5, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), |
---|
377 | 393 | PFUZE100_VGEN_REG(PFUZE100, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), |
---|
| 394 | + PFUZE100_COIN_REG(PFUZE100, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin), |
---|
378 | 395 | }; |
---|
379 | 396 | |
---|
380 | 397 | static struct pfuze_regulator pfuze200_regulators[] = { |
---|
.. | .. |
---|
441 | 458 | { .name = "vgen4", }, |
---|
442 | 459 | { .name = "vgen5", }, |
---|
443 | 460 | { .name = "vgen6", }, |
---|
| 461 | + { .name = "coin", }, |
---|
444 | 462 | }; |
---|
445 | 463 | |
---|
446 | 464 | /* PFUZE200 */ |
---|
.. | .. |
---|
513 | 531 | parent = of_get_child_by_name(np, "regulators"); |
---|
514 | 532 | if (!parent) { |
---|
515 | 533 | dev_err(dev, "regulators node not found\n"); |
---|
| 534 | + of_node_put(np); |
---|
516 | 535 | return -EINVAL; |
---|
517 | 536 | } |
---|
518 | 537 | |
---|
.. | .. |
---|
542 | 561 | } |
---|
543 | 562 | |
---|
544 | 563 | of_node_put(parent); |
---|
| 564 | + of_node_put(np); |
---|
545 | 565 | if (ret < 0) { |
---|
546 | 566 | dev_err(dev, "Error parsing regulator init data: %d\n", |
---|
547 | 567 | ret); |
---|
.. | .. |
---|
576 | 596 | return NULL; |
---|
577 | 597 | } |
---|
578 | 598 | #endif |
---|
| 599 | + |
---|
| 600 | +static struct pfuze_chip *syspm_pfuze_chip; |
---|
| 601 | + |
---|
| 602 | +static void pfuze_power_off_prepare(void) |
---|
| 603 | +{ |
---|
| 604 | + dev_info(syspm_pfuze_chip->dev, "Configure standby mode for power off"); |
---|
| 605 | + |
---|
| 606 | + /* Switch from default mode: APS/APS to APS/Off */ |
---|
| 607 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1ABMODE, |
---|
| 608 | + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); |
---|
| 609 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW1CMODE, |
---|
| 610 | + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); |
---|
| 611 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW2MODE, |
---|
| 612 | + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); |
---|
| 613 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3AMODE, |
---|
| 614 | + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); |
---|
| 615 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW3BMODE, |
---|
| 616 | + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); |
---|
| 617 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_SW4MODE, |
---|
| 618 | + PFUZE100_SWxMODE_MASK, PFUZE100_SWxMODE_APS_OFF); |
---|
| 619 | + |
---|
| 620 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN1VOL, |
---|
| 621 | + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, |
---|
| 622 | + PFUZE100_VGENxSTBY); |
---|
| 623 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN2VOL, |
---|
| 624 | + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, |
---|
| 625 | + PFUZE100_VGENxSTBY); |
---|
| 626 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN3VOL, |
---|
| 627 | + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, |
---|
| 628 | + PFUZE100_VGENxSTBY); |
---|
| 629 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN4VOL, |
---|
| 630 | + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, |
---|
| 631 | + PFUZE100_VGENxSTBY); |
---|
| 632 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN5VOL, |
---|
| 633 | + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, |
---|
| 634 | + PFUZE100_VGENxSTBY); |
---|
| 635 | + regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN6VOL, |
---|
| 636 | + PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, |
---|
| 637 | + PFUZE100_VGENxSTBY); |
---|
| 638 | +} |
---|
| 639 | + |
---|
| 640 | +static int pfuze_power_off_prepare_init(struct pfuze_chip *pfuze_chip) |
---|
| 641 | +{ |
---|
| 642 | + if (pfuze_chip->chip_id != PFUZE100) { |
---|
| 643 | + dev_warn(pfuze_chip->dev, "Requested pm_power_off_prepare handler for not supported chip\n"); |
---|
| 644 | + return -ENODEV; |
---|
| 645 | + } |
---|
| 646 | + |
---|
| 647 | + if (pm_power_off_prepare) { |
---|
| 648 | + dev_warn(pfuze_chip->dev, "pm_power_off_prepare is already registered.\n"); |
---|
| 649 | + return -EBUSY; |
---|
| 650 | + } |
---|
| 651 | + |
---|
| 652 | + if (syspm_pfuze_chip) { |
---|
| 653 | + dev_warn(pfuze_chip->dev, "syspm_pfuze_chip is already set.\n"); |
---|
| 654 | + return -EBUSY; |
---|
| 655 | + } |
---|
| 656 | + |
---|
| 657 | + syspm_pfuze_chip = pfuze_chip; |
---|
| 658 | + pm_power_off_prepare = pfuze_power_off_prepare; |
---|
| 659 | + |
---|
| 660 | + return 0; |
---|
| 661 | +} |
---|
579 | 662 | |
---|
580 | 663 | static int pfuze_identify(struct pfuze_chip *pfuze_chip) |
---|
581 | 664 | { |
---|
.. | .. |
---|
708 | 791 | ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001")))); |
---|
709 | 792 | |
---|
710 | 793 | memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, |
---|
711 | | - sizeof(pfuze_chip->regulator_descs)); |
---|
| 794 | + regulator_num * sizeof(struct pfuze_regulator)); |
---|
712 | 795 | |
---|
713 | 796 | ret = pfuze_parse_regulators_dt(pfuze_chip); |
---|
714 | 797 | if (ret) |
---|
.. | .. |
---|
780 | 863 | } |
---|
781 | 864 | } |
---|
782 | 865 | |
---|
| 866 | + if (of_property_read_bool(client->dev.of_node, |
---|
| 867 | + "fsl,pmic-stby-poweroff")) |
---|
| 868 | + return pfuze_power_off_prepare_init(pfuze_chip); |
---|
| 869 | + |
---|
| 870 | + return 0; |
---|
| 871 | +} |
---|
| 872 | + |
---|
| 873 | +static int pfuze100_regulator_remove(struct i2c_client *client) |
---|
| 874 | +{ |
---|
| 875 | + if (syspm_pfuze_chip) { |
---|
| 876 | + syspm_pfuze_chip = NULL; |
---|
| 877 | + pm_power_off_prepare = NULL; |
---|
| 878 | + } |
---|
| 879 | + |
---|
783 | 880 | return 0; |
---|
784 | 881 | } |
---|
785 | 882 | |
---|
.. | .. |
---|
790 | 887 | .of_match_table = pfuze_dt_ids, |
---|
791 | 888 | }, |
---|
792 | 889 | .probe = pfuze100_regulator_probe, |
---|
| 890 | + .remove = pfuze100_regulator_remove, |
---|
793 | 891 | }; |
---|
794 | 892 | module_i2c_driver(pfuze_driver); |
---|
795 | 893 | |
---|