Loading Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ First Level Node - LCDB module to be enabled only on platforms where voltage needs to be ramped up with multiple steps. - qcom,pwrdn-delay-ms Usage: optional Value type: <u32> Definition: Required to control the LDO power down delay. Possible values are 0, 1, 4, 8. Touch-to-wake (TTW) properties: TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable Loading drivers/regulator/qpnp-lcdb-regulator.c +94 −2 Original line number Diff line number Diff line Loading @@ -114,6 +114,10 @@ #define PFM_CURRENT_SHIFT 2 #define LCDB_PWRUP_PWRDN_CTL_REG 0x66 #define PWRUP_DELAY_MASK GENAMSK(3, 2) #define PWRDN_DELAY_MASK GENMASK(1, 0) #define PWRDN_DELAY_MIN_MS 0 #define PWRDN_DELAY_MAX_MS 8 /* LDO */ #define LCDB_LDO_OUTPUT_VOLTAGE_REG 0x71 Loading @@ -126,6 +130,10 @@ #define LDO_DIS_PULLDOWN_BIT BIT(1) #define LDO_PD_STRENGTH_BIT BIT(0) #define LCDB_LDO_FORCE_PD_CTL_REG 0x79 #define LDO_FORCE_PD_EN_BIT BIT(0) #define LDO_FORCE_PD_MODE BIT(7) #define LCDB_LDO_ILIM_CTL1_REG 0x7B #define EN_LDO_ILIM_BIT BIT(7) #define SET_LDO_ILIM_MASK GENMASK(2, 0) Loading Loading @@ -220,7 +228,9 @@ struct qpnp_lcdb { struct regmap *regmap; struct pmic_revid_data *pmic_rev_id; u32 base; u32 wa_flags; int sc_irq; int pwrdn_delay_ms; /* TTW params */ bool ttw_enable; Loading Loading @@ -292,6 +302,11 @@ enum lcdb_settings_index { LCDB_SETTING_MAX, }; enum lcdb_wa_flags { NCP_SCP_DISABLE_WA = BIT(0), FORCE_PD_ENABLE_WA = BIT(1), }; static u32 soft_start_us[] = { 0, 500, Loading @@ -313,6 +328,13 @@ static u32 ncp_ilim_ma[] = { 810, }; static const u32 pwrup_pwrdn_ms[] = { 0, 1, 4, 8, }; #define SETTING(_id, _sec_access, _valid) \ [_id] = { \ .address = _id##_REG, \ Loading Loading @@ -915,6 +937,18 @@ static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb) return 0; } if (lcdb->wa_flags & FORCE_PD_ENABLE_WA) { /* * force pull-down to enable quick discharge after * turning off */ val = LDO_FORCE_PD_EN_BIT | LDO_FORCE_PD_MODE; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_FORCE_PD_CTL_REG, &val, 1); if (rc < 0) return rc; } val = 0; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG, &val, 1); Loading @@ -923,6 +957,17 @@ static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb) else lcdb->lcdb_enabled = false; if (lcdb->wa_flags & FORCE_PD_ENABLE_WA) { /* wait for 10 msec after module disable for LDO to discharge */ usleep_range(10000, 11000); val = 0; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_FORCE_PD_CTL_REG, &val, 1); if (rc < 0) return rc; } return rc; } Loading Loading @@ -2020,11 +2065,40 @@ static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb) return 0; } static void qpnp_lcdb_pmic_config(struct qpnp_lcdb *lcdb) { switch (lcdb->pmic_rev_id->pmic_subtype) { case PM660L_SUBTYPE: if (lcdb->pmic_rev_id->rev4 < PM660L_V2P0_REV4) lcdb->wa_flags |= NCP_SCP_DISABLE_WA; break; case PMI632_SUBTYPE: case PM6150L_SUBTYPE: lcdb->wa_flags |= FORCE_PD_ENABLE_WA; break; default: break; } pr_debug("LCDB wa_flags = 0x%2x\n", lcdb->wa_flags); } static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb) { int rc = 0; u8 val = 0; qpnp_lcdb_pmic_config(lcdb); if (lcdb->pwrdn_delay_ms != -EINVAL) { rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG, PWRDN_DELAY_MASK, lcdb->pwrdn_delay_ms); if (rc < 0) return rc; } rc = qpnp_lcdb_init_bst(lcdb); if (rc < 0) { pr_err("Failed to initialize BOOST rc=%d\n", rc); Loading Loading @@ -2082,7 +2156,8 @@ static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb) static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb) { int rc = 0; int rc = 0, i = 0; u32 tmp; const char *label; struct device_node *revid_dev_node, *temp, *node = lcdb->dev->of_node; Loading Loading @@ -2146,7 +2221,24 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb) lcdb->voltage_step_ramp = of_property_read_bool(node, "qcom,voltage-step-ramp"); return rc; lcdb->pwrdn_delay_ms = -EINVAL; rc = of_property_read_u32(node, "qcom,pwrdn-delay-ms", &tmp); if (!rc) { if (!is_between(tmp, PWRDN_DELAY_MIN_MS, PWRDN_DELAY_MAX_MS)) { pr_err("Invalid PWRDN_DLY val %d (min=%d max=%d)\n", tmp, PWRDN_DELAY_MIN_MS, PWRDN_DELAY_MAX_MS); return -EINVAL; } for (i = 0; i < ARRAY_SIZE(pwrup_pwrdn_ms); i++) { if (tmp == pwrup_pwrdn_ms[i]) { lcdb->pwrdn_delay_ms = i; break; } } } return 0; } static int qpnp_lcdb_regulator_probe(struct platform_device *pdev) Loading Loading
Documentation/devicetree/bindings/regulator/qpnp-lcdb-regulator.txt +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ First Level Node - LCDB module to be enabled only on platforms where voltage needs to be ramped up with multiple steps. - qcom,pwrdn-delay-ms Usage: optional Value type: <u32> Definition: Required to control the LDO power down delay. Possible values are 0, 1, 4, 8. Touch-to-wake (TTW) properties: TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable Loading
drivers/regulator/qpnp-lcdb-regulator.c +94 −2 Original line number Diff line number Diff line Loading @@ -114,6 +114,10 @@ #define PFM_CURRENT_SHIFT 2 #define LCDB_PWRUP_PWRDN_CTL_REG 0x66 #define PWRUP_DELAY_MASK GENAMSK(3, 2) #define PWRDN_DELAY_MASK GENMASK(1, 0) #define PWRDN_DELAY_MIN_MS 0 #define PWRDN_DELAY_MAX_MS 8 /* LDO */ #define LCDB_LDO_OUTPUT_VOLTAGE_REG 0x71 Loading @@ -126,6 +130,10 @@ #define LDO_DIS_PULLDOWN_BIT BIT(1) #define LDO_PD_STRENGTH_BIT BIT(0) #define LCDB_LDO_FORCE_PD_CTL_REG 0x79 #define LDO_FORCE_PD_EN_BIT BIT(0) #define LDO_FORCE_PD_MODE BIT(7) #define LCDB_LDO_ILIM_CTL1_REG 0x7B #define EN_LDO_ILIM_BIT BIT(7) #define SET_LDO_ILIM_MASK GENMASK(2, 0) Loading Loading @@ -220,7 +228,9 @@ struct qpnp_lcdb { struct regmap *regmap; struct pmic_revid_data *pmic_rev_id; u32 base; u32 wa_flags; int sc_irq; int pwrdn_delay_ms; /* TTW params */ bool ttw_enable; Loading Loading @@ -292,6 +302,11 @@ enum lcdb_settings_index { LCDB_SETTING_MAX, }; enum lcdb_wa_flags { NCP_SCP_DISABLE_WA = BIT(0), FORCE_PD_ENABLE_WA = BIT(1), }; static u32 soft_start_us[] = { 0, 500, Loading @@ -313,6 +328,13 @@ static u32 ncp_ilim_ma[] = { 810, }; static const u32 pwrup_pwrdn_ms[] = { 0, 1, 4, 8, }; #define SETTING(_id, _sec_access, _valid) \ [_id] = { \ .address = _id##_REG, \ Loading Loading @@ -915,6 +937,18 @@ static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb) return 0; } if (lcdb->wa_flags & FORCE_PD_ENABLE_WA) { /* * force pull-down to enable quick discharge after * turning off */ val = LDO_FORCE_PD_EN_BIT | LDO_FORCE_PD_MODE; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_FORCE_PD_CTL_REG, &val, 1); if (rc < 0) return rc; } val = 0; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG, &val, 1); Loading @@ -923,6 +957,17 @@ static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb) else lcdb->lcdb_enabled = false; if (lcdb->wa_flags & FORCE_PD_ENABLE_WA) { /* wait for 10 msec after module disable for LDO to discharge */ usleep_range(10000, 11000); val = 0; rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_LDO_FORCE_PD_CTL_REG, &val, 1); if (rc < 0) return rc; } return rc; } Loading Loading @@ -2020,11 +2065,40 @@ static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb) return 0; } static void qpnp_lcdb_pmic_config(struct qpnp_lcdb *lcdb) { switch (lcdb->pmic_rev_id->pmic_subtype) { case PM660L_SUBTYPE: if (lcdb->pmic_rev_id->rev4 < PM660L_V2P0_REV4) lcdb->wa_flags |= NCP_SCP_DISABLE_WA; break; case PMI632_SUBTYPE: case PM6150L_SUBTYPE: lcdb->wa_flags |= FORCE_PD_ENABLE_WA; break; default: break; } pr_debug("LCDB wa_flags = 0x%2x\n", lcdb->wa_flags); } static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb) { int rc = 0; u8 val = 0; qpnp_lcdb_pmic_config(lcdb); if (lcdb->pwrdn_delay_ms != -EINVAL) { rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG, PWRDN_DELAY_MASK, lcdb->pwrdn_delay_ms); if (rc < 0) return rc; } rc = qpnp_lcdb_init_bst(lcdb); if (rc < 0) { pr_err("Failed to initialize BOOST rc=%d\n", rc); Loading Loading @@ -2082,7 +2156,8 @@ static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb) static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb) { int rc = 0; int rc = 0, i = 0; u32 tmp; const char *label; struct device_node *revid_dev_node, *temp, *node = lcdb->dev->of_node; Loading Loading @@ -2146,7 +2221,24 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb) lcdb->voltage_step_ramp = of_property_read_bool(node, "qcom,voltage-step-ramp"); return rc; lcdb->pwrdn_delay_ms = -EINVAL; rc = of_property_read_u32(node, "qcom,pwrdn-delay-ms", &tmp); if (!rc) { if (!is_between(tmp, PWRDN_DELAY_MIN_MS, PWRDN_DELAY_MAX_MS)) { pr_err("Invalid PWRDN_DLY val %d (min=%d max=%d)\n", tmp, PWRDN_DELAY_MIN_MS, PWRDN_DELAY_MAX_MS); return -EINVAL; } for (i = 0; i < ARRAY_SIZE(pwrup_pwrdn_ms); i++) { if (tmp == pwrup_pwrdn_ms[i]) { lcdb->pwrdn_delay_ms = i; break; } } } return 0; } static int qpnp_lcdb_regulator_probe(struct platform_device *pdev) Loading