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 +74 −3 Original line number Diff line number Diff line /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading 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 @@ -223,6 +231,7 @@ struct qpnp_lcdb { u32 base; u32 wa_flags; int sc_irq; int pwrdn_delay_ms; /* TTW params */ bool ttw_enable; Loading Loading @@ -297,6 +306,7 @@ enum lcdb_settings_index { enum lcdb_wa_flags { NCP_SCP_DISABLE_WA = BIT(0), FORCE_PD_ENABLE_WA = BIT(1), }; static u32 soft_start_us[] = { Loading @@ -320,6 +330,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 @@ -922,6 +939,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 @@ -930,6 +959,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 @@ -2052,6 +2092,10 @@ static void qpnp_lcdb_pmic_config(struct qpnp_lcdb *lcdb) if (lcdb->pmic_rev_id->rev4 < PM660L_V2P0_REV4) lcdb->wa_flags |= NCP_SCP_DISABLE_WA; break; case PMI632_SUBTYPE: case PM855L_SUBTYPE: lcdb->wa_flags |= FORCE_PD_ENABLE_WA; break; default: break; } Loading @@ -2066,6 +2110,15 @@ static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb) 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 @@ -2124,7 +2177,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 @@ -2189,7 +2243,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 ssize_t qpnp_lcdb_irq_control(struct class *c, 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 +74 −3 Original line number Diff line number Diff line /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading 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 @@ -223,6 +231,7 @@ struct qpnp_lcdb { u32 base; u32 wa_flags; int sc_irq; int pwrdn_delay_ms; /* TTW params */ bool ttw_enable; Loading Loading @@ -297,6 +306,7 @@ enum lcdb_settings_index { enum lcdb_wa_flags { NCP_SCP_DISABLE_WA = BIT(0), FORCE_PD_ENABLE_WA = BIT(1), }; static u32 soft_start_us[] = { Loading @@ -320,6 +330,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 @@ -922,6 +939,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 @@ -930,6 +959,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 @@ -2052,6 +2092,10 @@ static void qpnp_lcdb_pmic_config(struct qpnp_lcdb *lcdb) if (lcdb->pmic_rev_id->rev4 < PM660L_V2P0_REV4) lcdb->wa_flags |= NCP_SCP_DISABLE_WA; break; case PMI632_SUBTYPE: case PM855L_SUBTYPE: lcdb->wa_flags |= FORCE_PD_ENABLE_WA; break; default: break; } Loading @@ -2066,6 +2110,15 @@ static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb) 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 @@ -2124,7 +2177,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 @@ -2189,7 +2243,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 ssize_t qpnp_lcdb_irq_control(struct class *c, Loading