Loading drivers/power/supply/qcom/battery.c +42 −1 Original line number Original line Diff line number Diff line Loading @@ -142,6 +142,15 @@ enum { /********* /********* * HELPER* * HELPER* *********/ *********/ static bool is_usb_available(struct pl_data *chip) { if (!chip->usb_psy) chip->usb_psy = power_supply_get_by_name("usb"); return !!chip->usb_psy; } static bool is_cp_available(struct pl_data *chip) static bool is_cp_available(struct pl_data *chip) { { if (!chip->cp_master_psy) if (!chip->cp_master_psy) Loading Loading @@ -195,9 +204,12 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode) */ */ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) { { int rc, fcc; int rc, fcc, main_icl, target_icl = chip->chg_param->hvdcp3_max_icl_ua; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; if (!is_usb_available(chip)) return; if (!is_cp_available(chip)) if (!is_cp_available(chip)) return; return; Loading @@ -205,6 +217,31 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) == POWER_SUPPLY_PL_OUTPUT_VPH) == POWER_SUPPLY_PL_OUTPUT_VPH) return; return; rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE, &pval); if (rc < 0) return; /* * For HVDCP3 adapters limit max. ILIM based on DT configuration * of HVDCP3 ICL value. * Input VBUS: * target_icl = HVDCP3_ICL - main_ICL * Input VMID * target_icl = HVDCP3_ICL */ if (pval.intval == POWER_SUPPLY_TYPE_USB_HVDCP_3) { if (((cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE)) == POWER_SUPPLY_PL_USBIN_USBIN)) { main_icl = get_effective_result_locked( chip->usb_icl_votable); if ((main_icl >= 0) && (main_icl < target_icl)) target_icl -= main_icl; } ilim = min(target_icl, ilim); } rc = power_supply_get_property(chip->cp_master_psy, rc = power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_MIN_ICL, &pval); POWER_SUPPLY_PROP_MIN_ICL, &pval); if (rc < 0) if (rc < 0) Loading @@ -226,6 +263,10 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) vote(chip->cp_ilim_votable, voter, true, pval.intval); vote(chip->cp_ilim_votable, voter, true, pval.intval); else else vote(chip->cp_ilim_votable, voter, true, ilim); vote(chip->cp_ilim_votable, voter, true, ilim); pl_dbg(chip, PR_PARALLEL, "ILIM: vote: %d voter:%s min_ilim=%d fcc = %d\n", ilim, voter, pval.intval, fcc); } } } } Loading drivers/power/supply/qcom/battery.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -10,6 +10,7 @@ struct charger_param { u32 fcc_step_delay_ms; u32 fcc_step_delay_ms; u32 fcc_step_size_ua; u32 fcc_step_size_ua; u32 smb_version; u32 smb_version; u32 hvdcp3_max_icl_ua; }; }; int qcom_batt_init(struct charger_param *param); int qcom_batt_init(struct charger_param *param); Loading drivers/power/supply/qcom/qpnp-smb5.c +23 −2 Original line number Original line Diff line number Diff line Loading @@ -584,6 +584,18 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node) if (chg->chg_param.fcc_step_size_ua <= 0) if (chg->chg_param.fcc_step_size_ua <= 0) chg->chg_param.fcc_step_size_ua = DEFAULT_FCC_STEP_SIZE_UA; chg->chg_param.fcc_step_size_ua = DEFAULT_FCC_STEP_SIZE_UA; /* * If property is present parallel charging with CP is disabled * with HVDCP3 adapter. */ chg->hvdcp3_standalone_config = of_property_read_bool(node, "qcom,hvdcp3-standalone-config"); of_property_read_u32(node, "qcom,hvdcp3-max-icl-ua", &chg->chg_param.hvdcp3_max_icl_ua); if (chg->chg_param.hvdcp3_max_icl_ua <= 0) chg->chg_param.hvdcp3_max_icl_ua = MICRO_3PA; return 0; return 0; } } Loading Loading @@ -1293,14 +1305,20 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, struct smb5 *chip = power_supply_get_drvdata(psy); struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; struct smb_charger *chg = &chip->chg; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; int rc = 0; int rc = 0, offset_ua = 0; switch (psp) { switch (psp) { case POWER_SUPPLY_PROP_VOLTAGE_MAX: case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval); rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval); break; break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); /* Adjust Main FCC for QC3.0 + SMB1390 */ rc = smblib_get_qc3_main_icl_offset(chg, &offset_ua); if (rc < 0) offset_ua = 0; rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval + offset_ua); break; break; case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_set_icl_current(chg, val->intval); rc = smblib_set_icl_current(chg, val->intval); Loading Loading @@ -1352,6 +1370,9 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: vote_override(chg->usb_icl_votable, CC_MODE_VOTER, vote_override(chg->usb_icl_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); (val->intval < 0) ? false : true, val->intval); /* Main ICL updated re-calculate ILIM */ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) rerun_election(chg->fcc_votable); break; break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = smb5_set_prop_comp_clamp_level(chg, val); rc = smb5_set_prop_comp_clamp_level(chg, val); Loading drivers/power/supply/qcom/smb1390-charger-psy.c +9 −0 Original line number Original line Diff line number Diff line Loading @@ -1096,6 +1096,12 @@ static void smb1390_status_change_work(struct work_struct *work) goto out; goto out; } } /* * Slave SMB1390 is not required for the power-rating of QC3 */ if (pval.intval != POWER_SUPPLY_CP_HVDCP3) vote(chip->slave_disable_votable, SRC_VOTER, false, 0); /* Check for SOC threshold only once before enabling CP */ /* Check for SOC threshold only once before enabling CP */ vote(chip->disable_votable, SRC_VOTER, false, 0); vote(chip->disable_votable, SRC_VOTER, false, 0); if (!chip->batt_soc_validated) { if (!chip->batt_soc_validated) { Loading Loading @@ -1163,6 +1169,7 @@ static void smb1390_status_change_work(struct work_struct *work) } } } else { } else { chip->batt_soc_validated = false; chip->batt_soc_validated = false; vote(chip->slave_disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); Loading Loading @@ -1578,6 +1585,8 @@ static int smb1390_create_votables(struct smb1390 *chip) if (IS_ERR(chip->slave_disable_votable)) if (IS_ERR(chip->slave_disable_votable)) return PTR_ERR(chip->slave_disable_votable); return PTR_ERR(chip->slave_disable_votable); /* Keep slave SMB disabled */ vote(chip->slave_disable_votable, SRC_VOTER, true, 0); /* /* * charge pump is initially disabled; this indirectly votes to allow * charge pump is initially disabled; this indirectly votes to allow * traditional parallel charging if present * traditional parallel charging if present Loading drivers/power/supply/qcom/smb5-lib.c +34 −10 Original line number Original line Diff line number Diff line Loading @@ -872,6 +872,37 @@ int smblib_set_aicl_cont_threshold(struct smb_chg_param *param, /******************** /******************** * HELPER FUNCTIONS * * HELPER FUNCTIONS * ********************/ ********************/ static bool is_cp_available(struct smb_charger *chg) { if (!chg->cp_psy) chg->cp_psy = power_supply_get_by_name("charge_pump_master"); return !!chg->cp_psy; } #define CP_TO_MAIN_ICL_OFFSET_PC 10 int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua) { union power_supply_propval pval = {0, }; int rc; if ((chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) || chg->hvdcp3_standalone_config || !is_cp_available(chg)) { *offset_ua = 0; return 0; } rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ILIM, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get CP ILIM rc=%d\n", rc); return rc; } *offset_ua = (pval.intval * CP_TO_MAIN_ICL_OFFSET_PC * 2) / 100; return 0; } int smblib_get_prop_from_bms(struct smb_charger *chg, int smblib_get_prop_from_bms(struct smb_charger *chg, enum power_supply_property psp, enum power_supply_property psp, Loading Loading @@ -2685,10 +2716,7 @@ static int smblib_update_thermal_readings(struct smb_charger *chg) } } if (chg->sec_chg_selected == POWER_SUPPLY_CHARGER_SEC_CP) { if (chg->sec_chg_selected == POWER_SUPPLY_CHARGER_SEC_CP) { if (!chg->cp_psy) if (is_cp_available(chg)) { chg->cp_psy = power_supply_get_by_name("charge_pump_master"); if (chg->cp_psy) { rc = power_supply_get_property(chg->cp_psy, rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_DIE_TEMP, &pval); POWER_SUPPLY_PROP_CP_DIE_TEMP, &pval); if (rc < 0) { if (rc < 0) { Loading Loading @@ -6216,12 +6244,8 @@ static bool is_cp_topo_vbatt(struct smb_charger *chg) bool is_vbatt; bool is_vbatt; union power_supply_propval pval; union power_supply_propval pval; if (!chg->cp_psy) { if (!is_cp_available(chg)) chg->cp_psy = power_supply_get_by_name("charge_pump_master"); if (!chg->cp_psy) return false; return false; } rc = power_supply_get_property(chg->cp_psy, rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); Loading Loading
drivers/power/supply/qcom/battery.c +42 −1 Original line number Original line Diff line number Diff line Loading @@ -142,6 +142,15 @@ enum { /********* /********* * HELPER* * HELPER* *********/ *********/ static bool is_usb_available(struct pl_data *chip) { if (!chip->usb_psy) chip->usb_psy = power_supply_get_by_name("usb"); return !!chip->usb_psy; } static bool is_cp_available(struct pl_data *chip) static bool is_cp_available(struct pl_data *chip) { { if (!chip->cp_master_psy) if (!chip->cp_master_psy) Loading Loading @@ -195,9 +204,12 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode) */ */ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) { { int rc, fcc; int rc, fcc, main_icl, target_icl = chip->chg_param->hvdcp3_max_icl_ua; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; if (!is_usb_available(chip)) return; if (!is_cp_available(chip)) if (!is_cp_available(chip)) return; return; Loading @@ -205,6 +217,31 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) == POWER_SUPPLY_PL_OUTPUT_VPH) == POWER_SUPPLY_PL_OUTPUT_VPH) return; return; rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE, &pval); if (rc < 0) return; /* * For HVDCP3 adapters limit max. ILIM based on DT configuration * of HVDCP3 ICL value. * Input VBUS: * target_icl = HVDCP3_ICL - main_ICL * Input VMID * target_icl = HVDCP3_ICL */ if (pval.intval == POWER_SUPPLY_TYPE_USB_HVDCP_3) { if (((cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE)) == POWER_SUPPLY_PL_USBIN_USBIN)) { main_icl = get_effective_result_locked( chip->usb_icl_votable); if ((main_icl >= 0) && (main_icl < target_icl)) target_icl -= main_icl; } ilim = min(target_icl, ilim); } rc = power_supply_get_property(chip->cp_master_psy, rc = power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_MIN_ICL, &pval); POWER_SUPPLY_PROP_MIN_ICL, &pval); if (rc < 0) if (rc < 0) Loading @@ -226,6 +263,10 @@ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) vote(chip->cp_ilim_votable, voter, true, pval.intval); vote(chip->cp_ilim_votable, voter, true, pval.intval); else else vote(chip->cp_ilim_votable, voter, true, ilim); vote(chip->cp_ilim_votable, voter, true, ilim); pl_dbg(chip, PR_PARALLEL, "ILIM: vote: %d voter:%s min_ilim=%d fcc = %d\n", ilim, voter, pval.intval, fcc); } } } } Loading
drivers/power/supply/qcom/battery.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -10,6 +10,7 @@ struct charger_param { u32 fcc_step_delay_ms; u32 fcc_step_delay_ms; u32 fcc_step_size_ua; u32 fcc_step_size_ua; u32 smb_version; u32 smb_version; u32 hvdcp3_max_icl_ua; }; }; int qcom_batt_init(struct charger_param *param); int qcom_batt_init(struct charger_param *param); Loading
drivers/power/supply/qcom/qpnp-smb5.c +23 −2 Original line number Original line Diff line number Diff line Loading @@ -584,6 +584,18 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node) if (chg->chg_param.fcc_step_size_ua <= 0) if (chg->chg_param.fcc_step_size_ua <= 0) chg->chg_param.fcc_step_size_ua = DEFAULT_FCC_STEP_SIZE_UA; chg->chg_param.fcc_step_size_ua = DEFAULT_FCC_STEP_SIZE_UA; /* * If property is present parallel charging with CP is disabled * with HVDCP3 adapter. */ chg->hvdcp3_standalone_config = of_property_read_bool(node, "qcom,hvdcp3-standalone-config"); of_property_read_u32(node, "qcom,hvdcp3-max-icl-ua", &chg->chg_param.hvdcp3_max_icl_ua); if (chg->chg_param.hvdcp3_max_icl_ua <= 0) chg->chg_param.hvdcp3_max_icl_ua = MICRO_3PA; return 0; return 0; } } Loading Loading @@ -1293,14 +1305,20 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, struct smb5 *chip = power_supply_get_drvdata(psy); struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; struct smb_charger *chg = &chip->chg; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; int rc = 0; int rc = 0, offset_ua = 0; switch (psp) { switch (psp) { case POWER_SUPPLY_PROP_VOLTAGE_MAX: case POWER_SUPPLY_PROP_VOLTAGE_MAX: rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval); rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval); break; break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); /* Adjust Main FCC for QC3.0 + SMB1390 */ rc = smblib_get_qc3_main_icl_offset(chg, &offset_ua); if (rc < 0) offset_ua = 0; rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval + offset_ua); break; break; case POWER_SUPPLY_PROP_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_set_icl_current(chg, val->intval); rc = smblib_set_icl_current(chg, val->intval); Loading Loading @@ -1352,6 +1370,9 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: vote_override(chg->usb_icl_votable, CC_MODE_VOTER, vote_override(chg->usb_icl_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); (val->intval < 0) ? false : true, val->intval); /* Main ICL updated re-calculate ILIM */ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) rerun_election(chg->fcc_votable); break; break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = smb5_set_prop_comp_clamp_level(chg, val); rc = smb5_set_prop_comp_clamp_level(chg, val); Loading
drivers/power/supply/qcom/smb1390-charger-psy.c +9 −0 Original line number Original line Diff line number Diff line Loading @@ -1096,6 +1096,12 @@ static void smb1390_status_change_work(struct work_struct *work) goto out; goto out; } } /* * Slave SMB1390 is not required for the power-rating of QC3 */ if (pval.intval != POWER_SUPPLY_CP_HVDCP3) vote(chip->slave_disable_votable, SRC_VOTER, false, 0); /* Check for SOC threshold only once before enabling CP */ /* Check for SOC threshold only once before enabling CP */ vote(chip->disable_votable, SRC_VOTER, false, 0); vote(chip->disable_votable, SRC_VOTER, false, 0); if (!chip->batt_soc_validated) { if (!chip->batt_soc_validated) { Loading Loading @@ -1163,6 +1169,7 @@ static void smb1390_status_change_work(struct work_struct *work) } } } else { } else { chip->batt_soc_validated = false; chip->batt_soc_validated = false; vote(chip->slave_disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); Loading Loading @@ -1578,6 +1585,8 @@ static int smb1390_create_votables(struct smb1390 *chip) if (IS_ERR(chip->slave_disable_votable)) if (IS_ERR(chip->slave_disable_votable)) return PTR_ERR(chip->slave_disable_votable); return PTR_ERR(chip->slave_disable_votable); /* Keep slave SMB disabled */ vote(chip->slave_disable_votable, SRC_VOTER, true, 0); /* /* * charge pump is initially disabled; this indirectly votes to allow * charge pump is initially disabled; this indirectly votes to allow * traditional parallel charging if present * traditional parallel charging if present Loading
drivers/power/supply/qcom/smb5-lib.c +34 −10 Original line number Original line Diff line number Diff line Loading @@ -872,6 +872,37 @@ int smblib_set_aicl_cont_threshold(struct smb_chg_param *param, /******************** /******************** * HELPER FUNCTIONS * * HELPER FUNCTIONS * ********************/ ********************/ static bool is_cp_available(struct smb_charger *chg) { if (!chg->cp_psy) chg->cp_psy = power_supply_get_by_name("charge_pump_master"); return !!chg->cp_psy; } #define CP_TO_MAIN_ICL_OFFSET_PC 10 int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua) { union power_supply_propval pval = {0, }; int rc; if ((chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) || chg->hvdcp3_standalone_config || !is_cp_available(chg)) { *offset_ua = 0; return 0; } rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ILIM, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get CP ILIM rc=%d\n", rc); return rc; } *offset_ua = (pval.intval * CP_TO_MAIN_ICL_OFFSET_PC * 2) / 100; return 0; } int smblib_get_prop_from_bms(struct smb_charger *chg, int smblib_get_prop_from_bms(struct smb_charger *chg, enum power_supply_property psp, enum power_supply_property psp, Loading Loading @@ -2685,10 +2716,7 @@ static int smblib_update_thermal_readings(struct smb_charger *chg) } } if (chg->sec_chg_selected == POWER_SUPPLY_CHARGER_SEC_CP) { if (chg->sec_chg_selected == POWER_SUPPLY_CHARGER_SEC_CP) { if (!chg->cp_psy) if (is_cp_available(chg)) { chg->cp_psy = power_supply_get_by_name("charge_pump_master"); if (chg->cp_psy) { rc = power_supply_get_property(chg->cp_psy, rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_DIE_TEMP, &pval); POWER_SUPPLY_PROP_CP_DIE_TEMP, &pval); if (rc < 0) { if (rc < 0) { Loading Loading @@ -6216,12 +6244,8 @@ static bool is_cp_topo_vbatt(struct smb_charger *chg) bool is_vbatt; bool is_vbatt; union power_supply_propval pval; union power_supply_propval pval; if (!chg->cp_psy) { if (!is_cp_available(chg)) chg->cp_psy = power_supply_get_by_name("charge_pump_master"); if (!chg->cp_psy) return false; return false; } rc = power_supply_get_property(chg->cp_psy, rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); Loading