Loading Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt +4 −1 Original line number Diff line number Diff line Loading @@ -68,9 +68,12 @@ Optional properties for WLED: - qcom,cons-sync-write-delay-us : Specify in 'us' the duration of delay between two consecutive writes to SYNC register. - qcom,sc-deb-cycles : debounce time for short circuit detection - qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3. - qcom,loop-auto-gm-en : A boolean property to specify if auto gm is enabled. - qcom,loop-auto-gm-thresh : Specify auto gm threshold if "loop-auto-gm-en" is defined. Supported values are: 0 - 3. Optional properties if 'qcom,disp-type-amoled' is mentioned in DT: - qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3. - qcom,loop-comp-res-kohm : control to select the compensation resistor in kohm. default is 320. - qcom,vref-psm-mv : reference psm voltage in mv. default for amoled is 450. - qcom,avdd-mode-spmi: Boolean property to enable AMOLED_VOUT programming via SPMI. If not specified, Loading drivers/leds/leds-qpnp-wled.c +96 −30 Original line number Diff line number Diff line Loading @@ -69,11 +69,18 @@ #define QPNP_WLED_LOOP_COMP_RES_STEP_KOHM 20 #define QPNP_WLED_LOOP_COMP_RES_MIN_KOHM 20 #define QPNP_WLED_LOOP_COMP_RES_MAX_KOHM 320 #define QPNP_WLED_VLOOP_COMP_GM_MASK 0xF0 #define QPNP_WLED_VLOOP_COMP_GM_MASK GENMASK(3, 0) #define QPNP_WLED_VLOOP_COMP_GM_OVERWRITE 0x80 #define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED 0x03 #define QPNP_WLED_VLOOP_COMP_AUTO_GM_EN BIT(6) #define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK GENMASK(5, 4) #define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT 4 #define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994 0x03 #define QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMICOBALT 0x09 #define QPNP_WLED_LOOP_GM_DFLT_WLED 0x09 #define QPNP_WLED_LOOP_EA_GM_MIN 0x0 #define QPNP_WLED_LOOP_EA_GM_MAX 0xF #define QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX 3 #define QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH 1 #define QPNP_WLED_VREF_PSM_MASK 0xF8 #define QPNP_WLED_VREF_PSM_STEP_MV 50 #define QPNP_WLED_VREF_PSM_MIN_MV 400 Loading Loading @@ -319,6 +326,8 @@ static struct wled_vref_setting vref_setting_pmicobalt = { * @ cons_sync_write_delay_us - delay between two consecutive writes to SYNC * @ strings - supported list of strings * @ num_strings - number of strings * @ loop_auto_gm_thresh - the clamping level for auto gm * @ loop_auto_gm_en - select if auto gm is enabled * @ avdd_mode_spmi - enable avdd programming via spmi * @ en_9b_dim_res - enable or disable 9bit dimming * @ en_phase_stag - enable or disable phase staggering Loading Loading @@ -362,6 +371,8 @@ struct qpnp_wled { u16 cons_sync_write_delay_us; u8 strings[QPNP_WLED_MAX_STRINGS]; u8 num_strings; u8 loop_auto_gm_thresh; bool loop_auto_gm_en; bool avdd_mode_spmi; bool en_9b_dim_res; bool en_phase_stag; Loading Loading @@ -987,24 +998,6 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr) if (rc) return rc; /* Configure the LOOP COMP GM register for AMOLED */ if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN; else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX; rc = qpnp_wled_read_reg(wled, ®, QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); if (rc < 0) return rc; reg &= QPNP_WLED_VLOOP_COMP_GM_MASK; reg |= (wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE); rc = qpnp_wled_write_reg(wled, reg, QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); if (rc) return rc; /* Configure the CTRL TEST4 register for AMOLED */ rc = qpnp_wled_read_reg(wled, ®, QPNP_WLED_TEST4_REG(wled->ctrl_base)); Loading Loading @@ -1084,6 +1077,45 @@ static bool is_avdd_trim_adjustment_required(struct qpnp_wled *wled) return !(reg & QPNP_WLED_AVDD_SET_BIT); } static int qpnp_wled_gm_config(struct qpnp_wled *wled) { int rc; u8 mask = 0, reg = 0; /* Configure the LOOP COMP GM register */ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { if (wled->loop_auto_gm_en) reg |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN; if (wled->loop_auto_gm_thresh > QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX) wled->loop_auto_gm_thresh = QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX; reg |= wled->loop_auto_gm_thresh << QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT; mask |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN | QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK; } if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN; else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX; reg |= wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE; mask |= QPNP_WLED_VLOOP_COMP_GM_MASK | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE; rc = qpnp_wled_masked_write_reg(wled, mask, ®, QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); if (rc) pr_err("write VLOOP_COMP_GM_REG failed, rc=%d]\n", rc); return rc; } static int qpnp_wled_ovp_config(struct qpnp_wled *wled) { int rc, i, *ovp_table; Loading Loading @@ -1317,6 +1349,13 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; } /* Configure VLOOP_COMP_GM register */ rc = qpnp_wled_gm_config(wled); if (rc < 0) { pr_err("Error in configureing wled gm, rc=%d\n", rc); return rc; } /* Configure the ILIM register */ rc = qpnp_wled_ilim_config(wled); if (rc < 0) { Loading Loading @@ -1689,16 +1728,6 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED; rc = of_property_read_u32(pdev->dev.of_node, "qcom,loop-ea-gm", &temp_val); if (!rc) { wled->loop_ea_gm = temp_val; } else if (rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read loop-ea-gm\n"); return rc; } wled->avdd_mode_spmi = of_property_read_bool(pdev->dev.of_node, "qcom,avdd-mode-spmi"); Loading @@ -1713,6 +1742,43 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) } } if (wled->disp_type_amoled) { if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) wled->loop_ea_gm = QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMICOBALT; else wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994; } else { wled->loop_ea_gm = QPNP_WLED_LOOP_GM_DFLT_WLED; } rc = of_property_read_u32(pdev->dev.of_node, "qcom,loop-ea-gm", &temp_val); if (!rc) { wled->loop_ea_gm = temp_val; } else if (rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read loop-ea-gm\n"); return rc; } if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { wled->loop_auto_gm_en = of_property_read_bool(pdev->dev.of_node, "qcom,loop-auto-gm-en"); wled->loop_auto_gm_thresh = QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH; rc = of_property_read_u8(pdev->dev.of_node, "qcom,loop-auto-gm-thresh", &wled->loop_auto_gm_thresh); if (rc && rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read loop-auto-gm-thresh\n"); return rc; } } wled->sc_deb_cycles = QPNP_WLED_SC_DEB_CYCLES_DFLT; rc = of_property_read_u32(pdev->dev.of_node, "qcom,sc-deb-cycles", &temp_val); Loading Loading
Documentation/devicetree/bindings/leds/leds-qpnp-wled.txt +4 −1 Original line number Diff line number Diff line Loading @@ -68,9 +68,12 @@ Optional properties for WLED: - qcom,cons-sync-write-delay-us : Specify in 'us' the duration of delay between two consecutive writes to SYNC register. - qcom,sc-deb-cycles : debounce time for short circuit detection - qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3. - qcom,loop-auto-gm-en : A boolean property to specify if auto gm is enabled. - qcom,loop-auto-gm-thresh : Specify auto gm threshold if "loop-auto-gm-en" is defined. Supported values are: 0 - 3. Optional properties if 'qcom,disp-type-amoled' is mentioned in DT: - qcom,loop-ea-gm : control the gm for gm stage in control loop. default is 3. - qcom,loop-comp-res-kohm : control to select the compensation resistor in kohm. default is 320. - qcom,vref-psm-mv : reference psm voltage in mv. default for amoled is 450. - qcom,avdd-mode-spmi: Boolean property to enable AMOLED_VOUT programming via SPMI. If not specified, Loading
drivers/leds/leds-qpnp-wled.c +96 −30 Original line number Diff line number Diff line Loading @@ -69,11 +69,18 @@ #define QPNP_WLED_LOOP_COMP_RES_STEP_KOHM 20 #define QPNP_WLED_LOOP_COMP_RES_MIN_KOHM 20 #define QPNP_WLED_LOOP_COMP_RES_MAX_KOHM 320 #define QPNP_WLED_VLOOP_COMP_GM_MASK 0xF0 #define QPNP_WLED_VLOOP_COMP_GM_MASK GENMASK(3, 0) #define QPNP_WLED_VLOOP_COMP_GM_OVERWRITE 0x80 #define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED 0x03 #define QPNP_WLED_VLOOP_COMP_AUTO_GM_EN BIT(6) #define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK GENMASK(5, 4) #define QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT 4 #define QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994 0x03 #define QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMICOBALT 0x09 #define QPNP_WLED_LOOP_GM_DFLT_WLED 0x09 #define QPNP_WLED_LOOP_EA_GM_MIN 0x0 #define QPNP_WLED_LOOP_EA_GM_MAX 0xF #define QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX 3 #define QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH 1 #define QPNP_WLED_VREF_PSM_MASK 0xF8 #define QPNP_WLED_VREF_PSM_STEP_MV 50 #define QPNP_WLED_VREF_PSM_MIN_MV 400 Loading Loading @@ -319,6 +326,8 @@ static struct wled_vref_setting vref_setting_pmicobalt = { * @ cons_sync_write_delay_us - delay between two consecutive writes to SYNC * @ strings - supported list of strings * @ num_strings - number of strings * @ loop_auto_gm_thresh - the clamping level for auto gm * @ loop_auto_gm_en - select if auto gm is enabled * @ avdd_mode_spmi - enable avdd programming via spmi * @ en_9b_dim_res - enable or disable 9bit dimming * @ en_phase_stag - enable or disable phase staggering Loading Loading @@ -362,6 +371,8 @@ struct qpnp_wled { u16 cons_sync_write_delay_us; u8 strings[QPNP_WLED_MAX_STRINGS]; u8 num_strings; u8 loop_auto_gm_thresh; bool loop_auto_gm_en; bool avdd_mode_spmi; bool en_9b_dim_res; bool en_phase_stag; Loading Loading @@ -987,24 +998,6 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr) if (rc) return rc; /* Configure the LOOP COMP GM register for AMOLED */ if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN; else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX; rc = qpnp_wled_read_reg(wled, ®, QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); if (rc < 0) return rc; reg &= QPNP_WLED_VLOOP_COMP_GM_MASK; reg |= (wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE); rc = qpnp_wled_write_reg(wled, reg, QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); if (rc) return rc; /* Configure the CTRL TEST4 register for AMOLED */ rc = qpnp_wled_read_reg(wled, ®, QPNP_WLED_TEST4_REG(wled->ctrl_base)); Loading Loading @@ -1084,6 +1077,45 @@ static bool is_avdd_trim_adjustment_required(struct qpnp_wled *wled) return !(reg & QPNP_WLED_AVDD_SET_BIT); } static int qpnp_wled_gm_config(struct qpnp_wled *wled) { int rc; u8 mask = 0, reg = 0; /* Configure the LOOP COMP GM register */ if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { if (wled->loop_auto_gm_en) reg |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN; if (wled->loop_auto_gm_thresh > QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX) wled->loop_auto_gm_thresh = QPNP_WLED_LOOP_AUTO_GM_THRESH_MAX; reg |= wled->loop_auto_gm_thresh << QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_SHIFT; mask |= QPNP_WLED_VLOOP_COMP_AUTO_GM_EN | QPNP_WLED_VLOOP_COMP_AUTO_GM_THRESH_MASK; } if (wled->loop_ea_gm < QPNP_WLED_LOOP_EA_GM_MIN) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MIN; else if (wled->loop_ea_gm > QPNP_WLED_LOOP_EA_GM_MAX) wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_MAX; reg |= wled->loop_ea_gm | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE; mask |= QPNP_WLED_VLOOP_COMP_GM_MASK | QPNP_WLED_VLOOP_COMP_GM_OVERWRITE; rc = qpnp_wled_masked_write_reg(wled, mask, ®, QPNP_WLED_VLOOP_COMP_GM_REG(wled->ctrl_base)); if (rc) pr_err("write VLOOP_COMP_GM_REG failed, rc=%d]\n", rc); return rc; } static int qpnp_wled_ovp_config(struct qpnp_wled *wled) { int rc, i, *ovp_table; Loading Loading @@ -1317,6 +1349,13 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; } /* Configure VLOOP_COMP_GM register */ rc = qpnp_wled_gm_config(wled); if (rc < 0) { pr_err("Error in configureing wled gm, rc=%d\n", rc); return rc; } /* Configure the ILIM register */ rc = qpnp_wled_ilim_config(wled); if (rc < 0) { Loading Loading @@ -1689,16 +1728,6 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) return rc; } wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED; rc = of_property_read_u32(pdev->dev.of_node, "qcom,loop-ea-gm", &temp_val); if (!rc) { wled->loop_ea_gm = temp_val; } else if (rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read loop-ea-gm\n"); return rc; } wled->avdd_mode_spmi = of_property_read_bool(pdev->dev.of_node, "qcom,avdd-mode-spmi"); Loading @@ -1713,6 +1742,43 @@ static int qpnp_wled_parse_dt(struct qpnp_wled *wled) } } if (wled->disp_type_amoled) { if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) wled->loop_ea_gm = QPNP_WLED_LOOP_GM_DFLT_AMOLED_PMICOBALT; else wled->loop_ea_gm = QPNP_WLED_LOOP_EA_GM_DFLT_AMOLED_PMI8994; } else { wled->loop_ea_gm = QPNP_WLED_LOOP_GM_DFLT_WLED; } rc = of_property_read_u32(pdev->dev.of_node, "qcom,loop-ea-gm", &temp_val); if (!rc) { wled->loop_ea_gm = temp_val; } else if (rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read loop-ea-gm\n"); return rc; } if (wled->pmic_rev_id->pmic_subtype == PMICOBALT_SUBTYPE || wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) { wled->loop_auto_gm_en = of_property_read_bool(pdev->dev.of_node, "qcom,loop-auto-gm-en"); wled->loop_auto_gm_thresh = QPNP_WLED_LOOP_AUTO_GM_DFLT_THRESH; rc = of_property_read_u8(pdev->dev.of_node, "qcom,loop-auto-gm-thresh", &wled->loop_auto_gm_thresh); if (rc && rc != -EINVAL) { dev_err(&pdev->dev, "Unable to read loop-auto-gm-thresh\n"); return rc; } } wled->sc_deb_cycles = QPNP_WLED_SC_DEB_CYCLES_DFLT; rc = of_property_read_u32(pdev->dev.of_node, "qcom,sc-deb-cycles", &temp_val); Loading