Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

regulator: s2mps11: add S2MPG10 regulator

The S2MPG10 PMIC is a Power Management IC for mobile applications with
buck converters, various LDOs, power meters, RTC, clock outputs, and
additional GPIO interfaces.

It has 10 buck and 31 LDO rails. Several of these can either be
controlled via software (register writes) or via external signals, in
particular by:
* one out of several input pins connected to a main processor's:
* GPIO pins
* other pins that are e.g. firmware- or power-domain-controlled
without explicit driver intervention
* a combination of input pins and register writes.

Control via input pins allows PMIC rails to be controlled by firmware,
e.g. during standby/suspend, or as part of power domain handling where
otherwise that would not be possible. Additionally toggling a pin is
faster than register writes, and it also allows the PMIC to ensure that
any necessary timing requirements between rails are respected
automatically if multiple rails are to be enabled or disabled quasi
simultaneously.

This commit implements support for all these rails and control
combinations.

Additional data needs to be stored for each regulator, e.g. the input
pin for external control, or a rail-specific ramp-rate for when
enabling a buck-rail. Therefore, probe() is updated slightly to make
that possible.

Note1: For an externally controlled rail, the regulator_ops provide an
empty ::enable() and no ::disable() implementations, even though Linux
can not enable the rail and one might think ::enable could be NULL.
Without ops->enable(), the regulator core will assume enabling such a
rail failed, though, and in turn never add a reference to its parent
(supplier) rail. Once a different (Linux-controlled) sibling (consumer)
rail on that same parent rail gets disabled, the parent gets disabled
(cutting power to the externally controlled rail although it should
stay on), and the system will misbehave.

Note2: While external control via input pins appears to exist on other
versions of this PMIC, there is more flexibility in this version, in
particular there is a selection of input pins to choose from for each
rail (which must therefore be configured accordingly if in use),
whereas other versions don't have this flexibility.

Signed-off-by: André Draszik <andre.draszik@linaro.org>
Link: https://patch.msgid.link/20260122-s2mpg1x-regulators-v7-16-3b1f9831fffd@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

André Draszik and committed by
Mark Brown
a2b8b9f3 0042c880

