1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved 4 */ 5 6 #include <assert.h> 7 #include <drivers/stpmic1.h> 8 #include <kernel/panic.h> 9 #include <platform_config.h> 10 #include <stdint.h> 11 #include <string.h> 12 #include <trace.h> 13 #include <util.h> 14 15 #define VOLTAGE_INDEX_INVALID ((unsigned int)~0) 16 17 struct regul_struct { 18 const char *dt_node_name; 19 const uint16_t *voltage_table; 20 uint8_t voltage_table_size; 21 uint8_t control_reg; 22 uint8_t low_power_reg; 23 uint8_t enable_pos; 24 uint8_t pull_down_reg; 25 uint8_t pull_down_pos; 26 uint8_t mask_reset_reg; 27 uint8_t mask_reset_pos; 28 }; 29 30 static struct i2c_handle_s *pmic_i2c_handle; 31 static uint16_t pmic_i2c_addr; 32 33 /* Voltage tables in mV */ 34 static const uint16_t buck1_voltage_table[] = { 35 725, 36 725, 37 725, 38 725, 39 725, 40 725, 41 750, 42 775, 43 800, 44 825, 45 850, 46 875, 47 900, 48 925, 49 950, 50 975, 51 1000, 52 1025, 53 1050, 54 1075, 55 1100, 56 1125, 57 1150, 58 1175, 59 1200, 60 1225, 61 1250, 62 1275, 63 1300, 64 1325, 65 1350, 66 1375, 67 1400, 68 1425, 69 1450, 70 1475, 71 1500, 72 1500, 73 1500, 74 1500, 75 1500, 76 1500, 77 1500, 78 1500, 79 1500, 80 1500, 81 1500, 82 1500, 83 1500, 84 1500, 85 1500, 86 1500, 87 1500, 88 1500, 89 1500, 90 1500, 91 1500, 92 1500, 93 1500, 94 1500, 95 1500, 96 1500, 97 1500, 98 1500, 99 }; 100 101 static const uint16_t buck2_voltage_table[] = { 102 1000, 103 1000, 104 1000, 105 1000, 106 1000, 107 1000, 108 1000, 109 1000, 110 1000, 111 1000, 112 1000, 113 1000, 114 1000, 115 1000, 116 1000, 117 1000, 118 1000, 119 1000, 120 1050, 121 1050, 122 1100, 123 1100, 124 1150, 125 1150, 126 1200, 127 1200, 128 1250, 129 1250, 130 1300, 131 1300, 132 1350, 133 1350, 134 1400, 135 1400, 136 1450, 137 1450, 138 1500, 139 }; 140 141 static const uint16_t buck3_voltage_table[] = { 142 1000, 143 1000, 144 1000, 145 1000, 146 1000, 147 1000, 148 1000, 149 1000, 150 1000, 151 1000, 152 1000, 153 1000, 154 1000, 155 1000, 156 1000, 157 1000, 158 1000, 159 1000, 160 1000, 161 1000, 162 1100, 163 1100, 164 1100, 165 1100, 166 1200, 167 1200, 168 1200, 169 1200, 170 1300, 171 1300, 172 1300, 173 1300, 174 1400, 175 1400, 176 1400, 177 1400, 178 1500, 179 1600, 180 1700, 181 1800, 182 1900, 183 2000, 184 2100, 185 2200, 186 2300, 187 2400, 188 2500, 189 2600, 190 2700, 191 2800, 192 2900, 193 3000, 194 3100, 195 3200, 196 3300, 197 3400, 198 }; 199 200 static const uint16_t buck4_voltage_table[] = { 201 600, 202 625, 203 650, 204 675, 205 700, 206 725, 207 750, 208 775, 209 800, 210 825, 211 850, 212 875, 213 900, 214 925, 215 950, 216 975, 217 1000, 218 1025, 219 1050, 220 1075, 221 1100, 222 1125, 223 1150, 224 1175, 225 1200, 226 1225, 227 1250, 228 1275, 229 1300, 230 1300, 231 1350, 232 1350, 233 1400, 234 1400, 235 1450, 236 1450, 237 1500, 238 1600, 239 1700, 240 1800, 241 1900, 242 2000, 243 2100, 244 2200, 245 2300, 246 2400, 247 2500, 248 2600, 249 2700, 250 2800, 251 2900, 252 3000, 253 3100, 254 3200, 255 3300, 256 3400, 257 3500, 258 3600, 259 3700, 260 3800, 261 3900, 262 }; 263 264 static const uint16_t ldo1_voltage_table[] = { 265 1700, 266 1700, 267 1700, 268 1700, 269 1700, 270 1700, 271 1700, 272 1700, 273 1700, 274 1800, 275 1900, 276 2000, 277 2100, 278 2200, 279 2300, 280 2400, 281 2500, 282 2600, 283 2700, 284 2800, 285 2900, 286 3000, 287 3100, 288 3200, 289 3300, 290 }; 291 292 static const uint16_t ldo2_voltage_table[] = { 293 1700, 294 1700, 295 1700, 296 1700, 297 1700, 298 1700, 299 1700, 300 1700, 301 1700, 302 1800, 303 1900, 304 2000, 305 2100, 306 2200, 307 2300, 308 2400, 309 2500, 310 2600, 311 2700, 312 2800, 313 2900, 314 3000, 315 3100, 316 3200, 317 3300, 318 }; 319 320 static const uint16_t ldo3_voltage_table[] = { 321 1700, 322 1700, 323 1700, 324 1700, 325 1700, 326 1700, 327 1700, 328 1700, 329 1700, 330 1800, 331 1900, 332 2000, 333 2100, 334 2200, 335 2300, 336 2400, 337 2500, 338 2600, 339 2700, 340 2800, 341 2900, 342 3000, 343 3100, 344 3200, 345 3300, 346 3300, 347 3300, 348 3300, 349 3300, 350 3300, 351 3300, 352 500, /* VOUT2/2 (Sink/source mode) */ 353 0xFFFF, /* VREFDDR */ 354 }; 355 356 static const uint16_t ldo5_voltage_table[] = { 357 1700, 358 1700, 359 1700, 360 1700, 361 1700, 362 1700, 363 1700, 364 1700, 365 1700, 366 1800, 367 1900, 368 2000, 369 2100, 370 2200, 371 2300, 372 2400, 373 2500, 374 2600, 375 2700, 376 2800, 377 2900, 378 3000, 379 3100, 380 3200, 381 3300, 382 3400, 383 3500, 384 3600, 385 3700, 386 3800, 387 3900, 388 }; 389 390 static const uint16_t ldo6_voltage_table[] = { 391 900, 392 1000, 393 1100, 394 1200, 395 1300, 396 1400, 397 1500, 398 1600, 399 1700, 400 1800, 401 1900, 402 2000, 403 2100, 404 2200, 405 2300, 406 2400, 407 2500, 408 2600, 409 2700, 410 2800, 411 2900, 412 3000, 413 3100, 414 3200, 415 3300, 416 }; 417 418 static const uint16_t ldo4_voltage_table[] = { 419 3300, 420 }; 421 422 static const uint16_t vref_ddr_voltage_table[] = { 423 3300, 424 }; 425 426 static const uint16_t fixed_5v_voltage_table[] = { 427 5000, 428 }; 429 430 /* Table of Regulators in PMIC SoC */ 431 static const struct regul_struct regulators_table[] = { 432 { 433 .dt_node_name = "buck1", 434 .voltage_table = buck1_voltage_table, 435 .voltage_table_size = ARRAY_SIZE(buck1_voltage_table), 436 .control_reg = BUCK1_CONTROL_REG, 437 .low_power_reg = BUCK1_PWRCTRL_REG, 438 .enable_pos = LDO_BUCK_ENABLE_POS, 439 .pull_down_reg = BUCK_PULL_DOWN_REG, 440 .pull_down_pos = BUCK1_PULL_DOWN_SHIFT, 441 .mask_reset_reg = MASK_RESET_BUCK_REG, 442 .mask_reset_pos = BUCK1_MASK_RESET_SHIFT, 443 }, 444 { 445 .dt_node_name = "buck2", 446 .voltage_table = buck2_voltage_table, 447 .voltage_table_size = ARRAY_SIZE(buck2_voltage_table), 448 .control_reg = BUCK2_CONTROL_REG, 449 .low_power_reg = BUCK2_PWRCTRL_REG, 450 .enable_pos = LDO_BUCK_ENABLE_POS, 451 .pull_down_reg = BUCK_PULL_DOWN_REG, 452 .pull_down_pos = BUCK2_PULL_DOWN_SHIFT, 453 .mask_reset_reg = MASK_RESET_BUCK_REG, 454 .mask_reset_pos = BUCK2_MASK_RESET_SHIFT, 455 }, 456 { 457 .dt_node_name = "buck3", 458 .voltage_table = buck3_voltage_table, 459 .voltage_table_size = ARRAY_SIZE(buck3_voltage_table), 460 .control_reg = BUCK3_CONTROL_REG, 461 .low_power_reg = BUCK3_PWRCTRL_REG, 462 .enable_pos = LDO_BUCK_ENABLE_POS, 463 .pull_down_reg = BUCK_PULL_DOWN_REG, 464 .pull_down_pos = BUCK3_PULL_DOWN_SHIFT, 465 .mask_reset_reg = MASK_RESET_BUCK_REG, 466 .mask_reset_pos = BUCK3_MASK_RESET_SHIFT, 467 }, 468 { 469 .dt_node_name = "buck4", 470 .voltage_table = buck4_voltage_table, 471 .voltage_table_size = ARRAY_SIZE(buck4_voltage_table), 472 .control_reg = BUCK4_CONTROL_REG, 473 .low_power_reg = BUCK4_PWRCTRL_REG, 474 .enable_pos = LDO_BUCK_ENABLE_POS, 475 .pull_down_reg = BUCK_PULL_DOWN_REG, 476 .pull_down_pos = BUCK4_PULL_DOWN_SHIFT, 477 .mask_reset_reg = MASK_RESET_BUCK_REG, 478 .mask_reset_pos = BUCK4_MASK_RESET_SHIFT, 479 }, 480 { 481 .dt_node_name = "ldo1", 482 .voltage_table = ldo1_voltage_table, 483 .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), 484 .control_reg = LDO1_CONTROL_REG, 485 .low_power_reg = LDO1_PWRCTRL_REG, 486 .enable_pos = LDO_BUCK_ENABLE_POS, 487 .mask_reset_reg = MASK_RESET_LDO_REG, 488 .mask_reset_pos = LDO1_MASK_RESET_SHIFT, 489 }, 490 { 491 .dt_node_name = "ldo2", 492 .voltage_table = ldo2_voltage_table, 493 .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), 494 .control_reg = LDO2_CONTROL_REG, 495 .low_power_reg = LDO2_PWRCTRL_REG, 496 .enable_pos = LDO_BUCK_ENABLE_POS, 497 .mask_reset_reg = MASK_RESET_LDO_REG, 498 .mask_reset_pos = LDO2_MASK_RESET_SHIFT, 499 }, 500 { 501 .dt_node_name = "ldo3", 502 .voltage_table = ldo3_voltage_table, 503 .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), 504 .control_reg = LDO3_CONTROL_REG, 505 .low_power_reg = LDO3_PWRCTRL_REG, 506 .enable_pos = LDO_BUCK_ENABLE_POS, 507 .mask_reset_reg = MASK_RESET_LDO_REG, 508 .mask_reset_pos = LDO3_MASK_RESET_SHIFT, 509 }, 510 { 511 .dt_node_name = "ldo4", 512 .voltage_table = ldo4_voltage_table, 513 .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), 514 .control_reg = LDO4_CONTROL_REG, 515 .low_power_reg = LDO4_PWRCTRL_REG, 516 .enable_pos = LDO_BUCK_ENABLE_POS, 517 .mask_reset_reg = MASK_RESET_LDO_REG, 518 .mask_reset_pos = LDO4_MASK_RESET_SHIFT, 519 }, 520 { 521 .dt_node_name = "ldo5", 522 .voltage_table = ldo5_voltage_table, 523 .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), 524 .control_reg = LDO5_CONTROL_REG, 525 .low_power_reg = LDO5_PWRCTRL_REG, 526 .enable_pos = LDO_BUCK_ENABLE_POS, 527 .mask_reset_reg = MASK_RESET_LDO_REG, 528 .mask_reset_pos = LDO5_MASK_RESET_SHIFT, 529 }, 530 { 531 .dt_node_name = "ldo6", 532 .voltage_table = ldo6_voltage_table, 533 .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), 534 .control_reg = LDO6_CONTROL_REG, 535 .low_power_reg = LDO6_PWRCTRL_REG, 536 .enable_pos = LDO_BUCK_ENABLE_POS, 537 .mask_reset_reg = MASK_RESET_LDO_REG, 538 .mask_reset_pos = LDO6_MASK_RESET_SHIFT, 539 }, 540 { 541 .dt_node_name = "vref_ddr", 542 .voltage_table = vref_ddr_voltage_table, 543 .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), 544 .control_reg = VREF_DDR_CONTROL_REG, 545 .low_power_reg = VREF_DDR_PWRCTRL_REG, 546 .enable_pos = LDO_BUCK_ENABLE_POS, 547 .mask_reset_reg = MASK_RESET_LDO_REG, 548 .mask_reset_pos = VREF_DDR_MASK_RESET_SHIFT, 549 }, 550 { 551 .dt_node_name = "boost", 552 .voltage_table = fixed_5v_voltage_table, 553 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table), 554 .control_reg = USB_CONTROL_REG, 555 .enable_pos = BOOST_ENABLED_POS, 556 }, 557 { 558 .dt_node_name = "pwr_sw1", 559 .voltage_table = fixed_5v_voltage_table, 560 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table), 561 .control_reg = USB_CONTROL_REG, 562 .enable_pos = USBSW_OTG_SWITCH_ENABLED_POS, 563 }, 564 { 565 .dt_node_name = "pwr_sw2", 566 .voltage_table = fixed_5v_voltage_table, 567 .voltage_table_size = ARRAY_SIZE(fixed_5v_voltage_table), 568 .control_reg = USB_CONTROL_REG, 569 .enable_pos = SWIN_SWOUT_ENABLED_POS, 570 }, 571 }; 572 573 static const struct regul_struct *get_regulator_data(const char *name) 574 { 575 unsigned int i = 0; 576 577 for (i = 0; i < ARRAY_SIZE(regulators_table); i++) 578 if (strcmp(name, regulators_table[i].dt_node_name) == 0) 579 return ®ulators_table[i]; 580 581 DMSG("Regulator %s not found", name); 582 return NULL; 583 } 584 585 TEE_Result stpmic1_regulator_levels_mv(const char *name, 586 const uint16_t **levels, 587 size_t *levels_count) 588 { 589 const struct regul_struct *regul = get_regulator_data(name); 590 591 if (!regul) 592 return TEE_ERROR_BAD_PARAMETERS; 593 594 if (levels_count) 595 *levels_count = regul->voltage_table_size; 596 597 if (levels) 598 *levels = regul->voltage_table; 599 600 return TEE_SUCCESS; 601 } 602 603 static size_t voltage_to_index(const char *name, uint16_t millivolts) 604 { 605 const struct regul_struct *regul = get_regulator_data(name); 606 unsigned int i = 0; 607 608 assert(regul->voltage_table); 609 for (i = 0; i < regul->voltage_table_size; i++) 610 if (regul->voltage_table[i] == millivolts) 611 return i; 612 613 return VOLTAGE_INDEX_INVALID; 614 } 615 616 int stpmic1_powerctrl_on(void) 617 { 618 return stpmic1_register_update(MAIN_CONTROL_REG, PWRCTRL_PIN_VALID, 619 PWRCTRL_PIN_VALID); 620 } 621 622 int stpmic1_switch_off(void) 623 { 624 return stpmic1_register_update(MAIN_CONTROL_REG, 1, 625 SOFTWARE_SWITCH_OFF_ENABLED); 626 } 627 628 int stpmic1_regulator_enable(const char *name) 629 { 630 const struct regul_struct *regul = get_regulator_data(name); 631 632 return stpmic1_register_update(regul->control_reg, 633 BIT(regul->enable_pos), 634 BIT(regul->enable_pos)); 635 } 636 637 int stpmic1_regulator_disable(const char *name) 638 { 639 const struct regul_struct *regul = get_regulator_data(name); 640 641 return stpmic1_register_update(regul->control_reg, 0, 642 BIT(regul->enable_pos)); 643 } 644 645 bool stpmic1_is_regulator_enabled(const char *name) 646 { 647 const struct regul_struct *regul = get_regulator_data(name); 648 uint8_t val = 0; 649 650 if (stpmic1_register_read(regul->control_reg, &val)) 651 panic(); 652 653 return val & BIT(regul->enable_pos); 654 } 655 656 /* Voltage can be set for buck<N> or ldo<N> (except ldo4) regulators */ 657 static uint8_t find_plat_mask(const char *name) 658 { 659 if (!strncmp(name, "buck", 4)) 660 return BUCK_VOLTAGE_MASK; 661 662 if (!strncmp(name, "ldo", 3) && strcmp(name, "ldo4")) 663 return LDO_VOLTAGE_MASK; 664 665 return 0; 666 } 667 668 int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts) 669 { 670 size_t voltage_index = voltage_to_index(name, millivolts); 671 const struct regul_struct *regul = get_regulator_data(name); 672 uint8_t mask = 0; 673 674 if (voltage_index == VOLTAGE_INDEX_INVALID) 675 return -1; 676 677 mask = find_plat_mask(name); 678 if (!mask) 679 return 0; 680 681 return stpmic1_register_update(regul->control_reg, 682 voltage_index << LDO_BUCK_VOLTAGE_SHIFT, 683 mask); 684 } 685 686 int stpmic1_regulator_mask_reset_set(const char *name) 687 { 688 const struct regul_struct *regul = get_regulator_data(name); 689 690 if (regul->control_reg == USB_CONTROL_REG) { 691 DMSG("No reset for USB control"); 692 return -1; 693 } 694 695 return stpmic1_register_update(regul->mask_reset_reg, 696 BIT(regul->mask_reset_pos), 697 LDO_BUCK_RESET_MASK << 698 regul->mask_reset_pos); 699 } 700 701 int stpmic1_bo_enable_cfg(const char *name, struct stpmic1_bo_cfg *cfg) 702 { 703 const struct regul_struct *regul = get_regulator_data(name); 704 705 cfg->ctrl_reg = regul->control_reg; 706 cfg->enable_pos = regul->enable_pos; 707 708 return 0; 709 } 710 711 int stpmic1_bo_enable_unpg(struct stpmic1_bo_cfg *cfg) 712 { 713 return stpmic1_register_update(cfg->ctrl_reg, 714 BIT(cfg->enable_pos), 715 BIT(cfg->enable_pos)); 716 } 717 718 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */ 719 int stpmic1_bo_voltage_cfg(const char *name, uint16_t min_millivolt, 720 struct stpmic1_bo_cfg *cfg) 721 { 722 size_t min_index = voltage_to_index(name, min_millivolt); 723 const struct regul_struct *regul = get_regulator_data(name); 724 uint8_t mask = 0; 725 726 if (min_index == VOLTAGE_INDEX_INVALID) 727 panic(); 728 729 mask = find_plat_mask(name); 730 if (!mask) 731 return 1; 732 733 cfg->ctrl_reg = regul->control_reg; 734 cfg->min_value = min_index << LDO_BUCK_VOLTAGE_SHIFT; 735 cfg->mask = mask; 736 737 return 0; 738 } 739 740 int stpmic1_bo_voltage_unpg(struct stpmic1_bo_cfg *cfg) 741 { 742 uint8_t value = 0; 743 744 assert(cfg->ctrl_reg); 745 746 if (stpmic1_register_read(cfg->ctrl_reg, &value)) 747 return -1; 748 749 if ((value & cfg->mask) >= cfg->min_value) 750 return 0; 751 752 return stpmic1_register_update(cfg->ctrl_reg, cfg->min_value, 753 cfg->mask); 754 } 755 756 int stpmic1_bo_pull_down_cfg(const char *name, struct stpmic1_bo_cfg *cfg) 757 { 758 const struct regul_struct *regul = get_regulator_data(name); 759 760 if (!regul->pull_down_reg) { 761 DMSG("No pull down for regu %s", name); 762 panic(); 763 } 764 765 cfg->pd_reg = regul->pull_down_reg; 766 cfg->pd_value = BIT(regul->pull_down_pos); 767 cfg->pd_mask = LDO_BUCK_PULL_DOWN_MASK << regul->pull_down_pos; 768 769 return 0; 770 } 771 772 int stpmic1_bo_pull_down_unpg(struct stpmic1_bo_cfg *cfg) 773 { 774 assert(cfg->pd_reg); 775 776 return stpmic1_register_update(cfg->pd_reg, cfg->pd_value, 777 cfg->pd_mask); 778 } 779 780 int stpmic1_bo_mask_reset_cfg(const char *name, struct stpmic1_bo_cfg *cfg) 781 { 782 const struct regul_struct *regul = get_regulator_data(name); 783 784 if (!regul->mask_reset_reg) { 785 DMSG("No reset mask for regu %s", name); 786 panic(); 787 } 788 789 cfg->mrst_reg = regul->mask_reset_reg; 790 cfg->mrst_value = BIT(regul->mask_reset_pos); 791 cfg->mrst_mask = LDO_BUCK_RESET_MASK << regul->mask_reset_pos; 792 793 return 0; 794 } 795 796 int stpmic1_bo_mask_reset_unpg(struct stpmic1_bo_cfg *cfg) 797 { 798 assert(cfg->mrst_reg); 799 800 return stpmic1_register_update(cfg->mrst_reg, cfg->mrst_value, 801 cfg->mrst_mask); 802 } 803 804 int stpmic1_regulator_voltage_get(const char *name) 805 { 806 const struct regul_struct *regul = get_regulator_data(name); 807 uint8_t value = 0; 808 uint8_t mask = 0; 809 810 mask = find_plat_mask(name); 811 if (!mask) 812 return 0; 813 814 if (stpmic1_register_read(regul->control_reg, &value)) 815 return -1; 816 817 value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT; 818 819 if (value > regul->voltage_table_size) 820 return -1; 821 822 return regul->voltage_table[value]; 823 } 824 825 int stpmic1_lp_copy_reg(const char *name) 826 { 827 const struct regul_struct *regul = get_regulator_data(name); 828 uint8_t val = 0; 829 int status = 0; 830 831 if (!regul->low_power_reg) 832 return -1; 833 834 status = stpmic1_register_read(regul->control_reg, &val); 835 if (status) 836 return status; 837 838 return stpmic1_register_write(regul->low_power_reg, val); 839 } 840 841 bool stpmic1_regu_has_lp_cfg(const char *name) 842 { 843 return get_regulator_data(name)->low_power_reg; 844 } 845 846 int stpmic1_lp_cfg(const char *name, struct stpmic1_lp_cfg *cfg) 847 { 848 const struct regul_struct *regul = get_regulator_data(name); 849 850 if (!regul->low_power_reg) 851 return -1; 852 853 cfg->ctrl_reg = regul->control_reg; 854 cfg->lp_reg = regul->low_power_reg; 855 856 return 0; 857 } 858 859 int stpmic1_lp_load_unpg(struct stpmic1_lp_cfg *cfg) 860 { 861 uint8_t val = 0; 862 int status = 0; 863 864 assert(cfg->lp_reg); 865 866 status = stpmic1_register_read(cfg->ctrl_reg, &val); 867 if (!status) 868 status = stpmic1_register_write(cfg->lp_reg, val); 869 870 return status; 871 } 872 873 int stpmic1_lp_reg_on_off(const char *name, uint8_t enable) 874 { 875 const struct regul_struct *regul = get_regulator_data(name); 876 877 if (!regul->low_power_reg) 878 return -1; 879 880 return stpmic1_register_update(regul->low_power_reg, enable, 881 LDO_BUCK_ENABLE_MASK); 882 } 883 884 int stpmic1_lp_on_off_unpg(struct stpmic1_lp_cfg *cfg, int enable) 885 { 886 assert(cfg->lp_reg && (enable == 0 || enable == 1)); 887 888 return stpmic1_register_update(cfg->lp_reg, enable, 889 LDO_BUCK_ENABLE_MASK); 890 } 891 892 int stpmic1_lp_set_mode(const char *name, uint8_t hplp) 893 { 894 const struct regul_struct *regul = get_regulator_data(name); 895 896 assert(regul->low_power_reg && (hplp == 0 || hplp == 1)); 897 898 return stpmic1_register_update(regul->low_power_reg, 899 hplp << LDO_BUCK_HPLP_POS, 900 BIT(LDO_BUCK_HPLP_POS)); 901 } 902 903 int stpmic1_lp_mode_unpg(struct stpmic1_lp_cfg *cfg, unsigned int mode) 904 { 905 assert(cfg->lp_reg && (mode == 0 || mode == 1)); 906 return stpmic1_register_update(cfg->lp_reg, 907 mode << LDO_BUCK_HPLP_POS, 908 BIT(LDO_BUCK_HPLP_POS)); 909 } 910 911 int stpmic1_lp_set_voltage(const char *name, uint16_t millivolts) 912 { 913 size_t voltage_index = voltage_to_index(name, millivolts); 914 const struct regul_struct *regul = get_regulator_data(name); 915 uint8_t mask = 0; 916 917 assert(voltage_index != VOLTAGE_INDEX_INVALID); 918 919 mask = find_plat_mask(name); 920 if (!mask) 921 return 0; 922 923 return stpmic1_register_update(regul->low_power_reg, voltage_index << 2, 924 mask); 925 } 926 927 /* Returns 1 if no configuration are expected applied at runtime, 0 otherwise */ 928 int stpmic1_lp_voltage_cfg(const char *name, uint16_t millivolts, 929 struct stpmic1_lp_cfg *cfg) 930 931 { 932 size_t voltage_index = voltage_to_index(name, millivolts); 933 uint8_t mask = 0; 934 935 mask = find_plat_mask(name); 936 if (!mask) 937 return 1; 938 939 assert(voltage_index != VOLTAGE_INDEX_INVALID && 940 cfg->lp_reg == get_regulator_data(name)->low_power_reg); 941 942 cfg->value = voltage_index << 2; 943 cfg->mask = mask; 944 945 return 0; 946 } 947 948 int stpmic1_lp_voltage_unpg(struct stpmic1_lp_cfg *cfg) 949 { 950 assert(cfg->lp_reg); 951 952 return stpmic1_register_update(cfg->lp_reg, cfg->value, cfg->mask); 953 } 954 955 int stpmic1_register_read(uint8_t register_id, uint8_t *value) 956 { 957 struct i2c_handle_s *i2c = pmic_i2c_handle; 958 959 return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr, 960 register_id, value, 961 false /* !write */); 962 } 963 964 int stpmic1_register_write(uint8_t register_id, uint8_t value) 965 { 966 struct i2c_handle_s *i2c = pmic_i2c_handle; 967 uint8_t val = value; 968 969 return stm32_i2c_read_write_membyte(i2c, pmic_i2c_addr, 970 register_id, &val, 971 true /* write */); 972 } 973 974 int stpmic1_register_update(uint8_t register_id, uint8_t value, uint8_t mask) 975 { 976 int status = 0; 977 uint8_t val = 0; 978 979 status = stpmic1_register_read(register_id, &val); 980 if (status) 981 return status; 982 983 val = (val & ~mask) | (value & mask); 984 985 return stpmic1_register_write(register_id, val); 986 } 987 988 void stpmic1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr) 989 { 990 pmic_i2c_handle = i2c_handle; 991 pmic_i2c_addr = i2c_addr; 992 } 993 994 void stpmic1_dump_regulators(void) 995 { 996 size_t i = 0; 997 char __maybe_unused const *name = NULL; 998 999 for (i = 0; i < ARRAY_SIZE(regulators_table); i++) { 1000 if (!regulators_table[i].control_reg) 1001 continue; 1002 1003 name = regulators_table[i].dt_node_name; 1004 DMSG("PMIC regul %s: %sable, %dmV", 1005 name, stpmic1_is_regulator_enabled(name) ? "en" : "dis", 1006 stpmic1_regulator_voltage_get(name)); 1007 } 1008 } 1009 1010 int stpmic1_get_version(unsigned long *version) 1011 { 1012 uint8_t read_val = 0; 1013 1014 if (stpmic1_register_read(VERSION_STATUS_REG, &read_val)) 1015 return -1; 1016 1017 *version = read_val; 1018 return 0; 1019 } 1020