Loading drivers/power/supply/qcom/battery.c +3 −2 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. */ */ #define pr_fmt(fmt) "QCOM-BATT: %s: " fmt, __func__ #define pr_fmt(fmt) "QCOM-BATT: %s: " fmt, __func__ Loading Loading @@ -194,7 +194,8 @@ static int get_hvdcp3_icl_limit(struct pl_data *chip) { { int main_icl, target_icl = -EINVAL; int main_icl, target_icl = -EINVAL; if (chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) if (chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3 && chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5) return target_icl; return target_icl; /* /* Loading drivers/power/supply/qcom/qpnp-smb5.c +3 −1 Original line number Original line Diff line number Diff line Loading @@ -1327,6 +1327,7 @@ 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, }; enum power_supply_type real_chg_type = chg->real_charger_type; int rc = 0, offset_ua = 0; int rc = 0, offset_ua = 0; switch (psp) { switch (psp) { Loading Loading @@ -1402,7 +1403,8 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, 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 */ /* Main ICL updated re-calculate ILIM */ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) if (real_chg_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || real_chg_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) rerun_election(chg->fcc_votable); rerun_election(chg->fcc_votable); break; break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: Loading drivers/power/supply/qcom/smb5-lib.c +28 −6 Original line number Original line Diff line number Diff line Loading @@ -915,7 +915,8 @@ int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua) * - Output connection topology is VBAT * - Output connection topology is VBAT */ */ if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config || (chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3)) || ((chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) && chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5)) return -EINVAL; return -EINVAL; rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ENABLE, rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ENABLE, Loading Loading @@ -1087,6 +1088,8 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) /* if PD is active, APSD is disabled so won't have a valid result */ /* if PD is active, APSD is disabled so won't have a valid result */ if (chg->pd_active) { if (chg->pd_active) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_PD; chg->real_charger_type = POWER_SUPPLY_TYPE_USB_PD; } else if (chg->qc3p5_detected) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_HVDCP_3P5; } else { } else { /* /* * Update real charger type only if its not FLOAT * Update real charger type only if its not FLOAT Loading @@ -1097,8 +1100,8 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) chg->real_charger_type = apsd_result->pst; chg->real_charger_type = apsd_result->pst; } } smblib_dbg(chg, PR_MISC, "APSD=%s PD=%d\n", smblib_dbg(chg, PR_MISC, "APSD=%s PD=%d QC3P5=%d\n", apsd_result->name, chg->pd_active); apsd_result->name, chg->pd_active, chg->qc3p5_detected); return apsd_result; return apsd_result; } } Loading Loading @@ -1285,6 +1288,9 @@ static void smblib_uusb_removal(struct smb_charger *chg) chg->qc2_unsupported_voltage = QC2_COMPLIANT; chg->qc2_unsupported_voltage = QC2_COMPLIANT; } } chg->qc3p5_detected = false; smblib_update_usb_type(chg); } } void smblib_suspend_on_debug_battery(struct smb_charger *chg) void smblib_suspend_on_debug_battery(struct smb_charger *chg) Loading Loading @@ -2536,7 +2542,8 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0); vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0); } } if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { rc = smblib_hvdcp3_set_fsw(chg); rc = smblib_hvdcp3_set_fsw(chg); if (rc < 0) if (rc < 0) smblib_err(chg, "Couldn't set QC3.0 Fsw rc=%d\n", rc); smblib_err(chg, "Couldn't set QC3.0 Fsw rc=%d\n", rc); Loading Loading @@ -2669,6 +2676,10 @@ int smblib_dp_dm(struct smb_charger *chg, int val) if (rc < 0) if (rc < 0) pr_err("Failed to force 12V\n"); pr_err("Failed to force 12V\n"); break; break; case POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5: chg->qc3p5_detected = true; smblib_update_usb_type(chg); break; case POWER_SUPPLY_DP_DM_ICL_UP: case POWER_SUPPLY_DP_DM_ICL_UP: default: default: break; break; Loading Loading @@ -3281,6 +3292,7 @@ int smblib_get_prop_usb_voltage_max_design(struct smb_charger *chg, break; break; } } /* else, fallthrough */ /* else, fallthrough */ case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_PD: case POWER_SUPPLY_TYPE_USB_PD: if (chg->chg_param.smb_version == PMI632_SUBTYPE) if (chg->chg_param.smb_version == PMI632_SUBTYPE) Loading Loading @@ -3310,6 +3322,7 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, break; break; } } /* else, fallthrough */ /* else, fallthrough */ case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: if (chg->chg_param.smb_version == PMI632_SUBTYPE) if (chg->chg_param.smb_version == PMI632_SUBTYPE) val->intval = MICRO_9V; val->intval = MICRO_9V; Loading @@ -3328,15 +3341,20 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, } } #define HVDCP3_STEP_UV 200000 #define HVDCP3_STEP_UV 200000 #define HVDCP3P5_STEP_UV 20000 static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, union power_supply_propval *val) union power_supply_propval *val) { { int step_uv = HVDCP3_STEP_UV; switch (chg->real_charger_type) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_HVDCP: case POWER_SUPPLY_TYPE_USB_HVDCP: val->intval = MICRO_12V; val->intval = MICRO_12V; break; break; case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: step_uv = HVDCP3P5_STEP_UV; case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: val->intval = MICRO_5V + (HVDCP3_STEP_UV * chg->pulse_cnt); val->intval = MICRO_5V + (step_uv * chg->pulse_cnt); break; break; case POWER_SUPPLY_TYPE_USB_PD: case POWER_SUPPLY_TYPE_USB_PD: /* Take the average of min and max values */ /* Take the average of min and max values */ Loading Loading @@ -3893,8 +3911,11 @@ int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, union power_supply_propval *val) union power_supply_propval *val) { { int rc, pulses; int rc, pulses; int step_uv = HVDCP3_STEP_UV; switch (chg->real_charger_type) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: step_uv = HVDCP3P5_STEP_UV; case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: rc = smblib_get_pulse_cnt(chg, &pulses); rc = smblib_get_pulse_cnt(chg, &pulses); if (rc < 0) { if (rc < 0) { Loading @@ -3902,7 +3923,7 @@ int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, "Couldn't read QC_PULSE_COUNT rc=%d\n", rc); "Couldn't read QC_PULSE_COUNT rc=%d\n", rc); return 0; return 0; } } val->intval = MICRO_5V + HVDCP3_STEP_UV * pulses; val->intval = MICRO_5V + step_uv * pulses; break; break; case POWER_SUPPLY_TYPE_USB_PD: case POWER_SUPPLY_TYPE_USB_PD: val->intval = chg->voltage_min_uv; val->intval = chg->voltage_min_uv; Loading Loading @@ -5906,6 +5927,7 @@ static void typec_src_removal(struct smb_charger *chg) dev_err(chg->dev, dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", rc); "Couldn't disable secondary charger rc=%d\n", rc); chg->qc3p5_detected = false; typec_src_fault_condition_cfg(chg, false); typec_src_fault_condition_cfg(chg, false); smblib_hvdcp_detect_try_enable(chg, false); smblib_hvdcp_detect_try_enable(chg, false); smblib_update_usb_type(chg); smblib_update_usb_type(chg); Loading drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -565,6 +565,7 @@ struct smb_charger { bool dcin_icl_user_set; bool dcin_icl_user_set; bool dpdm_enabled; bool dpdm_enabled; bool apsd_ext_timeout; bool apsd_ext_timeout; bool qc3p5_detected; /* workaround flag */ /* workaround flag */ u32 wa_flags; u32 wa_flags; Loading Loading
drivers/power/supply/qcom/battery.c +3 −2 Original line number Original line Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only /* /* * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. */ */ #define pr_fmt(fmt) "QCOM-BATT: %s: " fmt, __func__ #define pr_fmt(fmt) "QCOM-BATT: %s: " fmt, __func__ Loading Loading @@ -194,7 +194,8 @@ static int get_hvdcp3_icl_limit(struct pl_data *chip) { { int main_icl, target_icl = -EINVAL; int main_icl, target_icl = -EINVAL; if (chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) if (chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3 && chip->charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5) return target_icl; return target_icl; /* /* Loading
drivers/power/supply/qcom/qpnp-smb5.c +3 −1 Original line number Original line Diff line number Diff line Loading @@ -1327,6 +1327,7 @@ 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, }; enum power_supply_type real_chg_type = chg->real_charger_type; int rc = 0, offset_ua = 0; int rc = 0, offset_ua = 0; switch (psp) { switch (psp) { Loading Loading @@ -1402,7 +1403,8 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, 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 */ /* Main ICL updated re-calculate ILIM */ if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) if (real_chg_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || real_chg_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) rerun_election(chg->fcc_votable); rerun_election(chg->fcc_votable); break; break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: Loading
drivers/power/supply/qcom/smb5-lib.c +28 −6 Original line number Original line Diff line number Diff line Loading @@ -915,7 +915,8 @@ int smblib_get_qc3_main_icl_offset(struct smb_charger *chg, int *offset_ua) * - Output connection topology is VBAT * - Output connection topology is VBAT */ */ if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config if (!is_cp_topo_vbatt(chg) || chg->hvdcp3_standalone_config || (chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3)) || ((chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3) && chg->real_charger_type != POWER_SUPPLY_TYPE_USB_HVDCP_3P5)) return -EINVAL; return -EINVAL; rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ENABLE, rc = power_supply_get_property(chg->cp_psy, POWER_SUPPLY_PROP_CP_ENABLE, Loading Loading @@ -1087,6 +1088,8 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) /* if PD is active, APSD is disabled so won't have a valid result */ /* if PD is active, APSD is disabled so won't have a valid result */ if (chg->pd_active) { if (chg->pd_active) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_PD; chg->real_charger_type = POWER_SUPPLY_TYPE_USB_PD; } else if (chg->qc3p5_detected) { chg->real_charger_type = POWER_SUPPLY_TYPE_USB_HVDCP_3P5; } else { } else { /* /* * Update real charger type only if its not FLOAT * Update real charger type only if its not FLOAT Loading @@ -1097,8 +1100,8 @@ static const struct apsd_result *smblib_update_usb_type(struct smb_charger *chg) chg->real_charger_type = apsd_result->pst; chg->real_charger_type = apsd_result->pst; } } smblib_dbg(chg, PR_MISC, "APSD=%s PD=%d\n", smblib_dbg(chg, PR_MISC, "APSD=%s PD=%d QC3P5=%d\n", apsd_result->name, chg->pd_active); apsd_result->name, chg->pd_active, chg->qc3p5_detected); return apsd_result; return apsd_result; } } Loading Loading @@ -1285,6 +1288,9 @@ static void smblib_uusb_removal(struct smb_charger *chg) chg->qc2_unsupported_voltage = QC2_COMPLIANT; chg->qc2_unsupported_voltage = QC2_COMPLIANT; } } chg->qc3p5_detected = false; smblib_update_usb_type(chg); } } void smblib_suspend_on_debug_battery(struct smb_charger *chg) void smblib_suspend_on_debug_battery(struct smb_charger *chg) Loading Loading @@ -2536,7 +2542,8 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg) vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0); vote(chg->usb_icl_votable, HVDCP2_ICL_VOTER, false, 0); } } if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3) { if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3 || chg->real_charger_type == POWER_SUPPLY_TYPE_USB_HVDCP_3P5) { rc = smblib_hvdcp3_set_fsw(chg); rc = smblib_hvdcp3_set_fsw(chg); if (rc < 0) if (rc < 0) smblib_err(chg, "Couldn't set QC3.0 Fsw rc=%d\n", rc); smblib_err(chg, "Couldn't set QC3.0 Fsw rc=%d\n", rc); Loading Loading @@ -2669,6 +2676,10 @@ int smblib_dp_dm(struct smb_charger *chg, int val) if (rc < 0) if (rc < 0) pr_err("Failed to force 12V\n"); pr_err("Failed to force 12V\n"); break; break; case POWER_SUPPLY_DP_DM_CONFIRMED_HVDCP3P5: chg->qc3p5_detected = true; smblib_update_usb_type(chg); break; case POWER_SUPPLY_DP_DM_ICL_UP: case POWER_SUPPLY_DP_DM_ICL_UP: default: default: break; break; Loading Loading @@ -3281,6 +3292,7 @@ int smblib_get_prop_usb_voltage_max_design(struct smb_charger *chg, break; break; } } /* else, fallthrough */ /* else, fallthrough */ case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_PD: case POWER_SUPPLY_TYPE_USB_PD: if (chg->chg_param.smb_version == PMI632_SUBTYPE) if (chg->chg_param.smb_version == PMI632_SUBTYPE) Loading Loading @@ -3310,6 +3322,7 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, break; break; } } /* else, fallthrough */ /* else, fallthrough */ case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: if (chg->chg_param.smb_version == PMI632_SUBTYPE) if (chg->chg_param.smb_version == PMI632_SUBTYPE) val->intval = MICRO_9V; val->intval = MICRO_9V; Loading @@ -3328,15 +3341,20 @@ int smblib_get_prop_usb_voltage_max(struct smb_charger *chg, } } #define HVDCP3_STEP_UV 200000 #define HVDCP3_STEP_UV 200000 #define HVDCP3P5_STEP_UV 20000 static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, static int smblib_estimate_adaptor_voltage(struct smb_charger *chg, union power_supply_propval *val) union power_supply_propval *val) { { int step_uv = HVDCP3_STEP_UV; switch (chg->real_charger_type) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_HVDCP: case POWER_SUPPLY_TYPE_USB_HVDCP: val->intval = MICRO_12V; val->intval = MICRO_12V; break; break; case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: step_uv = HVDCP3P5_STEP_UV; case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: val->intval = MICRO_5V + (HVDCP3_STEP_UV * chg->pulse_cnt); val->intval = MICRO_5V + (step_uv * chg->pulse_cnt); break; break; case POWER_SUPPLY_TYPE_USB_PD: case POWER_SUPPLY_TYPE_USB_PD: /* Take the average of min and max values */ /* Take the average of min and max values */ Loading Loading @@ -3893,8 +3911,11 @@ int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, union power_supply_propval *val) union power_supply_propval *val) { { int rc, pulses; int rc, pulses; int step_uv = HVDCP3_STEP_UV; switch (chg->real_charger_type) { switch (chg->real_charger_type) { case POWER_SUPPLY_TYPE_USB_HVDCP_3P5: step_uv = HVDCP3P5_STEP_UV; case POWER_SUPPLY_TYPE_USB_HVDCP_3: case POWER_SUPPLY_TYPE_USB_HVDCP_3: rc = smblib_get_pulse_cnt(chg, &pulses); rc = smblib_get_pulse_cnt(chg, &pulses); if (rc < 0) { if (rc < 0) { Loading @@ -3902,7 +3923,7 @@ int smblib_get_prop_input_voltage_settled(struct smb_charger *chg, "Couldn't read QC_PULSE_COUNT rc=%d\n", rc); "Couldn't read QC_PULSE_COUNT rc=%d\n", rc); return 0; return 0; } } val->intval = MICRO_5V + HVDCP3_STEP_UV * pulses; val->intval = MICRO_5V + step_uv * pulses; break; break; case POWER_SUPPLY_TYPE_USB_PD: case POWER_SUPPLY_TYPE_USB_PD: val->intval = chg->voltage_min_uv; val->intval = chg->voltage_min_uv; Loading Loading @@ -5906,6 +5927,7 @@ static void typec_src_removal(struct smb_charger *chg) dev_err(chg->dev, dev_err(chg->dev, "Couldn't disable secondary charger rc=%d\n", rc); "Couldn't disable secondary charger rc=%d\n", rc); chg->qc3p5_detected = false; typec_src_fault_condition_cfg(chg, false); typec_src_fault_condition_cfg(chg, false); smblib_hvdcp_detect_try_enable(chg, false); smblib_hvdcp_detect_try_enable(chg, false); smblib_update_usb_type(chg); smblib_update_usb_type(chg); Loading
drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -565,6 +565,7 @@ struct smb_charger { bool dcin_icl_user_set; bool dcin_icl_user_set; bool dpdm_enabled; bool dpdm_enabled; bool apsd_ext_timeout; bool apsd_ext_timeout; bool qc3p5_detected; /* workaround flag */ /* workaround flag */ u32 wa_flags; u32 wa_flags; Loading