+608 -3
+584 -3
drivers/regulator/s2mps11.c
··· 3 3 // Copyright (c) 2012-2014 Samsung Electronics Co., Ltd 4 4 // http://www.samsung.com 5 5 6 + #include <dt-bindings/regulator/samsung,s2mpg10-regulator.h> 6 7 #include <linux/bug.h> 7 8 #include <linux/cleanup.h> 8 9 #include <linux/err.h> ··· 17 16 #include <linux/regulator/machine.h> 18 17 #include <linux/regulator/of_regulator.h> 19 18 #include <linux/mfd/samsung/core.h> 19 + #include <linux/mfd/samsung/s2mpg10.h> 20 20 #include <linux/mfd/samsung/s2mps11.h> 21 21 #include <linux/mfd/samsung/s2mps13.h> 22 22 #include <linux/mfd/samsung/s2mps14.h> 23 23 #include <linux/mfd/samsung/s2mps15.h> 24 24 #include <linux/mfd/samsung/s2mpu02.h> 25 25 #include <linux/mfd/samsung/s2mpu05.h> 26 + 27 + enum { 28 + S2MPG10_REGULATOR_OPS_STD, 29 + S2MPG10_REGULATOR_OPS_EXTCONTROL, 30 + }; 26 31 27 32 /* The highest number of possible regulators for supported devices. */ 28 33 #define S2MPS_REGULATOR_MAX S2MPS13_REGULATOR_MAX ··· 47 40 * the suspend mode was enabled. 48 41 */ 49 42 DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX); 43 + }; 44 + 45 + #define to_s2mpg10_regulator_desc(x) container_of((x), struct s2mpg10_regulator_desc, desc) 46 + 47 + struct s2mpg10_regulator_desc { 48 + struct regulator_desc desc; 49 + 50 + /* Ramp rate during enable, valid for bucks only. */ 51 + unsigned int enable_ramp_rate; 52 + 53 + /* Registers for external control of rail. */ 54 + unsigned int pctrlsel_reg; 55 + unsigned int pctrlsel_mask; 56 + /* Populated from DT. */ 57 + unsigned int pctrlsel_val; 50 58 }; 51 59 52 60 static int get_ramp_delay(int ramp_delay) ··· 415 393 return s2mps11_of_parse_gpiod(np, "samsung,ext-control", false, desc, 416 394 config); 417 395 } 396 + 397 + static int s2mpg10_of_parse_cb(struct device_node *np, 398 + const struct regulator_desc *desc, 399 + struct regulator_config *config) 400 + { 401 + const struct s2mps11_info *s2mps11 = config->driver_data; 402 + struct s2mpg10_regulator_desc *s2mpg10_desc = to_s2mpg10_regulator_desc(desc); 403 + static const u32 ext_control_s2mpg10[] = { 404 + [S2MPG10_EXTCTRL_PWREN] = S2MPG10_PCTRLSEL_PWREN, 405 + [S2MPG10_EXTCTRL_PWREN_MIF] = S2MPG10_PCTRLSEL_PWREN_MIF, 406 + [S2MPG10_EXTCTRL_AP_ACTIVE_N] = S2MPG10_PCTRLSEL_AP_ACTIVE_N, 407 + [S2MPG10_EXTCTRL_CPUCL1_EN] = S2MPG10_PCTRLSEL_CPUCL1_EN, 408 + [S2MPG10_EXTCTRL_CPUCL1_EN2] = S2MPG10_PCTRLSEL_CPUCL1_EN2, 409 + [S2MPG10_EXTCTRL_CPUCL2_EN] = S2MPG10_PCTRLSEL_CPUCL2_EN, 410 + [S2MPG10_EXTCTRL_CPUCL2_EN2] = S2MPG10_PCTRLSEL_CPUCL2_EN2, 411 + [S2MPG10_EXTCTRL_TPU_EN] = S2MPG10_PCTRLSEL_TPU_EN, 412 + [S2MPG10_EXTCTRL_TPU_EN2] = S2MPG10_PCTRLSEL_TPU_EN2, 413 + [S2MPG10_EXTCTRL_TCXO_ON] = S2MPG10_PCTRLSEL_TCXO_ON, 414 + [S2MPG10_EXTCTRL_TCXO_ON2] = S2MPG10_PCTRLSEL_TCXO_ON2, 415 + [S2MPG10_EXTCTRL_LDO20M_EN2] = S2MPG10_PCTRLSEL_LDO20M_EN2, 416 + [S2MPG10_EXTCTRL_LDO20M_EN] = S2MPG10_PCTRLSEL_LDO20M_EN, 417 + }; 418 + u32 ext_control; 419 + 420 + if (s2mps11->dev_type != S2MPG10) 421 + return 0; 422 + 423 + if (of_property_read_u32(np, "samsung,ext-control", &ext_control)) 424 + return 0; 425 + 426 + switch (s2mps11->dev_type) { 427 + case S2MPG10: 428 + switch (desc->id) { 429 + case S2MPG10_BUCK1 ... S2MPG10_BUCK7: 430 + case S2MPG10_BUCK10: 431 + case S2MPG10_LDO3 ... S2MPG10_LDO19: 432 + if (ext_control > S2MPG10_EXTCTRL_TCXO_ON2) 433 + return -EINVAL; 434 + break; 435 + 436 + case S2MPG10_LDO20: 437 + if (ext_control < S2MPG10_EXTCTRL_LDO20M_EN2 || 438 + ext_control > S2MPG10_EXTCTRL_LDO20M_EN) 439 + return -EINVAL; 440 + break; 441 + 442 + default: 443 + return -EINVAL; 444 + } 445 + 446 + if (ext_control > ARRAY_SIZE(ext_control_s2mpg10)) 447 + return -EINVAL; 448 + ext_control = ext_control_s2mpg10[ext_control]; 449 + break; 450 + 451 + default: 452 + return -EINVAL; 453 + } 454 + 455 + /* 456 + * If the regulator should be configured for external control, then: 457 + * 1) the PCTRLSELx register needs to be set accordingly 458 + * 2) regulator_desc::enable_val needs to be: 459 + * a) updated and 460 + * b) written to the hardware 461 + * 3) we switch to the ::ops that provide an empty ::enable() and no 462 + * ::disable() implementations 463 + * 464 + * Points 1) and 2b) will be handled in _probe(), after 465 + * devm_regulator_register() returns, so that we can properly act on 466 + * failures, since the regulator core ignores most return values from 467 + * this parse callback. 468 + */ 469 + s2mpg10_desc->pctrlsel_val = ext_control; 470 + s2mpg10_desc->pctrlsel_val <<= (ffs(s2mpg10_desc->pctrlsel_mask) - 1); 471 + 472 + s2mpg10_desc->desc.enable_val = S2MPG10_PMIC_CTRL_ENABLE_EXT; 473 + s2mpg10_desc->desc.enable_val <<= (ffs(desc->enable_mask) - 1); 474 + 475 + ++s2mpg10_desc->desc.ops; 476 + 477 + return s2mps11_of_parse_gpiod(np, "enable", true, desc, config); 478 + } 479 + 480 + static int s2mpg10_enable_ext_control(struct s2mps11_info *s2mps11, 481 + struct regulator_dev *rdev) 482 + { 483 + const struct s2mpg10_regulator_desc *s2mpg10_desc; 484 + int ret; 485 + 486 + switch (s2mps11->dev_type) { 487 + case S2MPG10: 488 + s2mpg10_desc = to_s2mpg10_regulator_desc(rdev->desc); 489 + break; 490 + 491 + default: 492 + return 0; 493 + } 494 + 495 + ret = regmap_update_bits(rdev_get_regmap(rdev), 496 + s2mpg10_desc->pctrlsel_reg, 497 + s2mpg10_desc->pctrlsel_mask, 498 + s2mpg10_desc->pctrlsel_val); 499 + if (ret) 500 + return dev_err_probe(rdev_get_dev(rdev), ret, 501 + "failed to configure pctrlsel for %s\n", 502 + rdev->desc->name); 503 + 504 + /* 505 + * When using external control, the enable bit of the regulator still 506 + * needs to be set. The actual state will still be determined by the 507 + * external signal. 508 + */ 509 + ret = regulator_enable_regmap(rdev); 510 + if (ret) 511 + return dev_err_probe(rdev_get_dev(rdev), ret, 512 + "failed to enable regulator %s\n", 513 + rdev->desc->name); 514 + 515 + return 0; 516 + } 517 + 518 + static int s2mpg10_regulator_enable_nop(struct regulator_dev *rdev) 519 + { 520 + /* 521 + * We need to provide this, otherwise the regulator core's enable on 522 + * this regulator will return a failure and subsequently disable our 523 + * parent regulator. 524 + */ 525 + return 0; 526 + } 527 + 528 + static int s2mpg10_regulator_buck_enable_time(struct regulator_dev *rdev) 529 + { 530 + const struct s2mpg10_regulator_desc * const s2mpg10_desc = 531 + to_s2mpg10_regulator_desc(rdev->desc); 532 + const struct regulator_ops * const ops = rdev->desc->ops; 533 + int vsel, curr_uV; 534 + 535 + vsel = ops->get_voltage_sel(rdev); 536 + if (vsel < 0) 537 + return vsel; 538 + 539 + curr_uV = ops->list_voltage(rdev, vsel); 540 + if (curr_uV < 0) 541 + return curr_uV; 542 + 543 + return (rdev->desc->enable_time 544 + + DIV_ROUND_UP(curr_uV, s2mpg10_desc->enable_ramp_rate)); 545 + } 546 + 547 + static int s2mpg10_regulator_buck_set_voltage_time(struct regulator_dev *rdev, 548 + int old_uV, int new_uV) 549 + { 550 + unsigned int ramp_reg, ramp_sel, ramp_rate; 551 + int ret; 552 + 553 + if (old_uV == new_uV) 554 + return 0; 555 + 556 + ramp_reg = rdev->desc->ramp_reg; 557 + if (old_uV > new_uV) 558 + /* The downwards ramp is at a different offset. */ 559 + ramp_reg += S2MPG10_PMIC_DVS_RAMP4 - S2MPG10_PMIC_DVS_RAMP1; 560 + 561 + ret = regmap_read(rdev->regmap, ramp_reg, &ramp_sel); 562 + if (ret) 563 + return ret; 564 + 565 + ramp_sel &= rdev->desc->ramp_mask; 566 + ramp_sel >>= ffs(rdev->desc->ramp_mask) - 1; 567 + if (ramp_sel >= rdev->desc->n_ramp_values || 568 + !rdev->desc->ramp_delay_table) 569 + return -EINVAL; 570 + 571 + ramp_rate = rdev->desc->ramp_delay_table[ramp_sel]; 572 + 573 + return DIV_ROUND_UP(abs(new_uV - old_uV), ramp_rate); 574 + } 575 + 576 + /* 577 + * We assign both, ::set_voltage_time() and ::set_voltage_time_sel(), because 578 + * only if the latter is != NULL, the regulator core will call neither during 579 + * DVS if the regulator is disabled. If the latter is NULL, the core always 580 + * calls the ::set_voltage_time() callback, which would give incorrect results 581 + * if the regulator is off. 582 + * At the same time, we do need ::set_voltage_time() due to differing upwards 583 + * and downwards ramps and we can not make that code dependent on the regulator 584 + * enable state, as that would break regulator_set_voltage_time() which 585 + * expects a correct result no matter the enable state. 586 + */ 587 + static const struct regulator_ops s2mpg10_reg_buck_ops[] = { 588 + [S2MPG10_REGULATOR_OPS_STD] = { 589 + .list_voltage = regulator_list_voltage_linear_range, 590 + .map_voltage = regulator_map_voltage_linear_range, 591 + .is_enabled = regulator_is_enabled_regmap, 592 + .enable = regulator_enable_regmap, 593 + .disable = regulator_disable_regmap, 594 + .enable_time = s2mpg10_regulator_buck_enable_time, 595 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 596 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 597 + .set_voltage_time = s2mpg10_regulator_buck_set_voltage_time, 598 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 599 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 600 + }, 601 + [S2MPG10_REGULATOR_OPS_EXTCONTROL] = { 602 + .list_voltage = regulator_list_voltage_linear_range, 603 + .map_voltage = regulator_map_voltage_linear_range, 604 + .enable = s2mpg10_regulator_enable_nop, 605 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 606 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 607 + .set_voltage_time = s2mpg10_regulator_buck_set_voltage_time, 608 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 609 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 610 + } 611 + }; 612 + 613 + #define s2mpg10_buck_to_ramp_mask(n) (GENMASK(1, 0) << (((n) % 4) * 2)) 614 + 615 + /* 616 + * The ramp_delay during enable is fixed (12.5mV/μs), while the ramp during 617 + * DVS can be adjusted. Linux can adjust the ramp delay via DT, in which case 618 + * the regulator core will modify the regulator's constraints and call our 619 + * .set_ramp_delay() which updates the DVS ramp in ramp_reg. 620 + * For enable, our .enable_time() unconditionally uses enable_ramp_rate 621 + * (12.5mV/μs) while our ::set_voltage_time() takes the value in ramp_reg 622 + * into account. 623 + */ 624 + #define regulator_desc_s2mpg10_buck(_num, _vrange, _r_reg) { \ 625 + .name = "buck"#_num "m", \ 626 + .supply_name = "vinb"#_num "m", \ 627 + .of_match = of_match_ptr("buck"#_num "m"), \ 628 + .regulators_node = of_match_ptr("regulators"), \ 629 + .of_parse_cb = s2mpg10_of_parse_cb, \ 630 + .id = S2MPG10_BUCK##_num, \ 631 + .ops = &s2mpg10_reg_buck_ops[0], \ 632 + .type = REGULATOR_VOLTAGE, \ 633 + .owner = THIS_MODULE, \ 634 + .linear_ranges = _vrange, \ 635 + .n_linear_ranges = ARRAY_SIZE(_vrange), \ 636 + .n_voltages = _vrange##_count, \ 637 + .vsel_reg = S2MPG10_PMIC_B##_num##M_OUT1, \ 638 + .vsel_mask = 0xff, \ 639 + .enable_reg = S2MPG10_PMIC_B##_num##M_CTRL, \ 640 + .enable_mask = GENMASK(7, 6), \ 641 + .ramp_reg = S2MPG10_PMIC_##_r_reg, \ 642 + .ramp_mask = s2mpg10_buck_to_ramp_mask(S2MPG10_BUCK##_num \ 643 + - S2MPG10_BUCK1), \ 644 + .ramp_delay_table = s2mpg10_buck_ramp_table, \ 645 + .n_ramp_values = ARRAY_SIZE(s2mpg10_buck_ramp_table), \ 646 + .enable_time = 30, /* + V/enable_ramp_rate */ \ 647 + } 648 + 649 + #define s2mpg10_regulator_desc_buck_cm(_num, _vrange, _r_reg) \ 650 + .desc = regulator_desc_s2mpg10_buck(_num, _vrange, _r_reg), \ 651 + .enable_ramp_rate = 12500 652 + 653 + #define s2mpg10_regulator_desc_buck_gpio(_num, _vrange, _r_reg, \ 654 + _pc_reg, _pc_mask) \ 655 + [S2MPG10_BUCK##_num] = { \ 656 + s2mpg10_regulator_desc_buck_cm(_num, _vrange, _r_reg), \ 657 + .pctrlsel_reg = S2MPG10_PMIC_##_pc_reg, \ 658 + .pctrlsel_mask = _pc_mask, \ 659 + } 660 + 661 + #define s2mpg10_regulator_desc_buck(_num, _vrange, _r_reg) \ 662 + [S2MPG10_BUCK##_num] = { \ 663 + s2mpg10_regulator_desc_buck_cm(_num, _vrange, _r_reg), \ 664 + } 665 + 666 + /* ops for S2MPG1x LDO regulators without ramp control */ 667 + static const struct regulator_ops s2mpg10_reg_ldo_ops[] = { 668 + [S2MPG10_REGULATOR_OPS_STD] = { 669 + .list_voltage = regulator_list_voltage_linear_range, 670 + .map_voltage = regulator_map_voltage_linear_range, 671 + .is_enabled = regulator_is_enabled_regmap, 672 + .enable = regulator_enable_regmap, 673 + .disable = regulator_disable_regmap, 674 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 675 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 676 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 677 + }, 678 + [S2MPG10_REGULATOR_OPS_EXTCONTROL] = { 679 + .list_voltage = regulator_list_voltage_linear_range, 680 + .map_voltage = regulator_map_voltage_linear_range, 681 + .enable = s2mpg10_regulator_enable_nop, 682 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 683 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 684 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 685 + } 686 + }; 687 + 688 + /* ops for S2MPG1x LDO regulators that have ramp control */ 689 + static const struct regulator_ops s2mpg10_reg_ldo_ramp_ops[] = { 690 + [S2MPG10_REGULATOR_OPS_STD] = { 691 + .list_voltage = regulator_list_voltage_linear_range, 692 + .map_voltage = regulator_map_voltage_linear_range, 693 + .is_enabled = regulator_is_enabled_regmap, 694 + .enable = regulator_enable_regmap, 695 + .disable = regulator_disable_regmap, 696 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 697 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 698 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 699 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 700 + }, 701 + [S2MPG10_REGULATOR_OPS_EXTCONTROL] = { 702 + .list_voltage = regulator_list_voltage_linear_range, 703 + .map_voltage = regulator_map_voltage_linear_range, 704 + .enable = s2mpg10_regulator_enable_nop, 705 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 706 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 707 + .set_voltage_time_sel = regulator_set_voltage_time_sel, 708 + .set_ramp_delay = regulator_set_ramp_delay_regmap, 709 + } 710 + }; 711 + 712 + #define regulator_desc_s2mpg10_ldo_cmn(_num, _supply, _ops, _vrange, \ 713 + _vsel_reg_sfx, _vsel_mask, _en_reg, _en_mask, \ 714 + _ramp_delay, _r_reg, _r_mask, _r_table, _r_table_sz) { \ 715 + .name = "ldo"#_num "m", \ 716 + .supply_name = _supply, \ 717 + .of_match = of_match_ptr("ldo"#_num "m"), \ 718 + .regulators_node = of_match_ptr("regulators"), \ 719 + .of_parse_cb = s2mpg10_of_parse_cb, \ 720 + .id = S2MPG10_LDO##_num, \ 721 + .ops = &(_ops)[0], \ 722 + .type = REGULATOR_VOLTAGE, \ 723 + .owner = THIS_MODULE, \ 724 + .linear_ranges = _vrange, \ 725 + .n_linear_ranges = ARRAY_SIZE(_vrange), \ 726 + .n_voltages = _vrange##_count, \ 727 + .vsel_reg = S2MPG10_PMIC_L##_num##M_##_vsel_reg_sfx, \ 728 + .vsel_mask = _vsel_mask, \ 729 + .enable_reg = S2MPG10_PMIC_##_en_reg, \ 730 + .enable_mask = _en_mask, \ 731 + .ramp_delay = _ramp_delay, \ 732 + .ramp_reg = _r_reg, \ 733 + .ramp_mask = _r_mask, \ 734 + .ramp_delay_table = _r_table, \ 735 + .n_ramp_values = _r_table_sz, \ 736 + .enable_time = 130, /* startup 20+-10 + ramp 30..100μs */ \ 737 + } 738 + 739 + #define s2mpg10_regulator_desc_ldo_cmn(_num, _supply, _ops, _vrange, \ 740 + _vsel_reg_sfx, _vsel_mask, _en_reg, _en_mask, \ 741 + _ramp_delay, _r_reg, _r_mask, _r_table, _r_table_sz, \ 742 + _pc_reg, _pc_mask) \ 743 + [S2MPG10_LDO##_num] = { \ 744 + .desc = regulator_desc_s2mpg10_ldo_cmn(_num, _supply, \ 745 + _ops, \ 746 + _vrange, _vsel_reg_sfx, _vsel_mask, \ 747 + _en_reg, _en_mask, \ 748 + _ramp_delay, _r_reg, _r_mask, _r_table, \ 749 + _r_table_sz), \ 750 + .pctrlsel_reg = _pc_reg, \ 751 + .pctrlsel_mask = _pc_mask, \ 752 + } 753 + 754 + /* standard LDO via LxM_CTRL */ 755 + #define s2mpg10_regulator_desc_ldo(_num, _supply, _vrange) \ 756 + s2mpg10_regulator_desc_ldo_cmn(_num, _supply, \ 757 + s2mpg10_reg_ldo_ops, _vrange, CTRL, GENMASK(5, 0), \ 758 + L##_num##M_CTRL, BIT(7), \ 759 + 0, 0, 0, NULL, 0, \ 760 + 0, 0) 761 + 762 + /* standard LDO but possibly GPIO controlled */ 763 + #define s2mpg10_regulator_desc_ldo_gpio(_num, _supply, _vrange, \ 764 + _pc_reg, _pc_mask) \ 765 + s2mpg10_regulator_desc_ldo_cmn(_num, _supply, \ 766 + s2mpg10_reg_ldo_ops, _vrange, CTRL, GENMASK(5, 0), \ 767 + L##_num##M_CTRL, GENMASK(7, 6), \ 768 + 0, 0, 0, NULL, 0, \ 769 + S2MPG10_PMIC_##_pc_reg, _pc_mask) 770 + 771 + /* LDO with ramp support and possibly GPIO controlled */ 772 + #define s2mpg10_regulator_desc_ldo_ramp(_num, _supply, _vrange, \ 773 + _en_mask, _r_reg, _pc_reg, _pc_mask) \ 774 + s2mpg10_regulator_desc_ldo_cmn(_num, _supply, \ 775 + s2mpg10_reg_ldo_ramp_ops, _vrange, CTRL1, GENMASK(6, 0), \ 776 + LDO_CTRL2, _en_mask, \ 777 + 6250, S2MPG10_PMIC_##_r_reg, GENMASK(1, 0), \ 778 + s2mpg10_ldo_ramp_table, \ 779 + ARRAY_SIZE(s2mpg10_ldo_ramp_table), \ 780 + S2MPG10_PMIC_##_pc_reg, _pc_mask) 781 + 782 + #define S2MPG10_VOLTAGE_RANGE(_prefix, _idx, _offs_uV, _min_uV, \ 783 + _max_uV, _step_uV) \ 784 + static const struct linear_range _prefix##_vranges##_idx[] = { \ 785 + REGULATOR_LINEAR_VRANGE(_offs_uV, _min_uV, _max_uV, _step_uV) \ 786 + }; \ 787 + static const unsigned int _prefix##_vranges##_idx##_count = \ 788 + ((((_max_uV) - (_offs_uV)) / (_step_uV)) + 1) 789 + 790 + /* voltage range for s2mpg10 BUCK 1, 2, 3, 4, 5, 7, 8, 9, 10 */ 791 + S2MPG10_VOLTAGE_RANGE(s2mpg10_buck, 1, 200000, 450000, 1300000, STEP_6_25_MV); 792 + 793 + /* voltage range for s2mpg10 BUCK 6 */ 794 + S2MPG10_VOLTAGE_RANGE(s2mpg10_buck, 6, 200000, 450000, 1350000, STEP_6_25_MV); 795 + 796 + static const unsigned int s2mpg10_buck_ramp_table[] = { 797 + 6250, 12500, 25000 798 + }; 799 + 800 + /* voltage range for s2mpg10 LDO 1, 11, 12 */ 801 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 1, 300000, 700000, 1300000, STEP_12_5_MV); 802 + 803 + /* voltage range for s2mpg10 LDO 2, 4, 9, 14, 18, 19, 20, 23, 25, 29, 30, 31 */ 804 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 2, 700000, 1600000, 1950000, STEP_25_MV); 805 + 806 + /* voltage range for s2mpg10 LDO 3, 5, 6, 8, 16, 17, 24, 28 */ 807 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 3, 725000, 725000, 1300000, STEP_12_5_MV); 808 + 809 + /* voltage range for s2mpg10 LDO 7 */ 810 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 7, 300000, 450000, 1300000, STEP_12_5_MV); 811 + 812 + /* voltage range for s2mpg10 LDO 13, 15 */ 813 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 13, 300000, 450000, 950000, STEP_12_5_MV); 814 + 815 + /* voltage range for s2mpg10 LDO 10 */ 816 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 10, 1800000, 1800000, 3350000, STEP_25_MV); 817 + 818 + /* voltage range for s2mpg10 LDO 21, 22, 26, 27 */ 819 + S2MPG10_VOLTAGE_RANGE(s2mpg10_ldo, 21, 1800000, 2500000, 3300000, STEP_25_MV); 820 + 821 + /* possible ramp values for s2mpg10 LDO 1, 7, 11, 12, 13, 15 */ 822 + static const unsigned int s2mpg10_ldo_ramp_table[] = { 823 + 6250, 12500 824 + }; 825 + 826 + static const struct s2mpg10_regulator_desc s2mpg10_regulators[] = { 827 + s2mpg10_regulator_desc_buck_gpio(1, s2mpg10_buck_vranges1, DVS_RAMP1, 828 + PCTRLSEL1, GENMASK(3, 0)), 829 + s2mpg10_regulator_desc_buck_gpio(2, s2mpg10_buck_vranges1, DVS_RAMP1, 830 + PCTRLSEL1, GENMASK(7, 4)), 831 + s2mpg10_regulator_desc_buck_gpio(3, s2mpg10_buck_vranges1, DVS_RAMP1, 832 + PCTRLSEL2, GENMASK(3, 0)), 833 + s2mpg10_regulator_desc_buck_gpio(4, s2mpg10_buck_vranges1, DVS_RAMP1, 834 + PCTRLSEL2, GENMASK(7, 4)), 835 + s2mpg10_regulator_desc_buck_gpio(5, s2mpg10_buck_vranges1, DVS_RAMP2, 836 + PCTRLSEL3, GENMASK(3, 0)), 837 + s2mpg10_regulator_desc_buck_gpio(6, s2mpg10_buck_vranges6, DVS_RAMP2, 838 + PCTRLSEL3, GENMASK(7, 4)), 839 + s2mpg10_regulator_desc_buck_gpio(7, s2mpg10_buck_vranges1, DVS_RAMP2, 840 + PCTRLSEL4, GENMASK(3, 0)), 841 + s2mpg10_regulator_desc_buck(8, s2mpg10_buck_vranges1, DVS_RAMP2), 842 + s2mpg10_regulator_desc_buck(9, s2mpg10_buck_vranges1, DVS_RAMP3), 843 + s2mpg10_regulator_desc_buck_gpio(10, s2mpg10_buck_vranges1, DVS_RAMP3, 844 + PCTRLSEL4, GENMASK(7, 4)), 845 + /* 846 + * Standard LDO via LxM_CTRL but non-standard (greater) V-range and with 847 + * ramp support. 848 + */ 849 + s2mpg10_regulator_desc_ldo_cmn(1, "vinl3m", s2mpg10_reg_ldo_ramp_ops, 850 + s2mpg10_ldo_vranges1, 851 + CTRL, GENMASK(6, 0), 852 + L1M_CTRL, BIT(7), 853 + 6250, S2MPG10_PMIC_DVS_RAMP6, 854 + GENMASK(5, 4), s2mpg10_ldo_ramp_table, 855 + ARRAY_SIZE(s2mpg10_ldo_ramp_table), 856 + 0, 0), 857 + s2mpg10_regulator_desc_ldo(2, "vinl9m", s2mpg10_ldo_vranges2), 858 + s2mpg10_regulator_desc_ldo_gpio(3, "vinl4m", s2mpg10_ldo_vranges3, 859 + PCTRLSEL5, GENMASK(3, 0)), 860 + s2mpg10_regulator_desc_ldo_gpio(4, "vinl9m", s2mpg10_ldo_vranges2, 861 + PCTRLSEL5, GENMASK(7, 4)), 862 + s2mpg10_regulator_desc_ldo_gpio(5, "vinl3m", s2mpg10_ldo_vranges3, 863 + PCTRLSEL6, GENMASK(3, 0)), 864 + s2mpg10_regulator_desc_ldo_gpio(6, "vinl7m", s2mpg10_ldo_vranges3, 865 + PCTRLSEL6, GENMASK(7, 4)), 866 + /* 867 + * Ramp support, possibly GPIO controlled, non-standard (greater) V- 868 + * range and enable reg & mask. 869 + */ 870 + s2mpg10_regulator_desc_ldo_cmn(7, "vinl3m", s2mpg10_reg_ldo_ramp_ops, 871 + s2mpg10_ldo_vranges7, 872 + CTRL, GENMASK(6, 0), 873 + LDO_CTRL1, GENMASK(4, 3), 874 + 6250, S2MPG10_PMIC_DVS_RAMP6, 875 + GENMASK(7, 6), s2mpg10_ldo_ramp_table, 876 + ARRAY_SIZE(s2mpg10_ldo_ramp_table), 877 + S2MPG10_PMIC_PCTRLSEL7, GENMASK(3, 0)), 878 + s2mpg10_regulator_desc_ldo_gpio(8, "vinl4m", s2mpg10_ldo_vranges3, 879 + PCTRLSEL7, GENMASK(7, 4)), 880 + s2mpg10_regulator_desc_ldo_gpio(9, "vinl10m", s2mpg10_ldo_vranges2, 881 + PCTRLSEL8, GENMASK(3, 0)), 882 + s2mpg10_regulator_desc_ldo_gpio(10, "vinl15m", s2mpg10_ldo_vranges10, 883 + PCTRLSEL8, GENMASK(7, 4)), 884 + s2mpg10_regulator_desc_ldo_ramp(11, "vinl7m", s2mpg10_ldo_vranges1, 885 + GENMASK(1, 0), DVS_SYNC_CTRL3, 886 + PCTRLSEL9, GENMASK(3, 0)), 887 + s2mpg10_regulator_desc_ldo_ramp(12, "vinl8m", s2mpg10_ldo_vranges1, 888 + GENMASK(3, 2), DVS_SYNC_CTRL4, 889 + PCTRLSEL9, GENMASK(7, 4)), 890 + s2mpg10_regulator_desc_ldo_ramp(13, "vinl1m", s2mpg10_ldo_vranges13, 891 + GENMASK(5, 4), DVS_SYNC_CTRL5, 892 + PCTRLSEL10, GENMASK(3, 0)), 893 + s2mpg10_regulator_desc_ldo_gpio(14, "vinl10m", s2mpg10_ldo_vranges2, 894 + PCTRLSEL10, GENMASK(7, 4)), 895 + s2mpg10_regulator_desc_ldo_ramp(15, "vinl2m", s2mpg10_ldo_vranges13, 896 + GENMASK(7, 6), DVS_SYNC_CTRL6, 897 + PCTRLSEL11, GENMASK(3, 0)), 898 + s2mpg10_regulator_desc_ldo_gpio(16, "vinl5m", s2mpg10_ldo_vranges3, 899 + PCTRLSEL11, GENMASK(7, 4)), 900 + s2mpg10_regulator_desc_ldo_gpio(17, "vinl6m", s2mpg10_ldo_vranges3, 901 + PCTRLSEL12, GENMASK(3, 0)), 902 + s2mpg10_regulator_desc_ldo_gpio(18, "vinl10m", s2mpg10_ldo_vranges2, 903 + PCTRLSEL12, GENMASK(7, 4)), 904 + s2mpg10_regulator_desc_ldo_gpio(19, "vinl10m", s2mpg10_ldo_vranges2, 905 + PCTRLSEL13, GENMASK(3, 0)), 906 + s2mpg10_regulator_desc_ldo_gpio(20, "vinl10m", s2mpg10_ldo_vranges2, 907 + PCTRLSEL13, GENMASK(7, 4)), 908 + s2mpg10_regulator_desc_ldo(21, "vinl14m", s2mpg10_ldo_vranges21), 909 + s2mpg10_regulator_desc_ldo(22, "vinl15m", s2mpg10_ldo_vranges21), 910 + s2mpg10_regulator_desc_ldo(23, "vinl11m", s2mpg10_ldo_vranges2), 911 + s2mpg10_regulator_desc_ldo(24, "vinl7m", s2mpg10_ldo_vranges3), 912 + s2mpg10_regulator_desc_ldo(25, "vinl10m", s2mpg10_ldo_vranges2), 913 + s2mpg10_regulator_desc_ldo(26, "vinl15m", s2mpg10_ldo_vranges21), 914 + s2mpg10_regulator_desc_ldo(27, "vinl15m", s2mpg10_ldo_vranges21), 915 + s2mpg10_regulator_desc_ldo(28, "vinl7m", s2mpg10_ldo_vranges3), 916 + s2mpg10_regulator_desc_ldo(29, "vinl12m", s2mpg10_ldo_vranges2), 917 + s2mpg10_regulator_desc_ldo(30, "vinl13m", s2mpg10_ldo_vranges2), 918 + s2mpg10_regulator_desc_ldo(31, "vinl11m", s2mpg10_ldo_vranges2) 919 + }; 418 920 419 921 static const struct regulator_ops s2mps11_ldo_ops = { 420 922 .list_voltage = regulator_list_voltage_linear, ··· 1823 1277 ret = s2mps14_pmic_enable_ext_control(s2mps11, rdev); 1824 1278 break; 1825 1279 1280 + case S2MPG10: 1281 + /* 1282 + * If desc.enable_val is != 0, then external control was 1283 + * requested. We can not test s2mpg10_desc::ext_control, 1284 + * because 0 is a valid value. 1285 + */ 1286 + if (!rdev->desc->enable_val) 1287 + return 0; 1288 + 1289 + ret = s2mpg10_enable_ext_control(s2mps11, rdev); 1290 + break; 1291 + 1826 1292 default: 1827 1293 return 0; 1828 1294 } ··· 1850 1292 unsigned int rdev_num; 1851 1293 int i, ret; 1852 1294 const struct regulator_desc *regulators; 1295 + const struct s2mpg10_regulator_desc *s2mpg1x_regulators = NULL; 1853 1296 1854 1297 s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), 1855 1298 GFP_KERNEL); ··· 1859 1300 1860 1301 s2mps11->dev_type = platform_get_device_id(pdev)->driver_data; 1861 1302 switch (s2mps11->dev_type) { 1303 + case S2MPG10: 1304 + rdev_num = ARRAY_SIZE(s2mpg10_regulators); 1305 + s2mpg1x_regulators = s2mpg10_regulators; 1306 + BUILD_BUG_ON(ARRAY_SIZE(s2mpg10_regulators) > S2MPS_REGULATOR_MAX); 1307 + break; 1862 1308 case S2MPS11X: 1863 1309 rdev_num = ARRAY_SIZE(s2mps11_regulators); 1864 1310 regulators = s2mps11_regulators; ··· 1900 1336 s2mps11->dev_type); 1901 1337 } 1902 1338 1339 + if (s2mpg1x_regulators) { 1340 + size_t regulators_sz = rdev_num * sizeof(*s2mpg1x_regulators); 1341 + 1342 + s2mpg1x_regulators = devm_kmemdup(&pdev->dev, 1343 + s2mpg1x_regulators, 1344 + regulators_sz, 1345 + GFP_KERNEL); 1346 + if (!s2mpg1x_regulators) 1347 + return -ENOMEM; 1348 + } 1349 + 1903 1350 device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); 1904 1351 1905 1352 platform_set_drvdata(pdev, s2mps11); ··· 1919 1344 config.regmap = iodev->regmap_pmic; 1920 1345 config.driver_data = s2mps11; 1921 1346 for (i = 0; i < rdev_num; i++) { 1347 + const struct regulator_desc *rdesc; 1922 1348 struct regulator_dev *regulator; 1923 1349 1350 + if (s2mpg1x_regulators) 1351 + rdesc = &s2mpg1x_regulators[i].desc; 1352 + else 1353 + rdesc = &regulators[i]; 1354 + 1924 1355 regulator = devm_regulator_register(&pdev->dev, 1925 - &regulators[i], &config); 1356 + rdesc, &config); 1926 1357 if (IS_ERR(regulator)) 1927 1358 return dev_err_probe(&pdev->dev, PTR_ERR(regulator), 1928 1359 "regulator init failed for %d/%s\n", 1929 - regulators[i].id, 1930 - regulators[i].name); 1360 + rdesc->id, rdesc->name); 1931 1361 1932 1362 ret = s2mps11_handle_ext_control(s2mps11, regulator); 1933 1363 if (ret < 0) ··· 1943 1363 } 1944 1364 1945 1365 static const struct platform_device_id s2mps11_pmic_id[] = { 1366 + { "s2mpg10-regulator", S2MPG10}, 1946 1367 { "s2mps11-regulator", S2MPS11X}, 1947 1368 { "s2mps13-regulator", S2MPS13X}, 1948 1369 { "s2mps14-regulator", S2MPS14X},
+24
include/linux/mfd/samsung/s2mpg10.h
··· 290 290 S2MPG10_PMIC_LDO_SENSE4, 291 291 }; 292 292 293 + /* Rail controlled externally, based on PCTRLSELx */ 294 + #define S2MPG10_PMIC_CTRL_ENABLE_EXT BIT(0) 295 + 296 + /* For S2MPG10_PMIC_PCTRLSELx */ 297 + #define S2MPG10_PCTRLSEL_PWREN 0x1 /* PWREN pin */ 298 + #define S2MPG10_PCTRLSEL_PWREN_TRG 0x2 /* PWREN_TRG bit in MIMICKING_CTRL */ 299 + #define S2MPG10_PCTRLSEL_PWREN_MIF 0x3 /* PWREN_MIF pin */ 300 + #define S2MPG10_PCTRLSEL_PWREN_MIF_TRG 0x4 /* PWREN_MIF_TRG bit in MIMICKING_CTRL */ 301 + #define S2MPG10_PCTRLSEL_AP_ACTIVE_N 0x5 /* ~AP_ACTIVE_N pin */ 302 + #define S2MPG10_PCTRLSEL_AP_ACTIVE_N_TRG 0x6 /* ~AP_ACTIVE_N_TRG bit in MIMICKING_CTRL */ 303 + #define S2MPG10_PCTRLSEL_CPUCL1_EN 0x7 /* CPUCL1_EN pin */ 304 + #define S2MPG10_PCTRLSEL_CPUCL1_EN2 0x8 /* CPUCL1_EN & PWREN pins */ 305 + #define S2MPG10_PCTRLSEL_CPUCL2_EN 0x9 /* CPUCL2_EN pin */ 306 + #define S2MPG10_PCTRLSEL_CPUCL2_EN2 0xa /* CPUCL2_E2 & PWREN pins */ 307 + #define S2MPG10_PCTRLSEL_TPU_EN 0xb /* TPU_EN pin */ 308 + #define S2MPG10_PCTRLSEL_TPU_EN2 0xc /* TPU_EN & ~AP_ACTIVE_N pins */ 309 + #define S2MPG10_PCTRLSEL_TCXO_ON 0xd /* TCXO_ON pin */ 310 + #define S2MPG10_PCTRLSEL_TCXO_ON2 0xe /* TCXO_ON & ~AP_ACTIVE_N pins */ 311 + 312 + /* For S2MPG10_PMIC_PCTRLSELx of LDO20M */ 313 + #define S2MPG10_PCTRLSEL_LDO20M_EN2 0x1 /* VLDO20M_EN & LDO20M_SFR */ 314 + #define S2MPG10_PCTRLSEL_LDO20M_EN 0x2 /* VLDO20M_EN pin */ 315 + #define S2MPG10_PCTRLSEL_LDO20M_SFR 0x3 /* LDO20M_SFR bit in LDO_CTRL1 register */ 316 + 293 317 /* Meter registers (type 0xa00) */ 294 318 enum s2mpg10_meter_reg { 295 319 S2MPG10_METER_CTRL1,