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

regulator: qcom-spmi: Add vendor specific configuration

Add support for over current protection (OCP), pin control
selection, soft start strength, and auto-mode.

Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Stephen Boyd and committed by
Mark Brown
e2adfacd 41dae91a

+251 -9
+56 -4
Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt
··· 91 91 - regulator-initial-mode: 92 92 Usage: optional 93 93 Value type: <u32> 94 - Descrption: 1 = Set initial mode to high power mode (HPM), also referred 95 - to as NPM. HPM consumes more ground current than LPM, but 94 + Description: 2 = Set initial mode to auto mode (automatically select 95 + between HPM and LPM); not available on boost type 96 + regulators. 97 + 98 + 1 = Set initial mode to high power mode (HPM), also referred 99 + to as NPM. HPM consumes more ground current than LPM, but 96 100 it can source significantly higher load current. HPM is not 97 101 available on boost type regulators. For voltage switch type 98 102 regulators, HPM implies that over current protection and 99 - soft start are active all the time. 0 = Set initial mode to 100 - low power mode (LPM). 103 + soft start are active all the time. 104 + 105 + 0 = Set initial mode to low power mode (LPM). 106 + 107 + - qcom,ocp-max-retries: 108 + Usage: optional 109 + Value type: <u32> 110 + Description: Maximum number of times to try toggling a voltage switch 111 + off and back on as a result of consecutive over current 112 + events. 113 + 114 + - qcom,ocp-retry-delay: 115 + Usage: optional 116 + Value type: <u32> 117 + Description: Time to delay in milliseconds between each voltage switch 118 + toggle after an over current event takes place. 119 + 120 + - qcom,pin-ctrl-enable: 121 + Usage: optional 122 + Value type: <u32> 123 + Description: Bit mask specifying which hardware pins should be used to 124 + enable the regulator, if any; supported bits are: 125 + 0 = ignore all hardware enable signals 126 + BIT(0) = follow HW0_EN signal 127 + BIT(1) = follow HW1_EN signal 128 + BIT(2) = follow HW2_EN signal 129 + BIT(3) = follow HW3_EN signal 130 + 131 + - qcom,pin-ctrl-hpm: 132 + Usage: optional 133 + Value type: <u32> 134 + Description: Bit mask specifying which hardware pins should be used to 135 + force the regulator into high power mode, if any; 136 + supported bits are: 137 + 0 = ignore all hardware enable signals 138 + BIT(0) = follow HW0_EN signal 139 + BIT(1) = follow HW1_EN signal 140 + BIT(2) = follow HW2_EN signal 141 + BIT(3) = follow HW3_EN signal 142 + BIT(4) = follow PMIC awake state 143 + 144 + - qcom,vs-soft-start-strength: 145 + Usage: optional 146 + Value type: <u32> 147 + Description: This property sets the soft start strength for voltage 148 + switch type regulators; supported values are: 149 + 0 = 0.05 uA 150 + 1 = 0.25 uA 151 + 2 = 0.55 uA 152 + 3 = 0.75 uA 101 153 102 154 Example: 103 155
+195 -5
drivers/regulator/qcom_spmi-regulator.c
··· 26 26 #include <linux/regmap.h> 27 27 #include <linux/list.h> 28 28 29 + /* Pin control enable input pins. */ 30 + #define SPMI_REGULATOR_PIN_CTRL_ENABLE_NONE 0x00 31 + #define SPMI_REGULATOR_PIN_CTRL_ENABLE_EN0 0x01 32 + #define SPMI_REGULATOR_PIN_CTRL_ENABLE_EN1 0x02 33 + #define SPMI_REGULATOR_PIN_CTRL_ENABLE_EN2 0x04 34 + #define SPMI_REGULATOR_PIN_CTRL_ENABLE_EN3 0x08 35 + #define SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT 0x10 36 + 37 + /* Pin control high power mode input pins. */ 38 + #define SPMI_REGULATOR_PIN_CTRL_HPM_NONE 0x00 39 + #define SPMI_REGULATOR_PIN_CTRL_HPM_EN0 0x01 40 + #define SPMI_REGULATOR_PIN_CTRL_HPM_EN1 0x02 41 + #define SPMI_REGULATOR_PIN_CTRL_HPM_EN2 0x04 42 + #define SPMI_REGULATOR_PIN_CTRL_HPM_EN3 0x08 43 + #define SPMI_REGULATOR_PIN_CTRL_HPM_SLEEP_B 0x10 44 + #define SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT 0x20 45 + 46 + /* 47 + * Used with enable parameters to specify that hardware default register values 48 + * should be left unaltered. 49 + */ 50 + #define SPMI_REGULATOR_USE_HW_DEFAULT 2 51 + 52 + /* Soft start strength of a voltage switch type regulator */ 53 + enum spmi_vs_soft_start_str { 54 + SPMI_VS_SOFT_START_STR_0P05_UA = 0, 55 + SPMI_VS_SOFT_START_STR_0P25_UA, 56 + SPMI_VS_SOFT_START_STR_0P55_UA, 57 + SPMI_VS_SOFT_START_STR_0P75_UA, 58 + SPMI_VS_SOFT_START_STR_HW_DEFAULT, 59 + }; 60 + 61 + /** 62 + * struct spmi_regulator_init_data - spmi-regulator initialization data 63 + * @pin_ctrl_enable: Bit mask specifying which hardware pins should be 64 + * used to enable the regulator, if any 65 + * Value should be an ORing of 66 + * SPMI_REGULATOR_PIN_CTRL_ENABLE_* constants. If 67 + * the bit specified by 68 + * SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT is 69 + * set, then pin control enable hardware registers 70 + * will not be modified. 71 + * @pin_ctrl_hpm: Bit mask specifying which hardware pins should be 72 + * used to force the regulator into high power 73 + * mode, if any 74 + * Value should be an ORing of 75 + * SPMI_REGULATOR_PIN_CTRL_HPM_* constants. If 76 + * the bit specified by 77 + * SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT is 78 + * set, then pin control mode hardware registers 79 + * will not be modified. 80 + * @vs_soft_start_strength: This parameter sets the soft start strength for 81 + * voltage switch type regulators. Its value 82 + * should be one of SPMI_VS_SOFT_START_STR_*. If 83 + * its value is SPMI_VS_SOFT_START_STR_HW_DEFAULT, 84 + * then the soft start strength will be left at its 85 + * default hardware value. 86 + */ 87 + struct spmi_regulator_init_data { 88 + unsigned pin_ctrl_enable; 89 + unsigned pin_ctrl_hpm; 90 + enum spmi_vs_soft_start_str vs_soft_start_strength; 91 + }; 92 + 29 93 /* These types correspond to unique register layouts. */ 30 94 enum spmi_regulator_logical_type { 31 95 SPMI_REGULATOR_LOGICAL_TYPE_SMPS, ··· 522 458 return spmi_regulator_common_enable(rdev); 523 459 } 524 460 461 + static int spmi_regulator_vs_ocp(struct regulator_dev *rdev) 462 + { 463 + struct spmi_regulator *vreg = rdev_get_drvdata(rdev); 464 + u8 reg = SPMI_VS_OCP_OVERRIDE; 465 + 466 + return spmi_vreg_write(vreg, SPMI_VS_REG_OCP, &reg, 1); 467 + } 468 + 525 469 static int spmi_regulator_common_disable(struct regulator_dev *rdev) 526 470 { 527 471 struct spmi_regulator *vreg = rdev_get_drvdata(rdev); ··· 863 791 if (reg & SPMI_COMMON_MODE_HPM_MASK) 864 792 return REGULATOR_MODE_NORMAL; 865 793 794 + if (reg & SPMI_COMMON_MODE_AUTO_MASK) 795 + return REGULATOR_MODE_FAST; 796 + 866 797 return REGULATOR_MODE_IDLE; 867 798 } 868 799 ··· 873 798 spmi_regulator_common_set_mode(struct regulator_dev *rdev, unsigned int mode) 874 799 { 875 800 struct spmi_regulator *vreg = rdev_get_drvdata(rdev); 876 - u8 mask = SPMI_COMMON_MODE_HPM_MASK; 801 + u8 mask = SPMI_COMMON_MODE_HPM_MASK | SPMI_COMMON_MODE_AUTO_MASK; 877 802 u8 val = 0; 878 803 879 804 if (mode == REGULATOR_MODE_NORMAL) 880 - val = mask; 805 + val = SPMI_COMMON_MODE_HPM_MASK; 806 + else if (mode == REGULATOR_MODE_FAST) 807 + val = SPMI_COMMON_MODE_AUTO_MASK; 881 808 882 809 return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_MODE, val, mask); 883 810 } ··· 1049 972 .is_enabled = spmi_regulator_common_is_enabled, 1050 973 .set_pull_down = spmi_regulator_common_set_pull_down, 1051 974 .set_soft_start = spmi_regulator_common_set_soft_start, 975 + .set_over_current_protection = spmi_regulator_vs_ocp, 1052 976 }; 1053 977 1054 978 static struct regulator_ops spmi_boost_ops = { ··· 1280 1202 return ret; 1281 1203 } 1282 1204 1205 + static int spmi_regulator_init_registers(struct spmi_regulator *vreg, 1206 + const struct spmi_regulator_init_data *data) 1207 + { 1208 + int ret; 1209 + enum spmi_regulator_logical_type type; 1210 + u8 ctrl_reg[8], reg, mask; 1211 + 1212 + type = vreg->logical_type; 1213 + 1214 + ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_RANGE, ctrl_reg, 8); 1215 + if (ret) 1216 + return ret; 1217 + 1218 + /* Set up enable pin control. */ 1219 + if ((type == SPMI_REGULATOR_LOGICAL_TYPE_SMPS 1220 + || type == SPMI_REGULATOR_LOGICAL_TYPE_LDO 1221 + || type == SPMI_REGULATOR_LOGICAL_TYPE_VS) 1222 + && !(data->pin_ctrl_enable 1223 + & SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT)) { 1224 + ctrl_reg[SPMI_COMMON_IDX_ENABLE] &= 1225 + ~SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; 1226 + ctrl_reg[SPMI_COMMON_IDX_ENABLE] |= 1227 + data->pin_ctrl_enable & SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; 1228 + } 1229 + 1230 + /* Set up mode pin control. */ 1231 + if ((type == SPMI_REGULATOR_LOGICAL_TYPE_SMPS 1232 + || type == SPMI_REGULATOR_LOGICAL_TYPE_LDO) 1233 + && !(data->pin_ctrl_hpm 1234 + & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { 1235 + ctrl_reg[SPMI_COMMON_IDX_MODE] &= 1236 + ~SPMI_COMMON_MODE_FOLLOW_ALL_MASK; 1237 + ctrl_reg[SPMI_COMMON_IDX_MODE] |= 1238 + data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_ALL_MASK; 1239 + } 1240 + 1241 + if (type == SPMI_REGULATOR_LOGICAL_TYPE_VS 1242 + && !(data->pin_ctrl_hpm & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { 1243 + ctrl_reg[SPMI_COMMON_IDX_MODE] &= 1244 + ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; 1245 + ctrl_reg[SPMI_COMMON_IDX_MODE] |= 1246 + data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; 1247 + } 1248 + 1249 + if ((type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS 1250 + || type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS 1251 + || type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_LDO) 1252 + && !(data->pin_ctrl_hpm 1253 + & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { 1254 + ctrl_reg[SPMI_COMMON_IDX_MODE] &= 1255 + ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; 1256 + ctrl_reg[SPMI_COMMON_IDX_MODE] |= 1257 + data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; 1258 + } 1259 + 1260 + /* Write back any control register values that were modified. */ 1261 + ret = spmi_vreg_write(vreg, SPMI_COMMON_REG_VOLTAGE_RANGE, ctrl_reg, 8); 1262 + if (ret) 1263 + return ret; 1264 + 1265 + /* Set soft start strength and over current protection for VS. */ 1266 + if (type == SPMI_REGULATOR_LOGICAL_TYPE_VS) { 1267 + if (data->vs_soft_start_strength 1268 + != SPMI_VS_SOFT_START_STR_HW_DEFAULT) { 1269 + reg = data->vs_soft_start_strength 1270 + & SPMI_VS_SOFT_START_SEL_MASK; 1271 + mask = SPMI_VS_SOFT_START_SEL_MASK; 1272 + return spmi_vreg_update_bits(vreg, 1273 + SPMI_VS_REG_SOFT_START, 1274 + reg, mask); 1275 + } 1276 + } 1277 + 1278 + return 0; 1279 + } 1280 + 1281 + static void spmi_regulator_get_dt_config(struct spmi_regulator *vreg, 1282 + struct device_node *node, struct spmi_regulator_init_data *data) 1283 + { 1284 + /* 1285 + * Initialize configuration parameters to use hardware default in case 1286 + * no value is specified via device tree. 1287 + */ 1288 + data->pin_ctrl_enable = SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT; 1289 + data->pin_ctrl_hpm = SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT; 1290 + data->vs_soft_start_strength = SPMI_VS_SOFT_START_STR_HW_DEFAULT; 1291 + 1292 + /* These bindings are optional, so it is okay if they aren't found. */ 1293 + of_property_read_u32(node, "qcom,ocp-max-retries", 1294 + &vreg->ocp_max_retries); 1295 + of_property_read_u32(node, "qcom,ocp-retry-delay", 1296 + &vreg->ocp_retry_delay_ms); 1297 + of_property_read_u32(node, "qcom,pin-ctrl-enable", 1298 + &data->pin_ctrl_enable); 1299 + of_property_read_u32(node, "qcom,pin-ctrl-hpm", &data->pin_ctrl_hpm); 1300 + of_property_read_u32(node, "qcom,vs-soft-start-strength", 1301 + &data->vs_soft_start_strength); 1302 + } 1303 + 1283 1304 static unsigned int spmi_regulator_of_map_mode(unsigned int mode) 1284 1305 { 1285 - if (mode) 1306 + if (mode == 1) 1286 1307 return REGULATOR_MODE_NORMAL; 1308 + if (mode == 2) 1309 + return REGULATOR_MODE_FAST; 1287 1310 1288 1311 return REGULATOR_MODE_IDLE; 1289 1312 } ··· 1393 1214 const struct regulator_desc *desc, 1394 1215 struct regulator_config *config) 1395 1216 { 1217 + struct spmi_regulator_init_data data = { }; 1396 1218 struct spmi_regulator *vreg = config->driver_data; 1397 1219 struct device *dev = config->dev; 1398 1220 int ret; 1399 1221 1400 - vreg->ocp_max_retries = SPMI_VS_OCP_DEFAULT_MAX_RETRIES; 1401 - vreg->ocp_retry_delay_ms = SPMI_VS_OCP_DEFAULT_RETRY_DELAY_MS; 1222 + spmi_regulator_get_dt_config(vreg, node, &data); 1223 + 1224 + if (!vreg->ocp_max_retries) 1225 + vreg->ocp_max_retries = SPMI_VS_OCP_DEFAULT_MAX_RETRIES; 1226 + if (!vreg->ocp_retry_delay_ms) 1227 + vreg->ocp_retry_delay_ms = SPMI_VS_OCP_DEFAULT_RETRY_DELAY_MS; 1228 + 1229 + ret = spmi_regulator_init_registers(vreg, &data); 1230 + if (ret) { 1231 + dev_err(dev, "common initialization failed, ret=%d\n", ret); 1232 + return ret; 1233 + } 1402 1234 1403 1235 if (vreg->logical_type == SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS) { 1404 1236 ret = spmi_regulator_ftsmps_init_slew_rate(vreg);