Loading Documentation/devicetree/bindings/regulator/palmas-pmic.txt +9 −3 Original line number Diff line number Diff line Loading @@ -26,11 +26,17 @@ Optional nodes: For ti,palmas-pmic - smps12, smps123, smps3 depending on OTP, smps45, smps457, smps7 depending on variant, smps6, smps[8-9], smps10_out2, smps10_out1, do[1-9], ldoln, ldousb. smps10_out2, smps10_out1, ldo[1-9], ldoln, ldousb. Optional sub-node properties: ti,warm-reset - maintain voltage during warm reset(boolean) ti,roof-floor - control voltage selection by pin(boolean) ti,roof-floor - This takes as optional argument on platform supporting the rail from desired external control. If there is no argument then it will be assume that it is controlled by NSLEEP pin. The valid value for external pins are: ENABLE1 then 1, ENABLE2 then 2 or NSLEEP then 3. ti,mode-sleep - mode to adopt in pmic sleep 0 - off, 1 - auto, 2 - eco, 3 - forced pwm ti,smps-range - OTP has the wrong range set for the hardware so override Loading Loading @@ -61,7 +67,7 @@ pmic { regulator-always-on; regulator-boot-on; ti,warm-reset; ti,roof-floor; ti,roof-floor = <1>; /* ENABLE1 control */ ti,mode-sleep = <0>; ti,smps-range = <1>; }; Loading drivers/regulator/palmas-regulator.c +159 −7 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct regs_info { u8 vsel_addr; u8 ctrl_addr; u8 tstep_addr; int sleep_id; }; static const struct regs_info palmas_regs_info[] = { Loading @@ -42,6 +43,7 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS12_VOLTAGE, .ctrl_addr = PALMAS_SMPS12_CTRL, .tstep_addr = PALMAS_SMPS12_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12, }, { .name = "SMPS123", Loading @@ -49,12 +51,14 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS12_VOLTAGE, .ctrl_addr = PALMAS_SMPS12_CTRL, .tstep_addr = PALMAS_SMPS12_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12, }, { .name = "SMPS3", .sname = "smps3-in", .vsel_addr = PALMAS_SMPS3_VOLTAGE, .ctrl_addr = PALMAS_SMPS3_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS3, }, { .name = "SMPS45", Loading @@ -62,6 +66,7 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS45_VOLTAGE, .ctrl_addr = PALMAS_SMPS45_CTRL, .tstep_addr = PALMAS_SMPS45_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45, }, { .name = "SMPS457", Loading @@ -69,6 +74,7 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS45_VOLTAGE, .ctrl_addr = PALMAS_SMPS45_CTRL, .tstep_addr = PALMAS_SMPS45_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45, }, { .name = "SMPS6", Loading @@ -76,12 +82,14 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS6_VOLTAGE, .ctrl_addr = PALMAS_SMPS6_CTRL, .tstep_addr = PALMAS_SMPS6_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS6, }, { .name = "SMPS7", .sname = "smps7-in", .vsel_addr = PALMAS_SMPS7_VOLTAGE, .ctrl_addr = PALMAS_SMPS7_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS7, }, { .name = "SMPS8", Loading @@ -89,108 +97,128 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS8_VOLTAGE, .ctrl_addr = PALMAS_SMPS8_CTRL, .tstep_addr = PALMAS_SMPS8_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS8, }, { .name = "SMPS9", .sname = "smps9-in", .vsel_addr = PALMAS_SMPS9_VOLTAGE, .ctrl_addr = PALMAS_SMPS9_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS9, }, { .name = "SMPS10_OUT2", .sname = "smps10-in", .ctrl_addr = PALMAS_SMPS10_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10, }, { .name = "SMPS10_OUT1", .sname = "smps10-out2", .ctrl_addr = PALMAS_SMPS10_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10, }, { .name = "LDO1", .sname = "ldo1-in", .vsel_addr = PALMAS_LDO1_VOLTAGE, .ctrl_addr = PALMAS_LDO1_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO1, }, { .name = "LDO2", .sname = "ldo2-in", .vsel_addr = PALMAS_LDO2_VOLTAGE, .ctrl_addr = PALMAS_LDO2_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO2, }, { .name = "LDO3", .sname = "ldo3-in", .vsel_addr = PALMAS_LDO3_VOLTAGE, .ctrl_addr = PALMAS_LDO3_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO3, }, { .name = "LDO4", .sname = "ldo4-in", .vsel_addr = PALMAS_LDO4_VOLTAGE, .ctrl_addr = PALMAS_LDO4_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO4, }, { .name = "LDO5", .sname = "ldo5-in", .vsel_addr = PALMAS_LDO5_VOLTAGE, .ctrl_addr = PALMAS_LDO5_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO5, }, { .name = "LDO6", .sname = "ldo6-in", .vsel_addr = PALMAS_LDO6_VOLTAGE, .ctrl_addr = PALMAS_LDO6_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO6, }, { .name = "LDO7", .sname = "ldo7-in", .vsel_addr = PALMAS_LDO7_VOLTAGE, .ctrl_addr = PALMAS_LDO7_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO7, }, { .name = "LDO8", .sname = "ldo8-in", .vsel_addr = PALMAS_LDO8_VOLTAGE, .ctrl_addr = PALMAS_LDO8_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO8, }, { .name = "LDO9", .sname = "ldo9-in", .vsel_addr = PALMAS_LDO9_VOLTAGE, .ctrl_addr = PALMAS_LDO9_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO9, }, { .name = "LDOLN", .sname = "ldoln-in", .vsel_addr = PALMAS_LDOLN_VOLTAGE, .ctrl_addr = PALMAS_LDOLN_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOLN, }, { .name = "LDOUSB", .sname = "ldousb-in", .vsel_addr = PALMAS_LDOUSB_VOLTAGE, .ctrl_addr = PALMAS_LDOUSB_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOUSB, }, { .name = "REGEN1", .ctrl_addr = PALMAS_REGEN1_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN1, }, { .name = "REGEN2", .ctrl_addr = PALMAS_REGEN2_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN2, }, { .name = "REGEN3", .ctrl_addr = PALMAS_REGEN3_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN3, }, { .name = "SYSEN1", .ctrl_addr = PALMAS_SYSEN1_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN1, }, { .name = "SYSEN2", .ctrl_addr = PALMAS_SYSEN2_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN2, }, }; Loading Loading @@ -478,6 +506,17 @@ static struct regulator_ops palmas_ops_smps = { .set_ramp_delay = palmas_smps_set_ramp_delay, }; static struct regulator_ops palmas_ops_ext_control_smps = { .set_mode = palmas_set_mode_smps, .get_mode = palmas_get_mode_smps, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = palmas_list_voltage_smps, .map_voltage = palmas_map_voltage_smps, .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, .set_ramp_delay = palmas_smps_set_ramp_delay, }; static struct regulator_ops palmas_ops_smps10 = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, Loading Loading @@ -513,12 +552,37 @@ static struct regulator_ops palmas_ops_ldo = { .map_voltage = regulator_map_voltage_linear, }; static struct regulator_ops palmas_ops_ext_control_ldo = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; static struct regulator_ops palmas_ops_extreg = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, }; static struct regulator_ops palmas_ops_ext_control_extreg = { }; static int palmas_regulator_config_external(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { int sleep_id = palmas_regs_info[id].sleep_id; int ret; ret = palmas_ext_control_req_config(palmas, sleep_id, reg_init->roof_floor, true); if (ret < 0) dev_err(palmas->dev, "Ext control config for regulator %d failed %d\n", id, ret); return ret; } /* * setup the hardware based sleep configuration of the SMPS/LDO regulators * from the platform data. This is different to the software based control Loading Loading @@ -577,7 +641,22 @@ static int palmas_smps_init(struct palmas *palmas, int id, return ret; } if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) && (id != PALMAS_REG_SMPS10_OUT2)) { /* Enable externally controlled regulator */ addr = palmas_regs_info[id].ctrl_addr; ret = palmas_smps_read(palmas, addr, ®); if (ret < 0) return ret; if (!(reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK)) { reg |= SMPS_CTRL_MODE_ON; ret = palmas_smps_write(palmas, addr, reg); if (ret < 0) return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; } Loading Loading @@ -608,6 +687,20 @@ static int palmas_ldo_init(struct palmas *palmas, int id, if (ret) return ret; if (reg_init->roof_floor) { /* Enable externally controlled regulator */ addr = palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_LDO_BASE, addr, PALMAS_LDO1_CTRL_MODE_ACTIVE, PALMAS_LDO1_CTRL_MODE_ACTIVE); if (ret < 0) { dev_err(palmas->dev, "LDO Register 0x%02x update failed %d\n", addr, ret); return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; } Loading @@ -630,6 +723,21 @@ static int palmas_extreg_init(struct palmas *palmas, int id, addr, ret); return ret; } if (reg_init->roof_floor) { /* Enable externally controlled regulator */ addr = palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE, PALMAS_REGEN1_CTRL_MODE_ACTIVE); if (ret < 0) { dev_err(palmas->dev, "Resource Register 0x%02x update failed %d\n", addr, ret); return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; } Loading Loading @@ -712,7 +820,7 @@ static void palmas_dt_to_pdata(struct device *dev, int idx, ret; node = of_node_get(node); regulators = of_find_node_by_name(node, "regulators"); regulators = of_get_child_by_name(node, "regulators"); if (!regulators) { dev_info(dev, "regulator node not found\n"); return; Loading Loading @@ -740,9 +848,35 @@ static void palmas_dt_to_pdata(struct device *dev, of_property_read_bool(palmas_matches[idx].of_node, "ti,warm-reset"); pdata->reg_init[idx]->roof_floor = of_property_read_bool(palmas_matches[idx].of_node, "ti,roof-floor"); ret = of_property_read_u32(palmas_matches[idx].of_node, "ti,roof-floor", &prop); /* EINVAL: Property not found */ if (ret != -EINVAL) { int econtrol; /* use default value, when no value is specified */ econtrol = PALMAS_EXT_CONTROL_NSLEEP; if (!ret) { switch (prop) { case 1: econtrol = PALMAS_EXT_CONTROL_ENABLE1; break; case 2: econtrol = PALMAS_EXT_CONTROL_ENABLE2; break; case 3: econtrol = PALMAS_EXT_CONTROL_NSLEEP; break; default: WARN_ON(1); dev_warn(dev, "%s: Invalid roof-floor option: %u\n", palmas_matches[idx].name, prop); break; } } pdata->reg_init[idx]->roof_floor = econtrol; } ret = of_property_read_u32(palmas_matches[idx].of_node, "ti,mode-sleep", &prop); Loading Loading @@ -869,6 +1003,8 @@ static int palmas_regulators_probe(struct platform_device *pdev) ret = palmas_smps_init(palmas, id, reg_init); if (ret) return ret; } else { reg_init = NULL; } /* Register the regulators */ Loading Loading @@ -913,6 +1049,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) pmic->range[id] = 1; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = &palmas_ops_ext_control_smps; else pmic->desc[id].ops = &palmas_ops_smps; pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; pmic->desc[id].vsel_reg = Loading Loading @@ -956,6 +1096,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) /* Start this loop from the id left from previous loop */ for (; id < PALMAS_NUM_REGS; id++) { if (pdata && pdata->reg_init[id]) reg_init = pdata->reg_init[id]; else reg_init = NULL; /* Miss out regulators which are not available due * to alternate functions. Loading @@ -969,6 +1113,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) if (id < PALMAS_REG_REGEN1) { pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = &palmas_ops_ext_control_ldo; else pmic->desc[id].ops = &palmas_ops_ldo; pmic->desc[id].min_uV = 900000; pmic->desc[id].uV_step = 50000; Loading Loading @@ -999,6 +1147,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) pmic->desc[id].enable_time = 2000; } else { pmic->desc[id].n_voltages = 1; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = &palmas_ops_ext_control_extreg; else pmic->desc[id].ops = &palmas_ops_extreg; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, Loading Loading
Documentation/devicetree/bindings/regulator/palmas-pmic.txt +9 −3 Original line number Diff line number Diff line Loading @@ -26,11 +26,17 @@ Optional nodes: For ti,palmas-pmic - smps12, smps123, smps3 depending on OTP, smps45, smps457, smps7 depending on variant, smps6, smps[8-9], smps10_out2, smps10_out1, do[1-9], ldoln, ldousb. smps10_out2, smps10_out1, ldo[1-9], ldoln, ldousb. Optional sub-node properties: ti,warm-reset - maintain voltage during warm reset(boolean) ti,roof-floor - control voltage selection by pin(boolean) ti,roof-floor - This takes as optional argument on platform supporting the rail from desired external control. If there is no argument then it will be assume that it is controlled by NSLEEP pin. The valid value for external pins are: ENABLE1 then 1, ENABLE2 then 2 or NSLEEP then 3. ti,mode-sleep - mode to adopt in pmic sleep 0 - off, 1 - auto, 2 - eco, 3 - forced pwm ti,smps-range - OTP has the wrong range set for the hardware so override Loading Loading @@ -61,7 +67,7 @@ pmic { regulator-always-on; regulator-boot-on; ti,warm-reset; ti,roof-floor; ti,roof-floor = <1>; /* ENABLE1 control */ ti,mode-sleep = <0>; ti,smps-range = <1>; }; Loading
drivers/regulator/palmas-regulator.c +159 −7 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct regs_info { u8 vsel_addr; u8 ctrl_addr; u8 tstep_addr; int sleep_id; }; static const struct regs_info palmas_regs_info[] = { Loading @@ -42,6 +43,7 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS12_VOLTAGE, .ctrl_addr = PALMAS_SMPS12_CTRL, .tstep_addr = PALMAS_SMPS12_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12, }, { .name = "SMPS123", Loading @@ -49,12 +51,14 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS12_VOLTAGE, .ctrl_addr = PALMAS_SMPS12_CTRL, .tstep_addr = PALMAS_SMPS12_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12, }, { .name = "SMPS3", .sname = "smps3-in", .vsel_addr = PALMAS_SMPS3_VOLTAGE, .ctrl_addr = PALMAS_SMPS3_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS3, }, { .name = "SMPS45", Loading @@ -62,6 +66,7 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS45_VOLTAGE, .ctrl_addr = PALMAS_SMPS45_CTRL, .tstep_addr = PALMAS_SMPS45_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45, }, { .name = "SMPS457", Loading @@ -69,6 +74,7 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS45_VOLTAGE, .ctrl_addr = PALMAS_SMPS45_CTRL, .tstep_addr = PALMAS_SMPS45_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45, }, { .name = "SMPS6", Loading @@ -76,12 +82,14 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS6_VOLTAGE, .ctrl_addr = PALMAS_SMPS6_CTRL, .tstep_addr = PALMAS_SMPS6_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS6, }, { .name = "SMPS7", .sname = "smps7-in", .vsel_addr = PALMAS_SMPS7_VOLTAGE, .ctrl_addr = PALMAS_SMPS7_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS7, }, { .name = "SMPS8", Loading @@ -89,108 +97,128 @@ static const struct regs_info palmas_regs_info[] = { .vsel_addr = PALMAS_SMPS8_VOLTAGE, .ctrl_addr = PALMAS_SMPS8_CTRL, .tstep_addr = PALMAS_SMPS8_TSTEP, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS8, }, { .name = "SMPS9", .sname = "smps9-in", .vsel_addr = PALMAS_SMPS9_VOLTAGE, .ctrl_addr = PALMAS_SMPS9_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS9, }, { .name = "SMPS10_OUT2", .sname = "smps10-in", .ctrl_addr = PALMAS_SMPS10_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10, }, { .name = "SMPS10_OUT1", .sname = "smps10-out2", .ctrl_addr = PALMAS_SMPS10_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10, }, { .name = "LDO1", .sname = "ldo1-in", .vsel_addr = PALMAS_LDO1_VOLTAGE, .ctrl_addr = PALMAS_LDO1_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO1, }, { .name = "LDO2", .sname = "ldo2-in", .vsel_addr = PALMAS_LDO2_VOLTAGE, .ctrl_addr = PALMAS_LDO2_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO2, }, { .name = "LDO3", .sname = "ldo3-in", .vsel_addr = PALMAS_LDO3_VOLTAGE, .ctrl_addr = PALMAS_LDO3_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO3, }, { .name = "LDO4", .sname = "ldo4-in", .vsel_addr = PALMAS_LDO4_VOLTAGE, .ctrl_addr = PALMAS_LDO4_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO4, }, { .name = "LDO5", .sname = "ldo5-in", .vsel_addr = PALMAS_LDO5_VOLTAGE, .ctrl_addr = PALMAS_LDO5_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO5, }, { .name = "LDO6", .sname = "ldo6-in", .vsel_addr = PALMAS_LDO6_VOLTAGE, .ctrl_addr = PALMAS_LDO6_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO6, }, { .name = "LDO7", .sname = "ldo7-in", .vsel_addr = PALMAS_LDO7_VOLTAGE, .ctrl_addr = PALMAS_LDO7_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO7, }, { .name = "LDO8", .sname = "ldo8-in", .vsel_addr = PALMAS_LDO8_VOLTAGE, .ctrl_addr = PALMAS_LDO8_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO8, }, { .name = "LDO9", .sname = "ldo9-in", .vsel_addr = PALMAS_LDO9_VOLTAGE, .ctrl_addr = PALMAS_LDO9_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO9, }, { .name = "LDOLN", .sname = "ldoln-in", .vsel_addr = PALMAS_LDOLN_VOLTAGE, .ctrl_addr = PALMAS_LDOLN_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOLN, }, { .name = "LDOUSB", .sname = "ldousb-in", .vsel_addr = PALMAS_LDOUSB_VOLTAGE, .ctrl_addr = PALMAS_LDOUSB_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOUSB, }, { .name = "REGEN1", .ctrl_addr = PALMAS_REGEN1_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN1, }, { .name = "REGEN2", .ctrl_addr = PALMAS_REGEN2_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN2, }, { .name = "REGEN3", .ctrl_addr = PALMAS_REGEN3_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN3, }, { .name = "SYSEN1", .ctrl_addr = PALMAS_SYSEN1_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN1, }, { .name = "SYSEN2", .ctrl_addr = PALMAS_SYSEN2_CTRL, .sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN2, }, }; Loading Loading @@ -478,6 +506,17 @@ static struct regulator_ops palmas_ops_smps = { .set_ramp_delay = palmas_smps_set_ramp_delay, }; static struct regulator_ops palmas_ops_ext_control_smps = { .set_mode = palmas_set_mode_smps, .get_mode = palmas_get_mode_smps, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = palmas_list_voltage_smps, .map_voltage = palmas_map_voltage_smps, .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel, .set_ramp_delay = palmas_smps_set_ramp_delay, }; static struct regulator_ops palmas_ops_smps10 = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, Loading Loading @@ -513,12 +552,37 @@ static struct regulator_ops palmas_ops_ldo = { .map_voltage = regulator_map_voltage_linear, }; static struct regulator_ops palmas_ops_ext_control_ldo = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; static struct regulator_ops palmas_ops_extreg = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, }; static struct regulator_ops palmas_ops_ext_control_extreg = { }; static int palmas_regulator_config_external(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { int sleep_id = palmas_regs_info[id].sleep_id; int ret; ret = palmas_ext_control_req_config(palmas, sleep_id, reg_init->roof_floor, true); if (ret < 0) dev_err(palmas->dev, "Ext control config for regulator %d failed %d\n", id, ret); return ret; } /* * setup the hardware based sleep configuration of the SMPS/LDO regulators * from the platform data. This is different to the software based control Loading Loading @@ -577,7 +641,22 @@ static int palmas_smps_init(struct palmas *palmas, int id, return ret; } if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) && (id != PALMAS_REG_SMPS10_OUT2)) { /* Enable externally controlled regulator */ addr = palmas_regs_info[id].ctrl_addr; ret = palmas_smps_read(palmas, addr, ®); if (ret < 0) return ret; if (!(reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK)) { reg |= SMPS_CTRL_MODE_ON; ret = palmas_smps_write(palmas, addr, reg); if (ret < 0) return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; } Loading Loading @@ -608,6 +687,20 @@ static int palmas_ldo_init(struct palmas *palmas, int id, if (ret) return ret; if (reg_init->roof_floor) { /* Enable externally controlled regulator */ addr = palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_LDO_BASE, addr, PALMAS_LDO1_CTRL_MODE_ACTIVE, PALMAS_LDO1_CTRL_MODE_ACTIVE); if (ret < 0) { dev_err(palmas->dev, "LDO Register 0x%02x update failed %d\n", addr, ret); return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; } Loading @@ -630,6 +723,21 @@ static int palmas_extreg_init(struct palmas *palmas, int id, addr, ret); return ret; } if (reg_init->roof_floor) { /* Enable externally controlled regulator */ addr = palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE, PALMAS_REGEN1_CTRL_MODE_ACTIVE); if (ret < 0) { dev_err(palmas->dev, "Resource Register 0x%02x update failed %d\n", addr, ret); return ret; } return palmas_regulator_config_external(palmas, id, reg_init); } return 0; } Loading Loading @@ -712,7 +820,7 @@ static void palmas_dt_to_pdata(struct device *dev, int idx, ret; node = of_node_get(node); regulators = of_find_node_by_name(node, "regulators"); regulators = of_get_child_by_name(node, "regulators"); if (!regulators) { dev_info(dev, "regulator node not found\n"); return; Loading Loading @@ -740,9 +848,35 @@ static void palmas_dt_to_pdata(struct device *dev, of_property_read_bool(palmas_matches[idx].of_node, "ti,warm-reset"); pdata->reg_init[idx]->roof_floor = of_property_read_bool(palmas_matches[idx].of_node, "ti,roof-floor"); ret = of_property_read_u32(palmas_matches[idx].of_node, "ti,roof-floor", &prop); /* EINVAL: Property not found */ if (ret != -EINVAL) { int econtrol; /* use default value, when no value is specified */ econtrol = PALMAS_EXT_CONTROL_NSLEEP; if (!ret) { switch (prop) { case 1: econtrol = PALMAS_EXT_CONTROL_ENABLE1; break; case 2: econtrol = PALMAS_EXT_CONTROL_ENABLE2; break; case 3: econtrol = PALMAS_EXT_CONTROL_NSLEEP; break; default: WARN_ON(1); dev_warn(dev, "%s: Invalid roof-floor option: %u\n", palmas_matches[idx].name, prop); break; } } pdata->reg_init[idx]->roof_floor = econtrol; } ret = of_property_read_u32(palmas_matches[idx].of_node, "ti,mode-sleep", &prop); Loading Loading @@ -869,6 +1003,8 @@ static int palmas_regulators_probe(struct platform_device *pdev) ret = palmas_smps_init(palmas, id, reg_init); if (ret) return ret; } else { reg_init = NULL; } /* Register the regulators */ Loading Loading @@ -913,6 +1049,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) pmic->range[id] = 1; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = &palmas_ops_ext_control_smps; else pmic->desc[id].ops = &palmas_ops_smps; pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; pmic->desc[id].vsel_reg = Loading Loading @@ -956,6 +1096,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) /* Start this loop from the id left from previous loop */ for (; id < PALMAS_NUM_REGS; id++) { if (pdata && pdata->reg_init[id]) reg_init = pdata->reg_init[id]; else reg_init = NULL; /* Miss out regulators which are not available due * to alternate functions. Loading @@ -969,6 +1113,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) if (id < PALMAS_REG_REGEN1) { pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = &palmas_ops_ext_control_ldo; else pmic->desc[id].ops = &palmas_ops_ldo; pmic->desc[id].min_uV = 900000; pmic->desc[id].uV_step = 50000; Loading Loading @@ -999,6 +1147,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) pmic->desc[id].enable_time = 2000; } else { pmic->desc[id].n_voltages = 1; if (reg_init && reg_init->roof_floor) pmic->desc[id].ops = &palmas_ops_ext_control_extreg; else pmic->desc[id].ops = &palmas_ops_extreg; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, Loading