Loading drivers/power/supply/qcom/qpnp-smb5.c +72 −0 Original line number Diff line number Diff line Loading @@ -292,6 +292,11 @@ enum { SMB_THERM, }; static const struct clamp_config clamp_levels[] = { { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2E, 0x90} }, { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2B, 0x9C} }, }; #define PMI632_MAX_ICL_UA 3000000 #define PM6150_MAX_FCC_UA 3000000 static int smb5_chg_config_init(struct smb5 *chip) Loading Loading @@ -701,6 +706,33 @@ static int smb5_parse_dt(struct smb5 *chip) return 0; } static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0, i; struct clamp_config clamp_config; enum comp_clamp_levels level; level = val->intval; if (level >= MAX_CLAMP_LEVEL) { pr_err("Invalid comp clamp level=%d\n", val->intval); return -EINVAL; } for (i = 0; i < ARRAY_SIZE(clamp_config.reg); i++) { rc = smblib_write(chg, clamp_levels[level].reg[i], clamp_levels[level].val[i]); if (rc < 0) dev_err(chg->dev, "Failed to configure comp clamp settings for reg=0x%04x rc=%d\n", clamp_levels[level].reg[i], rc); } chg->comp_clamp_level = val->intval; return rc; } /************************ * USB PSY REGISTRATION * ************************/ Loading Loading @@ -732,6 +764,7 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT, POWER_SUPPLY_PROP_SMB_EN_MODE, POWER_SUPPLY_PROP_SMB_EN_REASON, POWER_SUPPLY_PROP_ADAPTER_CC_MODE, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_MOISTURE_DETECTED, POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, Loading Loading @@ -875,6 +908,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER); break; case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: val->intval = chg->adapter_cc_mode; break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -961,6 +997,9 @@ static int smb5_usb_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: smblib_set_prop_usb_voltage_max_limit(chg, val); break; case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: chg->adapter_cc_mode = val->intval; break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading @@ -978,6 +1017,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: return 1; default: break; Loading Loading @@ -1129,6 +1169,9 @@ static enum power_supply_property smb5_usb_main_props[] = { POWER_SUPPLY_PROP_TOGGLE_STAT, POWER_SUPPLY_PROP_MAIN_FCC_MAX, POWER_SUPPLY_PROP_IRQ_STATUS, POWER_SUPPLY_PROP_FORCE_MAIN_FCC, POWER_SUPPLY_PROP_FORCE_MAIN_ICL, POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, }; static int smb5_usb_main_get_prop(struct power_supply *psy, Loading Loading @@ -1177,6 +1220,17 @@ static int smb5_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_IRQ_STATUS: rc = smblib_get_irq_status(chg, val); break; case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: rc = smblib_get_charge_param(chg, &chg->param.fcc, &val->intval); break; case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: rc = smblib_get_charge_param(chg, &chg->param.usb_icl, &val->intval); break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: val->intval = chg->comp_clamp_level; break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; Loading Loading @@ -1247,6 +1301,17 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, chg->main_fcc_max = val->intval; rerun_election(chg->fcc_votable); break; case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: vote_override(chg->fcc_main_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); break; case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: vote_override(chg->usb_icl_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = smb5_set_prop_comp_clamp_level(chg, val); break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading @@ -1264,6 +1329,9 @@ static int smb5_usb_main_prop_is_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_TOGGLE_STAT: case POWER_SUPPLY_PROP_MAIN_FCC_MAX: case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = 1; break; default: Loading Loading @@ -1452,6 +1520,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_QNOVO, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TECHNOLOGY, Loading Loading @@ -1543,6 +1612,9 @@ static int smb5_batt_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->fcc_votable, BATT_PROFILE_VOTER); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: val->intval = get_effective_result(chg->fcc_votable); break; case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: rc = smblib_get_prop_batt_iterm(chg, val); break; Loading drivers/power/supply/qcom/smb1390-charger-psy.c +117 −9 Original line number Diff line number Diff line Loading @@ -96,11 +96,15 @@ #define SWITCHER_TOGGLE_VOTER "SWITCHER_TOGGLE_VOTER" #define SOC_LEVEL_VOTER "SOC_LEVEL_VOTER" #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 #define THERMAL_SUSPEND_DECIDEGC 1400 #define MAX_ILIM_UA 3200000 #define MAX_ILIM_DUAL_CP_UA 6400000 #define CC_MODE_TAPER_DELTA_UA 200000 #define DEFAULT_TAPER_DELTA_UA 100000 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ Loading Loading @@ -195,6 +199,8 @@ struct smb1390 { u32 pl_output_mode; u32 cp_role; enum isns_mode current_capability; bool batt_soc_validated; int cp_slave_thr_taper_ua; }; struct smb_cfg { Loading Loading @@ -349,6 +355,28 @@ static int smb1390_isns_mode_control(struct smb1390 *chip, enum isns_mode mode) return rc; } static bool smb1390_is_adapter_cc_mode(struct smb1390 *chip) { int rc; union power_supply_propval pval = {0, }; if (!chip->usb_psy) { chip->usb_psy = power_supply_get_by_name("usb"); if (!chip->usb_psy) return false; } rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_ADAPTER_CC_MODE, &pval); if (rc < 0) { pr_err("Couldn't get PPS CC mode status rc=%d\n", rc); return false; } return pval.intval; } static bool is_cps_available(struct smb1390 *chip) { if (!chip->cps_psy) Loading Loading @@ -690,6 +718,30 @@ static int smb1390_get_isns_slave(struct smb1390 *chip, return rc; } static int smb1390_get_cp_ilim(struct smb1390 *chip, union power_supply_propval *val) { int rc = 0, status; if (is_cps_available(chip)) { if (!chip->ilim_votable) { chip->ilim_votable = find_votable("CP_ILIM"); if (!chip->ilim_votable) return -EINVAL; } val->intval = get_effective_result(chip->ilim_votable); } else { rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status); if (!rc) val->intval = ((status & CFG_ILIM_MASK) * 100000) + 500000; } return rc; } static int smb1390_is_batt_soc_valid(struct smb1390 *chip) { int rc; Loading Loading @@ -818,7 +870,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data, return -EINVAL; } ilim_uA = min(ilim_uA, MAX_ILIM_UA); ilim_uA = min(ilim_uA, (is_cps_available(chip) ? MAX_ILIM_DUAL_CP_UA : MAX_ILIM_UA)); /* ILIM less than min_ilim_ua, disable charging */ if (ilim_uA < chip->min_ilim_ua) { smb1390_dbg(chip, PR_INFO, "ILIM %duA is too low to allow charging\n", Loading Loading @@ -919,6 +972,7 @@ static void smb1390_status_change_work(struct work_struct *work) if (!is_psy_voter_available(chip)) goto out; if (!smb1390_is_adapter_cc_mode(chip)) vote(chip->disable_votable, SOC_LEVEL_VOTER, smb1390_is_batt_soc_valid(chip) ? false : true, 0); Loading @@ -937,7 +991,14 @@ static void smb1390_status_change_work(struct work_struct *work) goto out; } /* Check for SOC threshold only once before enabling CP */ vote(chip->disable_votable, SRC_VOTER, false, 0); if (!chip->batt_soc_validated) { vote(chip->disable_votable, SOC_LEVEL_VOTER, smb1390_is_batt_soc_valid(chip) ? false : true, 0); chip->batt_soc_validated = true; } if (pval.intval == POWER_SUPPLY_CP_WIRELESS) { vote(chip->ilim_votable, ICL_VOTER, false, 0); Loading Loading @@ -1007,10 +1068,12 @@ static void smb1390_status_change_work(struct work_struct *work) } } } else { chip->batt_soc_validated = false; vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0); vote_override(chip->ilim_votable, CC_MODE_VOTER, false, 0); } out: Loading @@ -1018,11 +1081,39 @@ static void smb1390_status_change_work(struct work_struct *work) chip->status_change_running = false; } static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) { int rc = 0; u8 mask; /* * In Collapse mode, while in Taper, Disable the slave SMB1390 * when FCC drops below a specified threshold. */ if (fcc_uA < (chip->cp_slave_thr_taper_ua) && is_cps_available(chip)) { mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, mask, CMD_EN_SWITCHER_BIT); if (rc < 0) return rc; /* * Set ILIM of master CP to Max value = 3.2A once slave is * disabled to prevent ILIM irq storm. */ smb1390_dbg(chip, PR_INFO, "Set Master ILIM to MAX, post Slave disable in taper, fcc=%d\n", fcc_uA); vote_override(chip->ilim_votable, CC_MODE_VOTER, true, MAX_ILIM_DUAL_CP_UA); } return rc; } static void smb1390_taper_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, taper_work); union power_supply_propval pval = {0, }; int rc, fcc_uA; int rc, fcc_uA, delta_fcc_uA; if (!is_psy_voter_available(chip)) goto out; Loading @@ -1046,11 +1137,21 @@ static void smb1390_taper_work(struct work_struct *work) } if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { delta_fcc_uA = (smb1390_is_adapter_cc_mode(chip) ? CC_MODE_TAPER_DELTA_UA : DEFAULT_TAPER_DELTA_UA); fcc_uA = get_effective_result(chip->fcc_votable) - 100000; - delta_fcc_uA; smb1390_dbg(chip, PR_INFO, "taper work reducing FCC to %duA\n", fcc_uA); vote(chip->fcc_votable, CP_VOTER, true, fcc_uA); rc = smb1390_validate_slave_chg_taper(chip, fcc_uA); if (rc < 0) { pr_err("Couldn't Disable slave in Taper, rc=%d\n", rc); goto out; } if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, Loading Loading @@ -1167,10 +1268,7 @@ static int smb1390_get_prop(struct power_supply *psy, val->intval |= status; break; case POWER_SUPPLY_PROP_CP_ILIM: rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status); if (!rc) val->intval = ((status & CFG_ILIM_MASK) * 100000) + 500000; rc = smb1390_get_cp_ilim(chip, val); break; case POWER_SUPPLY_PROP_CHIP_VERSION: val->intval = chip->pmic_rev_id->rev4; Loading Loading @@ -1208,6 +1306,11 @@ static int smb1390_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CP_IRQ_STATUS: chip->irq_status = val->intval; break; case POWER_SUPPLY_PROP_CP_ILIM: if (chip->ilim_votable) vote_override(chip->ilim_votable, CC_MODE_VOTER, true, val->intval); break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply set prop %d not supported\n", prop); Loading @@ -1226,6 +1329,7 @@ static int smb1390_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CP_IRQ_STATUS: case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_CAPABILITY: case POWER_SUPPLY_PROP_CP_ILIM: return 1; default: break; Loading Loading @@ -1300,6 +1404,10 @@ static int smb1390_parse_dt(struct smb1390 *chip) chip->pl_output_mode = POWER_SUPPLY_PL_OUTPUT_VPH; of_property_read_u32(chip->dev->of_node, "qcom,parallel-output-mode", &chip->pl_output_mode); chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3; of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua", &chip->cp_slave_thr_taper_ua); return 0; } Loading drivers/power/supply/qcom/smb5-lib.c +4 −1 Original line number Diff line number Diff line Loading @@ -5584,8 +5584,11 @@ static void typec_src_removal(struct smb_charger *chg) chg->voltage_max_uv = MICRO_5V; chg->usbin_forced_max_uv = 0; /* Reset CC mode Votes */ /* Reset all CC mode votes */ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); chg->adapter_cc_mode = 0; vote_override(chg->fcc_votable, CC_MODE_VOTER, false, 0); vote_override(chg->usb_icl_votable, CC_MODE_VOTER, false, 0); /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, Loading drivers/power/supply/qcom/smb5-lib.h +16 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ enum print_reason { #define CHARGER_TYPE_VOTER "CHARGER_TYPE_VOTER" #define HDC_IRQ_VOTER "HDC_IRQ_VOTER" #define DETACH_DETECT_VOTER "DETACH_DETECT_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define MAIN_FCC_VOTER "MAIN_FCC_VOTER" #define BOOST_BACK_STORM_COUNT 3 Loading Loading @@ -219,6 +220,17 @@ enum chg_term_config_src { ITERM_SRC_ANALOG }; enum comp_clamp_levels { CLAMP_LEVEL_DEFAULT = 0, CLAMP_LEVEL_1, MAX_CLAMP_LEVEL, }; struct clamp_config { u16 reg[3]; u16 val[3]; }; struct smb_irq_info { const char *name; const irq_handler_t handler; Loading Loading @@ -384,6 +396,9 @@ struct smb_charger { /* parallel charging */ struct parallel_params pl; /* CC Mode */ int adapter_cc_mode; /* regulators */ struct smb_regulator *vbus_vreg; struct smb_regulator *vconn_vreg; Loading Loading @@ -512,6 +527,7 @@ struct smb_charger { int last_cc_soc; int usbin_forced_max_uv; int init_thermal_ua; u32 comp_clamp_level; /* workaround flag */ u32 wa_flags; Loading Loading
drivers/power/supply/qcom/qpnp-smb5.c +72 −0 Original line number Diff line number Diff line Loading @@ -292,6 +292,11 @@ enum { SMB_THERM, }; static const struct clamp_config clamp_levels[] = { { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2E, 0x90} }, { {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2B, 0x9C} }, }; #define PMI632_MAX_ICL_UA 3000000 #define PM6150_MAX_FCC_UA 3000000 static int smb5_chg_config_init(struct smb5 *chip) Loading Loading @@ -701,6 +706,33 @@ static int smb5_parse_dt(struct smb5 *chip) return 0; } static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg, const union power_supply_propval *val) { int rc = 0, i; struct clamp_config clamp_config; enum comp_clamp_levels level; level = val->intval; if (level >= MAX_CLAMP_LEVEL) { pr_err("Invalid comp clamp level=%d\n", val->intval); return -EINVAL; } for (i = 0; i < ARRAY_SIZE(clamp_config.reg); i++) { rc = smblib_write(chg, clamp_levels[level].reg[i], clamp_levels[level].val[i]); if (rc < 0) dev_err(chg->dev, "Failed to configure comp clamp settings for reg=0x%04x rc=%d\n", clamp_levels[level].reg[i], rc); } chg->comp_clamp_level = val->intval; return rc; } /************************ * USB PSY REGISTRATION * ************************/ Loading Loading @@ -732,6 +764,7 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT, POWER_SUPPLY_PROP_SMB_EN_MODE, POWER_SUPPLY_PROP_SMB_EN_REASON, POWER_SUPPLY_PROP_ADAPTER_CC_MODE, POWER_SUPPLY_PROP_SCOPE, POWER_SUPPLY_PROP_MOISTURE_DETECTED, POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, Loading Loading @@ -875,6 +908,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER); break; case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: val->intval = chg->adapter_cc_mode; break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -961,6 +997,9 @@ static int smb5_usb_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: smblib_set_prop_usb_voltage_max_limit(chg, val); break; case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: chg->adapter_cc_mode = val->intval; break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading @@ -978,6 +1017,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT: case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: return 1; default: break; Loading Loading @@ -1129,6 +1169,9 @@ static enum power_supply_property smb5_usb_main_props[] = { POWER_SUPPLY_PROP_TOGGLE_STAT, POWER_SUPPLY_PROP_MAIN_FCC_MAX, POWER_SUPPLY_PROP_IRQ_STATUS, POWER_SUPPLY_PROP_FORCE_MAIN_FCC, POWER_SUPPLY_PROP_FORCE_MAIN_ICL, POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, }; static int smb5_usb_main_get_prop(struct power_supply *psy, Loading Loading @@ -1177,6 +1220,17 @@ static int smb5_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_IRQ_STATUS: rc = smblib_get_irq_status(chg, val); break; case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: rc = smblib_get_charge_param(chg, &chg->param.fcc, &val->intval); break; case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: rc = smblib_get_charge_param(chg, &chg->param.usb_icl, &val->intval); break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: val->intval = chg->comp_clamp_level; break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; Loading Loading @@ -1247,6 +1301,17 @@ static int smb5_usb_main_set_prop(struct power_supply *psy, chg->main_fcc_max = val->intval; rerun_election(chg->fcc_votable); break; case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: vote_override(chg->fcc_main_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); break; case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: vote_override(chg->usb_icl_votable, CC_MODE_VOTER, (val->intval < 0) ? false : true, val->intval); break; case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = smb5_set_prop_comp_clamp_level(chg, val); break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading @@ -1264,6 +1329,9 @@ static int smb5_usb_main_prop_is_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_TOGGLE_STAT: case POWER_SUPPLY_PROP_MAIN_FCC_MAX: case POWER_SUPPLY_PROP_FORCE_MAIN_FCC: case POWER_SUPPLY_PROP_FORCE_MAIN_ICL: case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: rc = 1; break; default: Loading Loading @@ -1452,6 +1520,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_QNOVO, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TECHNOLOGY, Loading Loading @@ -1543,6 +1612,9 @@ static int smb5_batt_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->fcc_votable, BATT_PROFILE_VOTER); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: val->intval = get_effective_result(chg->fcc_votable); break; case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: rc = smblib_get_prop_batt_iterm(chg, val); break; Loading
drivers/power/supply/qcom/smb1390-charger-psy.c +117 −9 Original line number Diff line number Diff line Loading @@ -96,11 +96,15 @@ #define SWITCHER_TOGGLE_VOTER "SWITCHER_TOGGLE_VOTER" #define SOC_LEVEL_VOTER "SOC_LEVEL_VOTER" #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 #define THERMAL_SUSPEND_DECIDEGC 1400 #define MAX_ILIM_UA 3200000 #define MAX_ILIM_DUAL_CP_UA 6400000 #define CC_MODE_TAPER_DELTA_UA 200000 #define DEFAULT_TAPER_DELTA_UA 100000 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ Loading Loading @@ -195,6 +199,8 @@ struct smb1390 { u32 pl_output_mode; u32 cp_role; enum isns_mode current_capability; bool batt_soc_validated; int cp_slave_thr_taper_ua; }; struct smb_cfg { Loading Loading @@ -349,6 +355,28 @@ static int smb1390_isns_mode_control(struct smb1390 *chip, enum isns_mode mode) return rc; } static bool smb1390_is_adapter_cc_mode(struct smb1390 *chip) { int rc; union power_supply_propval pval = {0, }; if (!chip->usb_psy) { chip->usb_psy = power_supply_get_by_name("usb"); if (!chip->usb_psy) return false; } rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_ADAPTER_CC_MODE, &pval); if (rc < 0) { pr_err("Couldn't get PPS CC mode status rc=%d\n", rc); return false; } return pval.intval; } static bool is_cps_available(struct smb1390 *chip) { if (!chip->cps_psy) Loading Loading @@ -690,6 +718,30 @@ static int smb1390_get_isns_slave(struct smb1390 *chip, return rc; } static int smb1390_get_cp_ilim(struct smb1390 *chip, union power_supply_propval *val) { int rc = 0, status; if (is_cps_available(chip)) { if (!chip->ilim_votable) { chip->ilim_votable = find_votable("CP_ILIM"); if (!chip->ilim_votable) return -EINVAL; } val->intval = get_effective_result(chip->ilim_votable); } else { rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status); if (!rc) val->intval = ((status & CFG_ILIM_MASK) * 100000) + 500000; } return rc; } static int smb1390_is_batt_soc_valid(struct smb1390 *chip) { int rc; Loading Loading @@ -818,7 +870,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data, return -EINVAL; } ilim_uA = min(ilim_uA, MAX_ILIM_UA); ilim_uA = min(ilim_uA, (is_cps_available(chip) ? MAX_ILIM_DUAL_CP_UA : MAX_ILIM_UA)); /* ILIM less than min_ilim_ua, disable charging */ if (ilim_uA < chip->min_ilim_ua) { smb1390_dbg(chip, PR_INFO, "ILIM %duA is too low to allow charging\n", Loading Loading @@ -919,6 +972,7 @@ static void smb1390_status_change_work(struct work_struct *work) if (!is_psy_voter_available(chip)) goto out; if (!smb1390_is_adapter_cc_mode(chip)) vote(chip->disable_votable, SOC_LEVEL_VOTER, smb1390_is_batt_soc_valid(chip) ? false : true, 0); Loading @@ -937,7 +991,14 @@ static void smb1390_status_change_work(struct work_struct *work) goto out; } /* Check for SOC threshold only once before enabling CP */ vote(chip->disable_votable, SRC_VOTER, false, 0); if (!chip->batt_soc_validated) { vote(chip->disable_votable, SOC_LEVEL_VOTER, smb1390_is_batt_soc_valid(chip) ? false : true, 0); chip->batt_soc_validated = true; } if (pval.intval == POWER_SUPPLY_CP_WIRELESS) { vote(chip->ilim_votable, ICL_VOTER, false, 0); Loading Loading @@ -1007,10 +1068,12 @@ static void smb1390_status_change_work(struct work_struct *work) } } } else { chip->batt_soc_validated = false; vote(chip->disable_votable, SRC_VOTER, true, 0); vote(chip->disable_votable, TAPER_END_VOTER, false, 0); vote(chip->fcc_votable, CP_VOTER, false, 0); vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0); vote_override(chip->ilim_votable, CC_MODE_VOTER, false, 0); } out: Loading @@ -1018,11 +1081,39 @@ static void smb1390_status_change_work(struct work_struct *work) chip->status_change_running = false; } static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) { int rc = 0; u8 mask; /* * In Collapse mode, while in Taper, Disable the slave SMB1390 * when FCC drops below a specified threshold. */ if (fcc_uA < (chip->cp_slave_thr_taper_ua) && is_cps_available(chip)) { mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, mask, CMD_EN_SWITCHER_BIT); if (rc < 0) return rc; /* * Set ILIM of master CP to Max value = 3.2A once slave is * disabled to prevent ILIM irq storm. */ smb1390_dbg(chip, PR_INFO, "Set Master ILIM to MAX, post Slave disable in taper, fcc=%d\n", fcc_uA); vote_override(chip->ilim_votable, CC_MODE_VOTER, true, MAX_ILIM_DUAL_CP_UA); } return rc; } static void smb1390_taper_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, taper_work); union power_supply_propval pval = {0, }; int rc, fcc_uA; int rc, fcc_uA, delta_fcc_uA; if (!is_psy_voter_available(chip)) goto out; Loading @@ -1046,11 +1137,21 @@ static void smb1390_taper_work(struct work_struct *work) } if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { delta_fcc_uA = (smb1390_is_adapter_cc_mode(chip) ? CC_MODE_TAPER_DELTA_UA : DEFAULT_TAPER_DELTA_UA); fcc_uA = get_effective_result(chip->fcc_votable) - 100000; - delta_fcc_uA; smb1390_dbg(chip, PR_INFO, "taper work reducing FCC to %duA\n", fcc_uA); vote(chip->fcc_votable, CP_VOTER, true, fcc_uA); rc = smb1390_validate_slave_chg_taper(chip, fcc_uA); if (rc < 0) { pr_err("Couldn't Disable slave in Taper, rc=%d\n", rc); goto out; } if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, Loading Loading @@ -1167,10 +1268,7 @@ static int smb1390_get_prop(struct power_supply *psy, val->intval |= status; break; case POWER_SUPPLY_PROP_CP_ILIM: rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status); if (!rc) val->intval = ((status & CFG_ILIM_MASK) * 100000) + 500000; rc = smb1390_get_cp_ilim(chip, val); break; case POWER_SUPPLY_PROP_CHIP_VERSION: val->intval = chip->pmic_rev_id->rev4; Loading Loading @@ -1208,6 +1306,11 @@ static int smb1390_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CP_IRQ_STATUS: chip->irq_status = val->intval; break; case POWER_SUPPLY_PROP_CP_ILIM: if (chip->ilim_votable) vote_override(chip->ilim_votable, CC_MODE_VOTER, true, val->intval); break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply set prop %d not supported\n", prop); Loading @@ -1226,6 +1329,7 @@ static int smb1390_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_CP_IRQ_STATUS: case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX: case POWER_SUPPLY_PROP_CURRENT_CAPABILITY: case POWER_SUPPLY_PROP_CP_ILIM: return 1; default: break; Loading Loading @@ -1300,6 +1404,10 @@ static int smb1390_parse_dt(struct smb1390 *chip) chip->pl_output_mode = POWER_SUPPLY_PL_OUTPUT_VPH; of_property_read_u32(chip->dev->of_node, "qcom,parallel-output-mode", &chip->pl_output_mode); chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3; of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua", &chip->cp_slave_thr_taper_ua); return 0; } Loading
drivers/power/supply/qcom/smb5-lib.c +4 −1 Original line number Diff line number Diff line Loading @@ -5584,8 +5584,11 @@ static void typec_src_removal(struct smb_charger *chg) chg->voltage_max_uv = MICRO_5V; chg->usbin_forced_max_uv = 0; /* Reset CC mode Votes */ /* Reset all CC mode votes */ vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0); chg->adapter_cc_mode = 0; vote_override(chg->fcc_votable, CC_MODE_VOTER, false, 0); vote_override(chg->usb_icl_votable, CC_MODE_VOTER, false, 0); /* write back the default FLOAT charger configuration */ rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG, Loading
drivers/power/supply/qcom/smb5-lib.h +16 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ enum print_reason { #define CHARGER_TYPE_VOTER "CHARGER_TYPE_VOTER" #define HDC_IRQ_VOTER "HDC_IRQ_VOTER" #define DETACH_DETECT_VOTER "DETACH_DETECT_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define MAIN_FCC_VOTER "MAIN_FCC_VOTER" #define BOOST_BACK_STORM_COUNT 3 Loading Loading @@ -219,6 +220,17 @@ enum chg_term_config_src { ITERM_SRC_ANALOG }; enum comp_clamp_levels { CLAMP_LEVEL_DEFAULT = 0, CLAMP_LEVEL_1, MAX_CLAMP_LEVEL, }; struct clamp_config { u16 reg[3]; u16 val[3]; }; struct smb_irq_info { const char *name; const irq_handler_t handler; Loading Loading @@ -384,6 +396,9 @@ struct smb_charger { /* parallel charging */ struct parallel_params pl; /* CC Mode */ int adapter_cc_mode; /* regulators */ struct smb_regulator *vbus_vreg; struct smb_regulator *vconn_vreg; Loading Loading @@ -512,6 +527,7 @@ struct smb_charger { int last_cc_soc; int usbin_forced_max_uv; int init_thermal_ua; u32 comp_clamp_level; /* workaround flag */ u32 wa_flags; Loading