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

Merge remote-tracking branch 'regulator/topic/palmas' into regulator-next

+168 -10
+9 -3
Documentation/devicetree/bindings/regulator/palmas-pmic.txt
··· 26 26 27 27 For ti,palmas-pmic - smps12, smps123, smps3 depending on OTP, 28 28 smps45, smps457, smps7 depending on variant, smps6, smps[8-9], 29 - smps10_out2, smps10_out1, do[1-9], ldoln, ldousb. 29 + smps10_out2, smps10_out1, ldo[1-9], ldoln, ldousb. 30 30 31 31 Optional sub-node properties: 32 32 ti,warm-reset - maintain voltage during warm reset(boolean) 33 - ti,roof-floor - control voltage selection by pin(boolean) 33 + ti,roof-floor - This takes as optional argument on platform supporting 34 + the rail from desired external control. If there is no argument then 35 + it will be assume that it is controlled by NSLEEP pin. 36 + The valid value for external pins are: 37 + ENABLE1 then 1, 38 + ENABLE2 then 2 or 39 + NSLEEP then 3. 34 40 ti,mode-sleep - mode to adopt in pmic sleep 0 - off, 1 - auto, 35 41 2 - eco, 3 - forced pwm 36 42 ti,smps-range - OTP has the wrong range set for the hardware so override ··· 67 61 regulator-always-on; 68 62 regulator-boot-on; 69 63 ti,warm-reset; 70 - ti,roof-floor; 64 + ti,roof-floor = <1>; /* ENABLE1 control */ 71 65 ti,mode-sleep = <0>; 72 66 ti,smps-range = <1>; 73 67 };
+159 -7
drivers/regulator/palmas-regulator.c
··· 33 33 u8 vsel_addr; 34 34 u8 ctrl_addr; 35 35 u8 tstep_addr; 36 + int sleep_id; 36 37 }; 37 38 38 39 static const struct regs_info palmas_regs_info[] = { ··· 43 42 .vsel_addr = PALMAS_SMPS12_VOLTAGE, 44 43 .ctrl_addr = PALMAS_SMPS12_CTRL, 45 44 .tstep_addr = PALMAS_SMPS12_TSTEP, 45 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12, 46 46 }, 47 47 { 48 48 .name = "SMPS123", ··· 51 49 .vsel_addr = PALMAS_SMPS12_VOLTAGE, 52 50 .ctrl_addr = PALMAS_SMPS12_CTRL, 53 51 .tstep_addr = PALMAS_SMPS12_TSTEP, 52 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12, 54 53 }, 55 54 { 56 55 .name = "SMPS3", 57 56 .sname = "smps3-in", 58 57 .vsel_addr = PALMAS_SMPS3_VOLTAGE, 59 58 .ctrl_addr = PALMAS_SMPS3_CTRL, 59 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS3, 60 60 }, 61 61 { 62 62 .name = "SMPS45", ··· 66 62 .vsel_addr = PALMAS_SMPS45_VOLTAGE, 67 63 .ctrl_addr = PALMAS_SMPS45_CTRL, 68 64 .tstep_addr = PALMAS_SMPS45_TSTEP, 65 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45, 69 66 }, 70 67 { 71 68 .name = "SMPS457", ··· 74 69 .vsel_addr = PALMAS_SMPS45_VOLTAGE, 75 70 .ctrl_addr = PALMAS_SMPS45_CTRL, 76 71 .tstep_addr = PALMAS_SMPS45_TSTEP, 72 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45, 77 73 }, 78 74 { 79 75 .name = "SMPS6", ··· 82 76 .vsel_addr = PALMAS_SMPS6_VOLTAGE, 83 77 .ctrl_addr = PALMAS_SMPS6_CTRL, 84 78 .tstep_addr = PALMAS_SMPS6_TSTEP, 79 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS6, 85 80 }, 86 81 { 87 82 .name = "SMPS7", 88 83 .sname = "smps7-in", 89 84 .vsel_addr = PALMAS_SMPS7_VOLTAGE, 90 85 .ctrl_addr = PALMAS_SMPS7_CTRL, 86 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS7, 91 87 }, 92 88 { 93 89 .name = "SMPS8", ··· 97 89 .vsel_addr = PALMAS_SMPS8_VOLTAGE, 98 90 .ctrl_addr = PALMAS_SMPS8_CTRL, 99 91 .tstep_addr = PALMAS_SMPS8_TSTEP, 92 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS8, 100 93 }, 101 94 { 102 95 .name = "SMPS9", 103 96 .sname = "smps9-in", 104 97 .vsel_addr = PALMAS_SMPS9_VOLTAGE, 105 98 .ctrl_addr = PALMAS_SMPS9_CTRL, 99 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS9, 106 100 }, 107 101 { 108 102 .name = "SMPS10_OUT2", 109 103 .sname = "smps10-in", 110 104 .ctrl_addr = PALMAS_SMPS10_CTRL, 105 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10, 111 106 }, 112 107 { 113 108 .name = "SMPS10_OUT1", 114 109 .sname = "smps10-out2", 115 110 .ctrl_addr = PALMAS_SMPS10_CTRL, 111 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10, 116 112 }, 117 113 { 118 114 .name = "LDO1", 119 115 .sname = "ldo1-in", 120 116 .vsel_addr = PALMAS_LDO1_VOLTAGE, 121 117 .ctrl_addr = PALMAS_LDO1_CTRL, 118 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO1, 122 119 }, 123 120 { 124 121 .name = "LDO2", 125 122 .sname = "ldo2-in", 126 123 .vsel_addr = PALMAS_LDO2_VOLTAGE, 127 124 .ctrl_addr = PALMAS_LDO2_CTRL, 125 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO2, 128 126 }, 129 127 { 130 128 .name = "LDO3", 131 129 .sname = "ldo3-in", 132 130 .vsel_addr = PALMAS_LDO3_VOLTAGE, 133 131 .ctrl_addr = PALMAS_LDO3_CTRL, 132 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO3, 134 133 }, 135 134 { 136 135 .name = "LDO4", 137 136 .sname = "ldo4-in", 138 137 .vsel_addr = PALMAS_LDO4_VOLTAGE, 139 138 .ctrl_addr = PALMAS_LDO4_CTRL, 139 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO4, 140 140 }, 141 141 { 142 142 .name = "LDO5", 143 143 .sname = "ldo5-in", 144 144 .vsel_addr = PALMAS_LDO5_VOLTAGE, 145 145 .ctrl_addr = PALMAS_LDO5_CTRL, 146 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO5, 146 147 }, 147 148 { 148 149 .name = "LDO6", 149 150 .sname = "ldo6-in", 150 151 .vsel_addr = PALMAS_LDO6_VOLTAGE, 151 152 .ctrl_addr = PALMAS_LDO6_CTRL, 153 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO6, 152 154 }, 153 155 { 154 156 .name = "LDO7", 155 157 .sname = "ldo7-in", 156 158 .vsel_addr = PALMAS_LDO7_VOLTAGE, 157 159 .ctrl_addr = PALMAS_LDO7_CTRL, 160 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO7, 158 161 }, 159 162 { 160 163 .name = "LDO8", 161 164 .sname = "ldo8-in", 162 165 .vsel_addr = PALMAS_LDO8_VOLTAGE, 163 166 .ctrl_addr = PALMAS_LDO8_CTRL, 167 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO8, 164 168 }, 165 169 { 166 170 .name = "LDO9", 167 171 .sname = "ldo9-in", 168 172 .vsel_addr = PALMAS_LDO9_VOLTAGE, 169 173 .ctrl_addr = PALMAS_LDO9_CTRL, 174 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO9, 170 175 }, 171 176 { 172 177 .name = "LDOLN", 173 178 .sname = "ldoln-in", 174 179 .vsel_addr = PALMAS_LDOLN_VOLTAGE, 175 180 .ctrl_addr = PALMAS_LDOLN_CTRL, 181 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOLN, 176 182 }, 177 183 { 178 184 .name = "LDOUSB", 179 185 .sname = "ldousb-in", 180 186 .vsel_addr = PALMAS_LDOUSB_VOLTAGE, 181 187 .ctrl_addr = PALMAS_LDOUSB_CTRL, 188 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOUSB, 182 189 }, 183 190 { 184 191 .name = "REGEN1", 185 192 .ctrl_addr = PALMAS_REGEN1_CTRL, 193 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN1, 186 194 }, 187 195 { 188 196 .name = "REGEN2", 189 197 .ctrl_addr = PALMAS_REGEN2_CTRL, 198 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN2, 190 199 }, 191 200 { 192 201 .name = "REGEN3", 193 202 .ctrl_addr = PALMAS_REGEN3_CTRL, 203 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN3, 194 204 }, 195 205 { 196 206 .name = "SYSEN1", 197 207 .ctrl_addr = PALMAS_SYSEN1_CTRL, 208 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN1, 198 209 }, 199 210 { 200 211 .name = "SYSEN2", 201 212 .ctrl_addr = PALMAS_SYSEN2_CTRL, 213 + .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN2, 202 214 }, 203 215 }; 204 216 ··· 506 478 .set_ramp_delay = palmas_smps_set_ramp_delay, 507 479 }; 508 480 481 + static struct regulator_ops palmas_ops_ext_control_smps = { 482 + .set_mode = palmas_set_mode_smps, 483 + .get_mode = palmas_get_mode_smps, 484 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 485 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 486 + .list_voltage = palmas_list_voltage_smps, 487 + .map_voltage = palmas_map_voltage_smps, 488 + .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, 489 + .set_ramp_delay = palmas_smps_set_ramp_delay, 490 + }; 491 + 509 492 static struct regulator_ops palmas_ops_smps10 = { 510 493 .is_enabled = regulator_is_enabled_regmap, 511 494 .enable = regulator_enable_regmap, ··· 552 513 .map_voltage = regulator_map_voltage_linear, 553 514 }; 554 515 516 + static struct regulator_ops palmas_ops_ext_control_ldo = { 517 + .get_voltage_sel = regulator_get_voltage_sel_regmap, 518 + .set_voltage_sel = regulator_set_voltage_sel_regmap, 519 + .list_voltage = regulator_list_voltage_linear, 520 + .map_voltage = regulator_map_voltage_linear, 521 + }; 522 + 555 523 static struct regulator_ops palmas_ops_extreg = { 556 524 .is_enabled = regulator_is_enabled_regmap, 557 525 .enable = regulator_enable_regmap, 558 526 .disable = regulator_disable_regmap, 559 527 }; 528 + 529 + static struct regulator_ops palmas_ops_ext_control_extreg = { 530 + }; 531 + 532 + static int palmas_regulator_config_external(struct palmas *palmas, int id, 533 + struct palmas_reg_init *reg_init) 534 + { 535 + int sleep_id = palmas_regs_info[id].sleep_id; 536 + int ret; 537 + 538 + ret = palmas_ext_control_req_config(palmas, sleep_id, 539 + reg_init->roof_floor, true); 540 + if (ret < 0) 541 + dev_err(palmas->dev, 542 + "Ext control config for regulator %d failed %d\n", 543 + id, ret); 544 + return ret; 545 + } 560 546 561 547 /* 562 548 * setup the hardware based sleep configuration of the SMPS/LDO regulators ··· 641 577 return ret; 642 578 } 643 579 580 + if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) && 581 + (id != PALMAS_REG_SMPS10_OUT2)) { 582 + /* Enable externally controlled regulator */ 583 + addr = palmas_regs_info[id].ctrl_addr; 584 + ret = palmas_smps_read(palmas, addr, &reg); 585 + if (ret < 0) 586 + return ret; 644 587 588 + if (!(reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK)) { 589 + reg |= SMPS_CTRL_MODE_ON; 590 + ret = palmas_smps_write(palmas, addr, reg); 591 + if (ret < 0) 592 + return ret; 593 + } 594 + return palmas_regulator_config_external(palmas, id, reg_init); 595 + } 645 596 return 0; 646 597 } 647 598 ··· 687 608 if (ret) 688 609 return ret; 689 610 611 + if (reg_init->roof_floor) { 612 + /* Enable externally controlled regulator */ 613 + addr = palmas_regs_info[id].ctrl_addr; 614 + ret = palmas_update_bits(palmas, PALMAS_LDO_BASE, 615 + addr, PALMAS_LDO1_CTRL_MODE_ACTIVE, 616 + PALMAS_LDO1_CTRL_MODE_ACTIVE); 617 + if (ret < 0) { 618 + dev_err(palmas->dev, 619 + "LDO Register 0x%02x update failed %d\n", 620 + addr, ret); 621 + return ret; 622 + } 623 + return palmas_regulator_config_external(palmas, id, reg_init); 624 + } 690 625 return 0; 691 626 } 692 627 ··· 722 629 dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n", 723 630 addr, ret); 724 631 return ret; 632 + } 633 + 634 + if (reg_init->roof_floor) { 635 + /* Enable externally controlled regulator */ 636 + addr = palmas_regs_info[id].ctrl_addr; 637 + ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, 638 + addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE, 639 + PALMAS_REGEN1_CTRL_MODE_ACTIVE); 640 + if (ret < 0) { 641 + dev_err(palmas->dev, 642 + "Resource Register 0x%02x update failed %d\n", 643 + addr, ret); 644 + return ret; 645 + } 646 + return palmas_regulator_config_external(palmas, id, reg_init); 725 647 } 726 648 return 0; 727 649 } ··· 820 712 int idx, ret; 821 713 822 714 node = of_node_get(node); 823 - regulators = of_find_node_by_name(node, "regulators"); 715 + regulators = of_get_child_by_name(node, "regulators"); 824 716 if (!regulators) { 825 717 dev_info(dev, "regulator node not found\n"); 826 718 return; ··· 848 740 of_property_read_bool(palmas_matches[idx].of_node, 849 741 "ti,warm-reset"); 850 742 851 - pdata->reg_init[idx]->roof_floor = 852 - of_property_read_bool(palmas_matches[idx].of_node, 853 - "ti,roof-floor"); 743 + ret = of_property_read_u32(palmas_matches[idx].of_node, 744 + "ti,roof-floor", &prop); 745 + /* EINVAL: Property not found */ 746 + if (ret != -EINVAL) { 747 + int econtrol; 748 + 749 + /* use default value, when no value is specified */ 750 + econtrol = PALMAS_EXT_CONTROL_NSLEEP; 751 + if (!ret) { 752 + switch (prop) { 753 + case 1: 754 + econtrol = PALMAS_EXT_CONTROL_ENABLE1; 755 + break; 756 + case 2: 757 + econtrol = PALMAS_EXT_CONTROL_ENABLE2; 758 + break; 759 + case 3: 760 + econtrol = PALMAS_EXT_CONTROL_NSLEEP; 761 + break; 762 + default: 763 + WARN_ON(1); 764 + dev_warn(dev, 765 + "%s: Invalid roof-floor option: %u\n", 766 + palmas_matches[idx].name, prop); 767 + break; 768 + } 769 + } 770 + pdata->reg_init[idx]->roof_floor = econtrol; 771 + } 854 772 855 773 ret = of_property_read_u32(palmas_matches[idx].of_node, 856 774 "ti,mode-sleep", &prop); ··· 1003 869 ret = palmas_smps_init(palmas, id, reg_init); 1004 870 if (ret) 1005 871 return ret; 872 + } else { 873 + reg_init = NULL; 1006 874 } 1007 875 1008 876 /* Register the regulators */ ··· 1049 913 if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) 1050 914 pmic->range[id] = 1; 1051 915 1052 - pmic->desc[id].ops = &palmas_ops_smps; 916 + if (reg_init && reg_init->roof_floor) 917 + pmic->desc[id].ops = 918 + &palmas_ops_ext_control_smps; 919 + else 920 + pmic->desc[id].ops = &palmas_ops_smps; 1053 921 pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; 1054 922 pmic->desc[id].vsel_reg = 1055 923 PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, ··· 1096 956 1097 957 /* Start this loop from the id left from previous loop */ 1098 958 for (; id < PALMAS_NUM_REGS; id++) { 959 + if (pdata && pdata->reg_init[id]) 960 + reg_init = pdata->reg_init[id]; 961 + else 962 + reg_init = NULL; 1099 963 1100 964 /* Miss out regulators which are not available due 1101 965 * to alternate functions. ··· 1113 969 1114 970 if (id < PALMAS_REG_REGEN1) { 1115 971 pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; 1116 - pmic->desc[id].ops = &palmas_ops_ldo; 972 + if (reg_init && reg_init->roof_floor) 973 + pmic->desc[id].ops = 974 + &palmas_ops_ext_control_ldo; 975 + else 976 + pmic->desc[id].ops = &palmas_ops_ldo; 1117 977 pmic->desc[id].min_uV = 900000; 1118 978 pmic->desc[id].uV_step = 50000; 1119 979 pmic->desc[id].linear_min_sel = 1; ··· 1147 999 pmic->desc[id].enable_time = 2000; 1148 1000 } else { 1149 1001 pmic->desc[id].n_voltages = 1; 1150 - pmic->desc[id].ops = &palmas_ops_extreg; 1002 + if (reg_init && reg_init->roof_floor) 1003 + pmic->desc[id].ops = 1004 + &palmas_ops_ext_control_extreg; 1005 + else 1006 + pmic->desc[id].ops = &palmas_ops_extreg; 1151 1007 pmic->desc[id].enable_reg = 1152 1008 PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, 1153 1009 palmas_regs_info[id].ctrl_addr);