Loading drivers/power/supply/qcom/battery.c +125 −68 Original line number Original line Diff line number Diff line Loading @@ -197,6 +197,34 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode) return pval.intval; return pval.intval; } } static int get_hvdcp3_icl_limit(struct pl_data *chip) { int rc, main_icl, target_icl = -EINVAL; union power_supply_propval pval = {0, }; rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE, &pval); if ((rc < 0) || (pval.intval != POWER_SUPPLY_TYPE_USB_HVDCP_3)) return target_icl; /* * For HVDCP3 adapters, limit max. ILIM as follows: * HVDCP3_ICL: Maximum ICL of HVDCP3 adapter(from DT configuration) * For Parallel input configurations: * VBUS: target_icl = HVDCP3_ICL - main_ICL * VMID: target_icl = HVDCP3_ICL */ target_icl = chip->chg_param->hvdcp3_max_icl_ua; 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; } return target_icl; } /* /* * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect. * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect. * * Loading @@ -212,7 +240,7 @@ 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, main_icl, target_icl = chip->chg_param->hvdcp3_max_icl_ua; int rc, fcc, target_icl; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; if (!is_usb_available(chip)) if (!is_usb_available(chip)) Loading @@ -225,30 +253,8 @@ 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, target_icl = get_hvdcp3_icl_limit(chip); POWER_SUPPLY_PROP_REAL_TYPE, &pval); ilim = (target_icl > 0) ? min(ilim, target_icl) : ilim; 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); Loading Loading @@ -671,14 +677,17 @@ static void get_main_fcc_config(struct pl_data *chip, int *total_fcc) static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, int parallel_fcc_ua) int parallel_fcc_ua) { { int main_set_fcc_ua, total_fcc_ua; int main_set_fcc_ua, total_fcc_ua, target_icl; bool override; if (!chip->chg_param->fcc_step_size_ua) { if (!chip->chg_param->fcc_step_size_ua) { pr_err("Invalid fcc stepper step size, value 0\n"); pr_err("Invalid fcc stepper step size, value 0\n"); return; return; } } if (is_override_vote_enabled_locked(chip->fcc_main_votable)) { total_fcc_ua = main_fcc_ua + parallel_fcc_ua; override = is_override_vote_enabled_locked(chip->fcc_main_votable); if (override) { /* /* * FCC stepper params need re-calculation in override mode * FCC stepper params need re-calculation in override mode * only if there is change in Main or total FCC * only if there is change in Main or total FCC Loading @@ -686,48 +695,99 @@ static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, main_set_fcc_ua = get_effective_result_locked( main_set_fcc_ua = get_effective_result_locked( chip->fcc_main_votable); chip->fcc_main_votable); total_fcc_ua = main_fcc_ua + parallel_fcc_ua; if ((main_set_fcc_ua != chip->override_main_fcc_ua) if ((main_set_fcc_ua != chip->override_main_fcc_ua) || (total_fcc_ua != chip->total_fcc_ua)) { || (total_fcc_ua != chip->total_fcc_ua)) { chip->override_main_fcc_ua = main_set_fcc_ua; chip->override_main_fcc_ua = main_set_fcc_ua; chip->total_fcc_ua = total_fcc_ua; chip->total_fcc_ua = total_fcc_ua; parallel_fcc_ua = (total_fcc_ua - chip->override_main_fcc_ua); } else { } else { goto skip_fcc_step_update; goto skip_fcc_step_update; } } } } /* Read current FCC of main charger */ /* chip->main_fcc_ua = get_effective_result(chip->fcc_main_votable); * If override vote is removed then start main FCC from the chip->main_step_fcc_dir = (main_fcc_ua > chip->main_fcc_ua) ? * last overridden value. STEP_UP : STEP_DOWN; * Clear slave_fcc if requested parallel current is 0 i.e. chip->main_step_fcc_count = abs((main_fcc_ua - chip->main_fcc_ua) / * parallel is disabled. chip->chg_param->fcc_step_size_ua); */ chip->main_step_fcc_residual = abs((main_fcc_ua - chip->main_fcc_ua) % if (chip->override_main_fcc_ua && !override) { chip->chg_param->fcc_step_size_ua); chip->main_fcc_ua = chip->override_main_fcc_ua; chip->override_main_fcc_ua = 0; if (!parallel_fcc_ua) chip->slave_fcc_ua = 0; } else { chip->main_fcc_ua = get_effective_result_locked( chip->fcc_main_votable); } chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ? /* Skip stepping if override vote is applied on main */ if (override) { chip->main_step_fcc_count = 0; chip->main_step_fcc_residual = 0; } else { chip->main_step_fcc_dir = (main_fcc_ua > chip->main_fcc_ua) ? STEP_UP : STEP_DOWN; STEP_UP : STEP_DOWN; chip->parallel_step_fcc_count chip->main_step_fcc_count = = abs((parallel_fcc_ua - chip->slave_fcc_ua) / abs(main_fcc_ua - chip->main_fcc_ua) / chip->chg_param->fcc_step_size_ua); chip->chg_param->fcc_step_size_ua; chip->parallel_step_fcc_residual chip->main_step_fcc_residual = = abs((parallel_fcc_ua - chip->slave_fcc_ua) % abs(main_fcc_ua - chip->main_fcc_ua) % chip->chg_param->fcc_step_size_ua); chip->chg_param->fcc_step_size_ua; } /* Calculate CP_ILIM based on adapter limit and max. FCC */ if (!parallel_fcc_ua && is_cp_available(chip) && override) { if (!chip->cp_ilim_votable) chip->cp_ilim_votable = find_votable("CP_ILIM"); target_icl = get_hvdcp3_icl_limit(chip) * 2; total_fcc_ua -= chip->main_fcc_ua; /* * CP_ILIM = parallel_fcc_ua / 2. * Calculate parallel_fcc_ua as follows: * parallel_fcc_ua is based minimum of total FCC * or adapter's maximum allowed ICL limitation(if adapter * has max. ICL limitations). */ parallel_fcc_ua = (target_icl > 0) ? min(target_icl, total_fcc_ua) : total_fcc_ua; } /* Skip stepping if override vote is applied on CP */ if (chip->cp_ilim_votable && is_override_vote_enabled(chip->cp_ilim_votable)) { chip->parallel_step_fcc_count = 0; chip->parallel_step_fcc_residual = 0; } else { chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ? STEP_UP : STEP_DOWN; chip->parallel_step_fcc_count = abs(parallel_fcc_ua - chip->slave_fcc_ua) / chip->chg_param->fcc_step_size_ua; chip->parallel_step_fcc_residual = abs(parallel_fcc_ua - chip->slave_fcc_ua) % chip->chg_param->fcc_step_size_ua; } skip_fcc_step_update: skip_fcc_step_update: if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual || chip->main_step_fcc_count || chip->main_step_fcc_residual) || chip->main_step_fcc_count || chip->main_step_fcc_residual) chip->step_fcc = 1; chip->step_fcc = 1; pr_debug("Main FCC Stepper parameters: main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d\n", pl_dbg(chip, PR_PARALLEL, chip->main_step_fcc_dir, chip->main_step_fcc_count, "Main FCC Stepper parameters: target_main_fcc: %d, current_main_fcc: %d main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d override_main_fcc_ua: %d override: %d\n", chip->main_step_fcc_residual); main_fcc_ua, chip->main_fcc_ua, chip->main_step_fcc_dir, pr_debug("Parallel FCC Stepper parameters: parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n", chip->main_step_fcc_count, chip->main_step_fcc_residual, chip->override_main_fcc_ua, override); pl_dbg(chip, PR_PARALLEL, "Parallel FCC Stepper parameters: target_pl_fcc: %d current_pl_fcc: %d parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n", parallel_fcc_ua, chip->slave_fcc_ua, chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count, chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count, chip->parallel_step_fcc_residual); chip->parallel_step_fcc_residual); pl_dbg(chip, PR_PARALLEL, "FCC Stepper parameters: step_fcc=%d\n", chip->step_fcc); } } #define MINIMUM_PARALLEL_FCC_UA 500000 #define MINIMUM_PARALLEL_FCC_UA 500000 Loading Loading @@ -853,7 +913,7 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, { { struct pl_data *chip = data; struct pl_data *chip = data; int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; int main_fcc_ua = 0, cp_fcc_ua = 0, fcc_thr_ua = 0, rc; int cp_fcc_ua = 0, fcc_thr_ua = 0, rc; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; bool is_cc_mode = false; bool is_cc_mode = false; Loading Loading @@ -900,14 +960,14 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, (4 * pval.intval); (4 * pval.intval); } } if (chip->fcc_main_votable) /* main_fcc_ua = * CP charger current = Total FCC - Main charger's FCC. get_effective_result_locked(chip->fcc_main_votable); * Main charger FCC is userspace's override vote on main. */ if (main_fcc_ua < 0) cp_fcc_ua = total_fcc_ua - chip->chg_param->forced_main_fcc; main_fcc_ua = 0; pl_dbg(chip, PR_PARALLEL, "cp_fcc_ua=%d total_fcc_ua=%d forced_main_fcc=%d\n", cp_fcc_ua = total_fcc_ua - main_fcc_ua; cp_fcc_ua, total_fcc_ua, chip->chg_param->forced_main_fcc); if (cp_fcc_ua > 0) { if (cp_fcc_ua > 0) { if (chip->cp_slave_psy && chip->cp_slave_disable_votable) { if (chip->cp_slave_psy && chip->cp_slave_disable_votable) { /* /* Loading Loading @@ -1482,13 +1542,6 @@ static int pl_disable_vote_callback(struct votable *votable, if (chip->step_fcc) { if (chip->step_fcc) { vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, true, 0); true, 0); /* * Configure ILIM above min ILIM of CP to * ensure CP is not disabled due to ILIM vote. * Later FCC stepper will take to ILIM to * target value. */ cp_configure_ilim(chip, FCC_VOTER, 0); schedule_delayed_work(&chip->fcc_stepper_work, schedule_delayed_work(&chip->fcc_stepper_work, 0); 0); } } Loading Loading @@ -1781,6 +1834,10 @@ static void handle_usb_change(struct pl_data *chip) vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER, vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER, false, 0); false, 0); vote(chip->pl_disable_votable, ICL_LIMIT_VOTER, false, 0); vote(chip->pl_disable_votable, ICL_LIMIT_VOTER, false, 0); chip->override_main_fcc_ua = 0; chip->total_fcc_ua = 0; chip->slave_fcc_ua = 0; chip->main_fcc_ua = 0; } } } } Loading drivers/power/supply/qcom/battery.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ struct charger_param { u32 fcc_step_size_ua; u32 fcc_step_size_ua; u32 smb_version; u32 smb_version; u32 hvdcp3_max_icl_ua; u32 hvdcp3_max_icl_ua; u32 forced_main_fcc; }; }; int qcom_batt_init(struct charger_param *param); int qcom_batt_init(struct charger_param *param); Loading drivers/power/supply/qcom/qpnp-smb5.c +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1310,6 +1310,9 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: vote_override(chg->fcc_main_votable, CC_MODE_VOTER, vote_override(chg->fcc_main_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); (val->intval < 0) ? false : true, val->intval); if (val->intval >= 0) chg->chg_param.forced_main_fcc = val->intval; /* Main FCC updated re-calculate FCC */ /* Main FCC updated re-calculate FCC */ rerun_election(chg->fcc_votable); rerun_election(chg->fcc_votable); break; break; Loading drivers/power/supply/qcom/smb5-lib.c +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1188,6 +1188,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) chg->usb_icl_delta_ua = 0; chg->usb_icl_delta_ua = 0; chg->pulse_cnt = 0; chg->pulse_cnt = 0; chg->uusb_apsd_rerun_done = false; chg->uusb_apsd_rerun_done = false; chg->chg_param.forced_main_fcc = 0; /* write back the default FLOAT charger configuration */ /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, Loading Loading @@ -5723,6 +5724,7 @@ static void typec_src_removal(struct smb_charger *chg) chg->voltage_min_uv = MICRO_5V; chg->voltage_min_uv = MICRO_5V; chg->voltage_max_uv = MICRO_5V; chg->voltage_max_uv = MICRO_5V; chg->usbin_forced_max_uv = 0; chg->usbin_forced_max_uv = 0; chg->chg_param.forced_main_fcc = 0; /* Reset CC mode votes */ /* Reset CC mode votes */ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); Loading Loading
drivers/power/supply/qcom/battery.c +125 −68 Original line number Original line Diff line number Diff line Loading @@ -197,6 +197,34 @@ static int cp_get_parallel_mode(struct pl_data *chip, int mode) return pval.intval; return pval.intval; } } static int get_hvdcp3_icl_limit(struct pl_data *chip) { int rc, main_icl, target_icl = -EINVAL; union power_supply_propval pval = {0, }; rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE, &pval); if ((rc < 0) || (pval.intval != POWER_SUPPLY_TYPE_USB_HVDCP_3)) return target_icl; /* * For HVDCP3 adapters, limit max. ILIM as follows: * HVDCP3_ICL: Maximum ICL of HVDCP3 adapter(from DT configuration) * For Parallel input configurations: * VBUS: target_icl = HVDCP3_ICL - main_ICL * VMID: target_icl = HVDCP3_ICL */ target_icl = chip->chg_param->hvdcp3_max_icl_ua; 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; } return target_icl; } /* /* * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect. * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect. * * Loading @@ -212,7 +240,7 @@ 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, main_icl, target_icl = chip->chg_param->hvdcp3_max_icl_ua; int rc, fcc, target_icl; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; if (!is_usb_available(chip)) if (!is_usb_available(chip)) Loading @@ -225,30 +253,8 @@ 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, target_icl = get_hvdcp3_icl_limit(chip); POWER_SUPPLY_PROP_REAL_TYPE, &pval); ilim = (target_icl > 0) ? min(ilim, target_icl) : ilim; 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); Loading Loading @@ -671,14 +677,17 @@ static void get_main_fcc_config(struct pl_data *chip, int *total_fcc) static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, int parallel_fcc_ua) int parallel_fcc_ua) { { int main_set_fcc_ua, total_fcc_ua; int main_set_fcc_ua, total_fcc_ua, target_icl; bool override; if (!chip->chg_param->fcc_step_size_ua) { if (!chip->chg_param->fcc_step_size_ua) { pr_err("Invalid fcc stepper step size, value 0\n"); pr_err("Invalid fcc stepper step size, value 0\n"); return; return; } } if (is_override_vote_enabled_locked(chip->fcc_main_votable)) { total_fcc_ua = main_fcc_ua + parallel_fcc_ua; override = is_override_vote_enabled_locked(chip->fcc_main_votable); if (override) { /* /* * FCC stepper params need re-calculation in override mode * FCC stepper params need re-calculation in override mode * only if there is change in Main or total FCC * only if there is change in Main or total FCC Loading @@ -686,48 +695,99 @@ static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua, main_set_fcc_ua = get_effective_result_locked( main_set_fcc_ua = get_effective_result_locked( chip->fcc_main_votable); chip->fcc_main_votable); total_fcc_ua = main_fcc_ua + parallel_fcc_ua; if ((main_set_fcc_ua != chip->override_main_fcc_ua) if ((main_set_fcc_ua != chip->override_main_fcc_ua) || (total_fcc_ua != chip->total_fcc_ua)) { || (total_fcc_ua != chip->total_fcc_ua)) { chip->override_main_fcc_ua = main_set_fcc_ua; chip->override_main_fcc_ua = main_set_fcc_ua; chip->total_fcc_ua = total_fcc_ua; chip->total_fcc_ua = total_fcc_ua; parallel_fcc_ua = (total_fcc_ua - chip->override_main_fcc_ua); } else { } else { goto skip_fcc_step_update; goto skip_fcc_step_update; } } } } /* Read current FCC of main charger */ /* chip->main_fcc_ua = get_effective_result(chip->fcc_main_votable); * If override vote is removed then start main FCC from the chip->main_step_fcc_dir = (main_fcc_ua > chip->main_fcc_ua) ? * last overridden value. STEP_UP : STEP_DOWN; * Clear slave_fcc if requested parallel current is 0 i.e. chip->main_step_fcc_count = abs((main_fcc_ua - chip->main_fcc_ua) / * parallel is disabled. chip->chg_param->fcc_step_size_ua); */ chip->main_step_fcc_residual = abs((main_fcc_ua - chip->main_fcc_ua) % if (chip->override_main_fcc_ua && !override) { chip->chg_param->fcc_step_size_ua); chip->main_fcc_ua = chip->override_main_fcc_ua; chip->override_main_fcc_ua = 0; if (!parallel_fcc_ua) chip->slave_fcc_ua = 0; } else { chip->main_fcc_ua = get_effective_result_locked( chip->fcc_main_votable); } chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ? /* Skip stepping if override vote is applied on main */ if (override) { chip->main_step_fcc_count = 0; chip->main_step_fcc_residual = 0; } else { chip->main_step_fcc_dir = (main_fcc_ua > chip->main_fcc_ua) ? STEP_UP : STEP_DOWN; STEP_UP : STEP_DOWN; chip->parallel_step_fcc_count chip->main_step_fcc_count = = abs((parallel_fcc_ua - chip->slave_fcc_ua) / abs(main_fcc_ua - chip->main_fcc_ua) / chip->chg_param->fcc_step_size_ua); chip->chg_param->fcc_step_size_ua; chip->parallel_step_fcc_residual chip->main_step_fcc_residual = = abs((parallel_fcc_ua - chip->slave_fcc_ua) % abs(main_fcc_ua - chip->main_fcc_ua) % chip->chg_param->fcc_step_size_ua); chip->chg_param->fcc_step_size_ua; } /* Calculate CP_ILIM based on adapter limit and max. FCC */ if (!parallel_fcc_ua && is_cp_available(chip) && override) { if (!chip->cp_ilim_votable) chip->cp_ilim_votable = find_votable("CP_ILIM"); target_icl = get_hvdcp3_icl_limit(chip) * 2; total_fcc_ua -= chip->main_fcc_ua; /* * CP_ILIM = parallel_fcc_ua / 2. * Calculate parallel_fcc_ua as follows: * parallel_fcc_ua is based minimum of total FCC * or adapter's maximum allowed ICL limitation(if adapter * has max. ICL limitations). */ parallel_fcc_ua = (target_icl > 0) ? min(target_icl, total_fcc_ua) : total_fcc_ua; } /* Skip stepping if override vote is applied on CP */ if (chip->cp_ilim_votable && is_override_vote_enabled(chip->cp_ilim_votable)) { chip->parallel_step_fcc_count = 0; chip->parallel_step_fcc_residual = 0; } else { chip->parallel_step_fcc_dir = (parallel_fcc_ua > chip->slave_fcc_ua) ? STEP_UP : STEP_DOWN; chip->parallel_step_fcc_count = abs(parallel_fcc_ua - chip->slave_fcc_ua) / chip->chg_param->fcc_step_size_ua; chip->parallel_step_fcc_residual = abs(parallel_fcc_ua - chip->slave_fcc_ua) % chip->chg_param->fcc_step_size_ua; } skip_fcc_step_update: skip_fcc_step_update: if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual if (chip->parallel_step_fcc_count || chip->parallel_step_fcc_residual || chip->main_step_fcc_count || chip->main_step_fcc_residual) || chip->main_step_fcc_count || chip->main_step_fcc_residual) chip->step_fcc = 1; chip->step_fcc = 1; pr_debug("Main FCC Stepper parameters: main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d\n", pl_dbg(chip, PR_PARALLEL, chip->main_step_fcc_dir, chip->main_step_fcc_count, "Main FCC Stepper parameters: target_main_fcc: %d, current_main_fcc: %d main_step_direction: %d, main_step_count: %d, main_residual_fcc: %d override_main_fcc_ua: %d override: %d\n", chip->main_step_fcc_residual); main_fcc_ua, chip->main_fcc_ua, chip->main_step_fcc_dir, pr_debug("Parallel FCC Stepper parameters: parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n", chip->main_step_fcc_count, chip->main_step_fcc_residual, chip->override_main_fcc_ua, override); pl_dbg(chip, PR_PARALLEL, "Parallel FCC Stepper parameters: target_pl_fcc: %d current_pl_fcc: %d parallel_step_direction: %d, parallel_step_count: %d, parallel_residual_fcc: %d\n", parallel_fcc_ua, chip->slave_fcc_ua, chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count, chip->parallel_step_fcc_dir, chip->parallel_step_fcc_count, chip->parallel_step_fcc_residual); chip->parallel_step_fcc_residual); pl_dbg(chip, PR_PARALLEL, "FCC Stepper parameters: step_fcc=%d\n", chip->step_fcc); } } #define MINIMUM_PARALLEL_FCC_UA 500000 #define MINIMUM_PARALLEL_FCC_UA 500000 Loading Loading @@ -853,7 +913,7 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, { { struct pl_data *chip = data; struct pl_data *chip = data; int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; int master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; int main_fcc_ua = 0, cp_fcc_ua = 0, fcc_thr_ua = 0, rc; int cp_fcc_ua = 0, fcc_thr_ua = 0, rc; union power_supply_propval pval = {0, }; union power_supply_propval pval = {0, }; bool is_cc_mode = false; bool is_cc_mode = false; Loading Loading @@ -900,14 +960,14 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, (4 * pval.intval); (4 * pval.intval); } } if (chip->fcc_main_votable) /* main_fcc_ua = * CP charger current = Total FCC - Main charger's FCC. get_effective_result_locked(chip->fcc_main_votable); * Main charger FCC is userspace's override vote on main. */ if (main_fcc_ua < 0) cp_fcc_ua = total_fcc_ua - chip->chg_param->forced_main_fcc; main_fcc_ua = 0; pl_dbg(chip, PR_PARALLEL, "cp_fcc_ua=%d total_fcc_ua=%d forced_main_fcc=%d\n", cp_fcc_ua = total_fcc_ua - main_fcc_ua; cp_fcc_ua, total_fcc_ua, chip->chg_param->forced_main_fcc); if (cp_fcc_ua > 0) { if (cp_fcc_ua > 0) { if (chip->cp_slave_psy && chip->cp_slave_disable_votable) { if (chip->cp_slave_psy && chip->cp_slave_disable_votable) { /* /* Loading Loading @@ -1482,13 +1542,6 @@ static int pl_disable_vote_callback(struct votable *votable, if (chip->step_fcc) { if (chip->step_fcc) { vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, vote(chip->pl_awake_votable, FCC_STEPPER_VOTER, true, 0); true, 0); /* * Configure ILIM above min ILIM of CP to * ensure CP is not disabled due to ILIM vote. * Later FCC stepper will take to ILIM to * target value. */ cp_configure_ilim(chip, FCC_VOTER, 0); schedule_delayed_work(&chip->fcc_stepper_work, schedule_delayed_work(&chip->fcc_stepper_work, 0); 0); } } Loading Loading @@ -1781,6 +1834,10 @@ static void handle_usb_change(struct pl_data *chip) vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER, vote(chip->pl_disable_votable, PL_TAPER_EARLY_BAD_VOTER, false, 0); false, 0); vote(chip->pl_disable_votable, ICL_LIMIT_VOTER, false, 0); vote(chip->pl_disable_votable, ICL_LIMIT_VOTER, false, 0); chip->override_main_fcc_ua = 0; chip->total_fcc_ua = 0; chip->slave_fcc_ua = 0; chip->main_fcc_ua = 0; } } } } Loading
drivers/power/supply/qcom/battery.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ struct charger_param { u32 fcc_step_size_ua; u32 fcc_step_size_ua; u32 smb_version; u32 smb_version; u32 hvdcp3_max_icl_ua; u32 hvdcp3_max_icl_ua; u32 forced_main_fcc; }; }; int qcom_batt_init(struct charger_param *param); int qcom_batt_init(struct charger_param *param); Loading
drivers/power/supply/qcom/qpnp-smb5.c +3 −0 Original line number Original line Diff line number Diff line Loading @@ -1310,6 +1310,9 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: vote_override(chg->fcc_main_votable, CC_MODE_VOTER, vote_override(chg->fcc_main_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); (val->intval < 0) ? false : true, val->intval); if (val->intval >= 0) chg->chg_param.forced_main_fcc = val->intval; /* Main FCC updated re-calculate FCC */ /* Main FCC updated re-calculate FCC */ rerun_election(chg->fcc_votable); rerun_election(chg->fcc_votable); break; break; Loading
drivers/power/supply/qcom/smb5-lib.c +2 −0 Original line number Original line Diff line number Diff line Loading @@ -1188,6 +1188,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) chg->usb_icl_delta_ua = 0; chg->usb_icl_delta_ua = 0; chg->pulse_cnt = 0; chg->pulse_cnt = 0; chg->uusb_apsd_rerun_done = false; chg->uusb_apsd_rerun_done = false; chg->chg_param.forced_main_fcc = 0; /* write back the default FLOAT charger configuration */ /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, Loading Loading @@ -5723,6 +5724,7 @@ static void typec_src_removal(struct smb_charger *chg) chg->voltage_min_uv = MICRO_5V; chg->voltage_min_uv = MICRO_5V; chg->voltage_max_uv = MICRO_5V; chg->voltage_max_uv = MICRO_5V; chg->usbin_forced_max_uv = 0; chg->usbin_forced_max_uv = 0; chg->chg_param.forced_main_fcc = 0; /* Reset CC mode votes */ /* Reset CC mode votes */ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); Loading