Loading Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt +8 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,14 @@ First Level Node - LCDB module Value type: <phandle> Definition: Phandle to the PMIC's revid node - qcom,voltage-step-ramp Usage: optional Value type: <bool> Definition: Required only if the voltage needs to be set in the steps of 500 mV starting from the 4500 mV. This needs to be enabled only on platforms where voltage needs to be ramped up with multiple steps. Touch-to-wake (TTW) properties: TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable Loading arch/arm64/boot/dts/qcom/pmi632.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -624,6 +624,7 @@ interrupt-names = "sc-irq"; qcom,pmic-revid = <&pmi632_revid>; qcom,voltage-step-ramp; lcdb_ldo_vreg: ldo { label = "ldo"; Loading drivers/regulator/qpnp-lcdb-regulator.c +115 −5 Original line number Diff line number Diff line Loading @@ -181,6 +181,7 @@ struct ldo_regulator { int soft_start_us; int vreg_ok_dbc_us; int voltage_mv; int prev_voltage_mv; }; struct ncp_regulator { Loading @@ -195,6 +196,7 @@ struct ncp_regulator { int soft_start_us; int vreg_ok_dbc_us; int voltage_mv; int prev_voltage_mv; }; struct bst_params { Loading Loading @@ -229,6 +231,7 @@ struct qpnp_lcdb { bool lcdb_enabled; bool settings_saved; bool lcdb_sc_disable; bool voltage_step_ramp; int sc_count; ktime_t sc_module_enable_time; Loading @@ -250,6 +253,7 @@ enum lcdb_module { LDO, NCP, BST, LDO_NCP, }; enum pfm_hysteresis { Loading Loading @@ -321,6 +325,12 @@ static u32 ncp_ilim_ma[] = { .valid = _valid \ } \ static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb, int voltage_start_mv, u8 type); static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb, int voltage_mv, u8 type); static bool is_between(int value, int min, int max) { if (value < min || value > max) Loading Loading @@ -784,9 +794,13 @@ static int qpnp_lcdb_enable_wa(struct qpnp_lcdb *lcdb) return 0; } #define VOLTAGE_START_MV 4500 #define VOLTAGE_STEP_MV 500 static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb) { int rc = 0, timeout, delay; int voltage_mv = VOLTAGE_START_MV; u8 val = 0; if (lcdb->lcdb_enabled || lcdb->lcdb_sc_disable) { Loading @@ -809,6 +823,22 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb) return rc; } if (lcdb->voltage_step_ramp) { if (lcdb->ldo.voltage_mv < VOLTAGE_START_MV) voltage_mv = lcdb->ldo.voltage_mv; rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, LDO); if (rc < 0) return rc; if (lcdb->ncp.voltage_mv < VOLTAGE_START_MV) voltage_mv = lcdb->ncp.voltage_mv; rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, NCP); if (rc < 0) return rc; } val = MODULE_EN_BIT; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG, &val, 1); Loading Loading @@ -845,6 +875,17 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb) } lcdb->lcdb_enabled = true; if (lcdb->voltage_step_ramp) { usleep_range(10000, 11000); rc = qpnp_lcdb_set_voltage_step(lcdb, voltage_mv + VOLTAGE_STEP_MV, LDO_NCP); if (rc < 0) { pr_err("Failed to set LCDB voltage rc=%d\n", rc); return rc; } } pr_debug("lcdb enabled successfully!\n"); return 0; Loading Loading @@ -1131,6 +1172,56 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb, return rc; } static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb, int voltage_start_mv, u8 type) { int i, ldo_voltage, ncp_voltage, voltage, rc = 0; for (i = voltage_start_mv; i <= (MAX_VOLTAGE_MV + VOLTAGE_STEP_MV); i += VOLTAGE_STEP_MV) { ldo_voltage = (lcdb->ldo.voltage_mv < i) ? lcdb->ldo.voltage_mv : i; ncp_voltage = (lcdb->ncp.voltage_mv < i) ? lcdb->ncp.voltage_mv : i; if (type == LDO_NCP) { rc = qpnp_lcdb_set_voltage(lcdb, ldo_voltage, LDO); if (rc < 0) return rc; rc = qpnp_lcdb_set_voltage(lcdb, ncp_voltage, NCP); if (rc < 0) return rc; pr_debug(" LDO voltage step %d NCP voltage step %d\n", ldo_voltage, ncp_voltage); if ((i >= lcdb->ncp.voltage_mv) && (i >= lcdb->ldo.voltage_mv)) break; } else { voltage = (type == LDO) ? ldo_voltage : ncp_voltage; rc = qpnp_lcdb_set_voltage(lcdb, voltage, type); if (rc < 0) return rc; pr_debug("%s voltage step %d\n", (type == LDO) ? "LDO" : "NCP", voltage); if ((type == LDO) && (i >= lcdb->ldo.voltage_mv)) break; if ((type == NCP) && (i >= lcdb->ncp.voltage_mv)) break; } usleep_range(1000, 1100); } return rc; } static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb, u32 *voltage_mv, u8 type) { Loading Loading @@ -1239,11 +1330,17 @@ static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev, int rc = 0; struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev); rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO); lcdb->ldo.voltage_mv = min_uV / 1000; if (lcdb->voltage_step_ramp) rc = qpnp_lcdb_set_voltage_step(lcdb, lcdb->ldo.prev_voltage_mv + VOLTAGE_STEP_MV, LDO); else rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ldo.voltage_mv, LDO); if (rc < 0) pr_err("Failed to set LDO voltage rc=%c\n", rc); else lcdb->ldo.voltage_mv = min_uV / 1000; lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv; return rc; } Loading Loading @@ -1312,11 +1409,17 @@ static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev, int rc = 0; struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev); rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP); lcdb->ncp.voltage_mv = min_uV / 1000; if (lcdb->voltage_step_ramp) rc = qpnp_lcdb_set_voltage_step(lcdb, lcdb->ncp.prev_voltage_mv + VOLTAGE_STEP_MV, NCP); else rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ncp.voltage_mv, NCP); if (rc < 0) pr_err("Failed to set LDO voltage rc=%c\n", rc); pr_err("Failed to set NCP voltage rc=%c\n", rc); else lcdb->ncp.voltage_mv = min_uV / 1000; lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv; return rc; } Loading Loading @@ -1678,6 +1781,8 @@ static int qpnp_lcdb_init_ldo(struct qpnp_lcdb *lcdb) return rc; } lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv; rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_LDO_VREG_OK_CTL_REG, &val, 1); if (rc < 0) { Loading Loading @@ -1783,6 +1888,8 @@ static int qpnp_lcdb_init_ncp(struct qpnp_lcdb *lcdb) return rc; } lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv; rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_NCP_VREG_OK_CTL_REG, &val, 1); if (rc < 0) { Loading Loading @@ -2056,6 +2163,9 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb) if (lcdb->sc_irq < 0) pr_debug("sc irq is not defined\n"); lcdb->voltage_step_ramp = of_property_read_bool(node, "qcom,voltage-step-ramp"); return rc; } Loading Loading
Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt +8 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,14 @@ First Level Node - LCDB module Value type: <phandle> Definition: Phandle to the PMIC's revid node - qcom,voltage-step-ramp Usage: optional Value type: <bool> Definition: Required only if the voltage needs to be set in the steps of 500 mV starting from the 4500 mV. This needs to be enabled only on platforms where voltage needs to be ramped up with multiple steps. Touch-to-wake (TTW) properties: TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable Loading
arch/arm64/boot/dts/qcom/pmi632.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -624,6 +624,7 @@ interrupt-names = "sc-irq"; qcom,pmic-revid = <&pmi632_revid>; qcom,voltage-step-ramp; lcdb_ldo_vreg: ldo { label = "ldo"; Loading
drivers/regulator/qpnp-lcdb-regulator.c +115 −5 Original line number Diff line number Diff line Loading @@ -181,6 +181,7 @@ struct ldo_regulator { int soft_start_us; int vreg_ok_dbc_us; int voltage_mv; int prev_voltage_mv; }; struct ncp_regulator { Loading @@ -195,6 +196,7 @@ struct ncp_regulator { int soft_start_us; int vreg_ok_dbc_us; int voltage_mv; int prev_voltage_mv; }; struct bst_params { Loading Loading @@ -229,6 +231,7 @@ struct qpnp_lcdb { bool lcdb_enabled; bool settings_saved; bool lcdb_sc_disable; bool voltage_step_ramp; int sc_count; ktime_t sc_module_enable_time; Loading @@ -250,6 +253,7 @@ enum lcdb_module { LDO, NCP, BST, LDO_NCP, }; enum pfm_hysteresis { Loading Loading @@ -321,6 +325,12 @@ static u32 ncp_ilim_ma[] = { .valid = _valid \ } \ static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb, int voltage_start_mv, u8 type); static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb, int voltage_mv, u8 type); static bool is_between(int value, int min, int max) { if (value < min || value > max) Loading Loading @@ -784,9 +794,13 @@ static int qpnp_lcdb_enable_wa(struct qpnp_lcdb *lcdb) return 0; } #define VOLTAGE_START_MV 4500 #define VOLTAGE_STEP_MV 500 static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb) { int rc = 0, timeout, delay; int voltage_mv = VOLTAGE_START_MV; u8 val = 0; if (lcdb->lcdb_enabled || lcdb->lcdb_sc_disable) { Loading @@ -809,6 +823,22 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb) return rc; } if (lcdb->voltage_step_ramp) { if (lcdb->ldo.voltage_mv < VOLTAGE_START_MV) voltage_mv = lcdb->ldo.voltage_mv; rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, LDO); if (rc < 0) return rc; if (lcdb->ncp.voltage_mv < VOLTAGE_START_MV) voltage_mv = lcdb->ncp.voltage_mv; rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, NCP); if (rc < 0) return rc; } val = MODULE_EN_BIT; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG, &val, 1); Loading Loading @@ -845,6 +875,17 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb) } lcdb->lcdb_enabled = true; if (lcdb->voltage_step_ramp) { usleep_range(10000, 11000); rc = qpnp_lcdb_set_voltage_step(lcdb, voltage_mv + VOLTAGE_STEP_MV, LDO_NCP); if (rc < 0) { pr_err("Failed to set LCDB voltage rc=%d\n", rc); return rc; } } pr_debug("lcdb enabled successfully!\n"); return 0; Loading Loading @@ -1131,6 +1172,56 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb, return rc; } static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb, int voltage_start_mv, u8 type) { int i, ldo_voltage, ncp_voltage, voltage, rc = 0; for (i = voltage_start_mv; i <= (MAX_VOLTAGE_MV + VOLTAGE_STEP_MV); i += VOLTAGE_STEP_MV) { ldo_voltage = (lcdb->ldo.voltage_mv < i) ? lcdb->ldo.voltage_mv : i; ncp_voltage = (lcdb->ncp.voltage_mv < i) ? lcdb->ncp.voltage_mv : i; if (type == LDO_NCP) { rc = qpnp_lcdb_set_voltage(lcdb, ldo_voltage, LDO); if (rc < 0) return rc; rc = qpnp_lcdb_set_voltage(lcdb, ncp_voltage, NCP); if (rc < 0) return rc; pr_debug(" LDO voltage step %d NCP voltage step %d\n", ldo_voltage, ncp_voltage); if ((i >= lcdb->ncp.voltage_mv) && (i >= lcdb->ldo.voltage_mv)) break; } else { voltage = (type == LDO) ? ldo_voltage : ncp_voltage; rc = qpnp_lcdb_set_voltage(lcdb, voltage, type); if (rc < 0) return rc; pr_debug("%s voltage step %d\n", (type == LDO) ? "LDO" : "NCP", voltage); if ((type == LDO) && (i >= lcdb->ldo.voltage_mv)) break; if ((type == NCP) && (i >= lcdb->ncp.voltage_mv)) break; } usleep_range(1000, 1100); } return rc; } static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb, u32 *voltage_mv, u8 type) { Loading Loading @@ -1239,11 +1330,17 @@ static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev, int rc = 0; struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev); rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO); lcdb->ldo.voltage_mv = min_uV / 1000; if (lcdb->voltage_step_ramp) rc = qpnp_lcdb_set_voltage_step(lcdb, lcdb->ldo.prev_voltage_mv + VOLTAGE_STEP_MV, LDO); else rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ldo.voltage_mv, LDO); if (rc < 0) pr_err("Failed to set LDO voltage rc=%c\n", rc); else lcdb->ldo.voltage_mv = min_uV / 1000; lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv; return rc; } Loading Loading @@ -1312,11 +1409,17 @@ static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev, int rc = 0; struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev); rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP); lcdb->ncp.voltage_mv = min_uV / 1000; if (lcdb->voltage_step_ramp) rc = qpnp_lcdb_set_voltage_step(lcdb, lcdb->ncp.prev_voltage_mv + VOLTAGE_STEP_MV, NCP); else rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ncp.voltage_mv, NCP); if (rc < 0) pr_err("Failed to set LDO voltage rc=%c\n", rc); pr_err("Failed to set NCP voltage rc=%c\n", rc); else lcdb->ncp.voltage_mv = min_uV / 1000; lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv; return rc; } Loading Loading @@ -1678,6 +1781,8 @@ static int qpnp_lcdb_init_ldo(struct qpnp_lcdb *lcdb) return rc; } lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv; rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_LDO_VREG_OK_CTL_REG, &val, 1); if (rc < 0) { Loading Loading @@ -1783,6 +1888,8 @@ static int qpnp_lcdb_init_ncp(struct qpnp_lcdb *lcdb) return rc; } lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv; rc = qpnp_lcdb_read(lcdb, lcdb->base + LCDB_NCP_VREG_OK_CTL_REG, &val, 1); if (rc < 0) { Loading Loading @@ -2056,6 +2163,9 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb) if (lcdb->sc_irq < 0) pr_debug("sc irq is not defined\n"); lcdb->voltage_step_ramp = of_property_read_bool(node, "qcom,voltage-step-ramp"); return rc; } Loading