Loading drivers/power/power_supply_sysfs.c +1 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(die_health), POWER_SUPPLY_ATTR(connector_health), POWER_SUPPLY_ATTR(ctm_current_max), POWER_SUPPLY_ATTR(hw_current_max), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ Loading drivers/power/supply/qcom/battery.c +36 −5 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct pl_data { struct votable *pl_disable_votable; struct votable *pl_awake_votable; struct votable *hvdcp_hw_inov_dis_votable; struct votable *usb_icl_votable; struct work_struct status_change_work; struct work_struct pl_disable_forever_work; struct delayed_work pl_taper_work; Loading Loading @@ -487,6 +488,25 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, return 0; } static int usb_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) { struct pl_data *chip = data; union power_supply_propval pval = {0, }; if (!chip->main_psy) return 0; if (client == NULL) icl_ua = INT_MAX; pval.intval = icl_ua; return power_supply_set_property(chip->main_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, &pval); return 0; } static void pl_disable_forever_work(struct work_struct *work) { struct pl_data *chip = container_of(work, Loading Loading @@ -596,13 +616,15 @@ static int pl_awake_vote_callback(struct votable *votable, static bool is_main_available(struct pl_data *chip) { if (!chip->main_psy) if (chip->main_psy) return true; chip->main_psy = power_supply_get_by_name("main"); if (!chip->main_psy) return false; if (chip->main_psy) rerun_election(chip->usb_icl_votable); return true; return !!chip->main_psy; } static bool is_batt_available(struct pl_data *chip) Loading Loading @@ -855,6 +877,14 @@ static int pl_init(void) goto destroy_votable; } chip->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, usb_icl_vote_callback, chip); if (IS_ERR(chip->usb_icl_votable)) { rc = PTR_ERR(chip->usb_icl_votable); goto destroy_votable; } chip->pl_disable_votable = create_votable("PL_DISABLE", VOTE_SET_ANY, pl_disable_vote_callback, chip); Loading Loading @@ -909,6 +939,7 @@ destroy_votable: destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); destroy_votable(chip->usb_icl_votable); release_wakeup_source: wakeup_source_unregister(chip->pl_ws); cleanup: Loading drivers/power/supply/qcom/qpnp-smb2.c +19 −0 Original line number Diff line number Diff line Loading @@ -616,6 +616,7 @@ static enum power_supply_property smb2_usb_main_props[] = { POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, POWER_SUPPLY_PROP_FCC_DELTA, POWER_SUPPLY_PROP_CURRENT_MAX, /* * TODO move the TEMP and TEMP_MAX properties here, * and update the thermal balancer to look here Loading Loading @@ -653,6 +654,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FCC_DELTA: rc = smblib_get_prop_fcc_delta(chg, val); break; case POWER_SUPPLY_PROP_CURRENT_MAX: val->intval = get_effective_result(chg->usb_icl_votable); break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; Loading Loading @@ -683,6 +687,9 @@ static int smb2_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); break; case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_set_icl_current(chg, val->intval); break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading Loading @@ -1572,6 +1579,16 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } /* disable h/w autonomous parallel charging control */ rc = smblib_masked_write(chg, MISC_CFG_REG, STAT_PARALLEL_1400MA_EN_CFG_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't disable h/w autonomous parallel control rc=%d\n", rc); return rc; } /* configure float charger options */ switch (chip->dt.float_option) { case 1: Loading Loading @@ -2230,6 +2247,8 @@ static int smb2_probe(struct platform_device *pdev) } batt_charge_type = val.intval; device_init_wakeup(chg->dev, true); pr_info("QPNP SMB2 probed successfully usb:present=%d type=%d batt:present = %d health = %d charge = %d\n", usb_present, chg->usb_psy_desc.type, batt_present, batt_health, batt_charge_type); Loading drivers/power/supply/qcom/smb-lib.c +53 −63 Original line number Diff line number Diff line Loading @@ -654,10 +654,13 @@ static void smblib_uusb_removal(struct smb_charger *chg) { int rc; cancel_delayed_work_sync(&chg->pl_enable_work); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); /* reset both usbin current and voltage votes */ vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); Loading Loading @@ -795,29 +798,12 @@ static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count) return 0; } /********************* * VOTABLE CALLBACKS * *********************/ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, int suspend, const char *client) { struct smb_charger *chg = data; /* resume input if suspend is invalid */ if (suspend < 0) suspend = 0; return smblib_set_dc_suspend(chg, (bool)suspend); } #define USBIN_25MA 25000 #define USBIN_100MA 100000 #define USBIN_150MA 150000 #define USBIN_500MA 500000 #define USBIN_900MA 900000 static int set_sdp_current(struct smb_charger *chg, int icl_ua) { int rc; Loading Loading @@ -856,20 +842,18 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) return rc; } static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { struct smb_charger *chg = data; int rc = 0; bool override; union power_supply_propval pval; /* suspend and return if 25mA or less is requested */ if (client && (icl_ua < USBIN_25MA)) if (icl_ua < USBIN_25MA) return smblib_set_usb_suspend(chg, true); disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq); if (!client) if (icl_ua == INT_MAX) goto override_suspend_config; rc = smblib_get_prop_typec_mode(chg, &pval); Loading Loading @@ -898,7 +882,7 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, override_suspend_config: /* determine if override needs to be enforced */ override = true; if (client == NULL) { if (icl_ua == INT_MAX) { /* remove override if no voters - hw defaults is desired */ override = false; } else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { Loading Loading @@ -936,6 +920,22 @@ enable_icl_changed_interrupt: return rc; } /********************* * VOTABLE CALLBACKS * *********************/ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, int suspend, const char *client) { struct smb_charger *chg = data; /* resume input if suspend is invalid */ if (suspend < 0) suspend = 0; return smblib_set_dc_suspend(chg, (bool)suspend); } static int smblib_dc_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) { Loading Loading @@ -2618,16 +2618,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); return rc; } /* pd active set, parallel charger can be enabled now */ rc = vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); if (rc < 0) { smblib_err(chg, "Couldn't unvote PL_DELAY_HVDCP_VOTER rc=%d\n", rc); return rc; } } /* CC pin selection s/w override in PD session; h/w otherwise. */ Loading Loading @@ -3159,6 +3149,7 @@ irqreturn_t smblib_handle_usbin_uv(int irq, void *data) return IRQ_HANDLED; } #define PL_DELAY_MS 30000 irqreturn_t smblib_handle_usb_plugin(int irq, void *data) { struct smb_irq_data *irq_data = data; Loading Loading @@ -3197,6 +3188,11 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data) smblib_err(chg, "Couldn't enable dpdm regulator rc=%d\n", rc); } /* Schedule work to enable parallel charger */ vote(chg->awake_votable, PL_DELAY_VOTER, true, 0); schedule_delayed_work(&chg->pl_enable_work, msecs_to_jiffies(PL_DELAY_MS)); } else { if (chg->wa_flags & BOOST_BACK_WA) vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0); Loading Loading @@ -3374,9 +3370,6 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, } } /* QC authentication done, parallel charger can be enabled now */ vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-3p0-auth-done rising; %s detected\n", apsd_result->name); } Loading Loading @@ -3406,15 +3399,6 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, /* enforce DCP ICL if specified */ vote(chg->usb_icl_votable, DCP_VOTER, chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua); /* * If adapter is not QC2.0/QC3.0 remove vote for parallel * disable. * Otherwise if adapter is QC2.0/QC3.0 wait for authentication * to complete. */ if (!qc_charger) vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); } smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n", Loading Loading @@ -3486,13 +3470,9 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) true); case OCP_CHARGER_BIT: case FLOAT_CHARGER_BIT: /* * if not DCP then no hvdcp timeout happens. Enable * pd/parallel here. */ /* if not DCP then no hvdcp timeout happens, Enable pd here. */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); break; case DCP_CHARGER_BIT: if (chg->wa_flags & QC_CHARGER_DETECTION_WA_BIT) Loading Loading @@ -3645,9 +3625,12 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) { int rc; cancel_delayed_work_sync(&chg->pl_enable_work); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0); vote(chg->usb_irq_enable_votable, QC_VOTER, false, 0); Loading Loading @@ -3703,8 +3686,6 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg, if (rp == POWER_SUPPLY_TYPEC_SOURCE_HIGH || rp == POWER_SUPPLY_TYPEC_NON_COMPLIANT) { smblib_dbg(chg, PR_MISC, "VBUS & CC could be shorted; keeping HVDCP disabled\n"); /* HVDCP is not going to be enabled; enable parallel */ vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); } else { Loading Loading @@ -4210,6 +4191,16 @@ static void smblib_icl_change_work(struct work_struct *work) smblib_dbg(chg, PR_INTERRUPT, "icl_settled=%d\n", settled_ua); } static void smblib_pl_enable_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, pl_enable_work.work); smblib_dbg(chg, PR_PARALLEL, "timer expired, enabling parallel\n"); vote(chg->pl_disable_votable, PL_DELAY_VOTER, false, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); } static int smblib_create_votables(struct smb_charger *chg) { int rc = 0; Loading @@ -4226,13 +4217,19 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } chg->usb_icl_votable = find_votable("USB_ICL"); if (!chg->usb_icl_votable) { rc = -EPROBE_DEFER; return rc; } chg->pl_disable_votable = find_votable("PL_DISABLE"); if (!chg->pl_disable_votable) { rc = -EPROBE_DEFER; return rc; } vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); chg->dc_suspend_votable = create_votable("DC_SUSPEND", VOTE_SET_ANY, smblib_dc_suspend_vote_callback, Loading @@ -4242,14 +4239,6 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, smblib_usb_icl_vote_callback, chg); if (IS_ERR(chg->usb_icl_votable)) { rc = PTR_ERR(chg->usb_icl_votable); return rc; } chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN, smblib_dc_icl_vote_callback, chg); Loading Loading @@ -4400,6 +4389,7 @@ int smblib_init(struct smb_charger *chg) INIT_WORK(&chg->vconn_oc_work, smblib_vconn_oc_work); INIT_DELAYED_WORK(&chg->otg_ss_done_work, smblib_otg_ss_done_work); INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work); INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work); chg->fake_capacity = -EINVAL; switch (chg->mode) { Loading drivers/power/supply/qcom/smb-lib.h +3 −1 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ enum print_reason { #define MICRO_USB_VOTER "MICRO_USB_VOTER" #define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" #define PD_SUSPEND_SUPPORTED_VOTER "PD_SUSPEND_SUPPORTED_VOTER" #define PL_DELAY_HVDCP_VOTER "PL_DELAY_HVDCP_VOTER" #define PL_DELAY_VOTER "PL_DELAY_VOTER" #define CTM_VOTER "CTM_VOTER" #define SW_QC3_VOTER "SW_QC3_VOTER" #define AICL_RERUN_VOTER "AICL_RERUN_VOTER" Loading Loading @@ -288,6 +288,7 @@ struct smb_charger { struct work_struct vconn_oc_work; struct delayed_work otg_ss_done_work; struct delayed_work icl_change_work; struct delayed_work pl_enable_work; /* cached status */ int voltage_min_uv; Loading Loading @@ -491,6 +492,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_set_icl_reduction(struct smb_charger *chg, int reduction_ua); int smblib_dp_dm(struct smb_charger *chg, int val); int smblib_rerun_aicl(struct smb_charger *chg); int smblib_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); Loading Loading
drivers/power/power_supply_sysfs.c +1 −0 Original line number Diff line number Diff line Loading @@ -293,6 +293,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(die_health), POWER_SUPPLY_ATTR(connector_health), POWER_SUPPLY_ATTR(ctm_current_max), POWER_SUPPLY_ATTR(hw_current_max), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ Loading
drivers/power/supply/qcom/battery.c +36 −5 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct pl_data { struct votable *pl_disable_votable; struct votable *pl_awake_votable; struct votable *hvdcp_hw_inov_dis_votable; struct votable *usb_icl_votable; struct work_struct status_change_work; struct work_struct pl_disable_forever_work; struct delayed_work pl_taper_work; Loading Loading @@ -487,6 +488,25 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, return 0; } static int usb_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) { struct pl_data *chip = data; union power_supply_propval pval = {0, }; if (!chip->main_psy) return 0; if (client == NULL) icl_ua = INT_MAX; pval.intval = icl_ua; return power_supply_set_property(chip->main_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, &pval); return 0; } static void pl_disable_forever_work(struct work_struct *work) { struct pl_data *chip = container_of(work, Loading Loading @@ -596,13 +616,15 @@ static int pl_awake_vote_callback(struct votable *votable, static bool is_main_available(struct pl_data *chip) { if (!chip->main_psy) if (chip->main_psy) return true; chip->main_psy = power_supply_get_by_name("main"); if (!chip->main_psy) return false; if (chip->main_psy) rerun_election(chip->usb_icl_votable); return true; return !!chip->main_psy; } static bool is_batt_available(struct pl_data *chip) Loading Loading @@ -855,6 +877,14 @@ static int pl_init(void) goto destroy_votable; } chip->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, usb_icl_vote_callback, chip); if (IS_ERR(chip->usb_icl_votable)) { rc = PTR_ERR(chip->usb_icl_votable); goto destroy_votable; } chip->pl_disable_votable = create_votable("PL_DISABLE", VOTE_SET_ANY, pl_disable_vote_callback, chip); Loading Loading @@ -909,6 +939,7 @@ destroy_votable: destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); destroy_votable(chip->usb_icl_votable); release_wakeup_source: wakeup_source_unregister(chip->pl_ws); cleanup: Loading
drivers/power/supply/qcom/qpnp-smb2.c +19 −0 Original line number Diff line number Diff line Loading @@ -616,6 +616,7 @@ static enum power_supply_property smb2_usb_main_props[] = { POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, POWER_SUPPLY_PROP_FCC_DELTA, POWER_SUPPLY_PROP_CURRENT_MAX, /* * TODO move the TEMP and TEMP_MAX properties here, * and update the thermal balancer to look here Loading Loading @@ -653,6 +654,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FCC_DELTA: rc = smblib_get_prop_fcc_delta(chg, val); break; case POWER_SUPPLY_PROP_CURRENT_MAX: val->intval = get_effective_result(chg->usb_icl_votable); break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; Loading Loading @@ -683,6 +687,9 @@ static int smb2_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); break; case POWER_SUPPLY_PROP_CURRENT_MAX: rc = smblib_set_icl_current(chg, val->intval); break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading Loading @@ -1572,6 +1579,16 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } /* disable h/w autonomous parallel charging control */ rc = smblib_masked_write(chg, MISC_CFG_REG, STAT_PARALLEL_1400MA_EN_CFG_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't disable h/w autonomous parallel control rc=%d\n", rc); return rc; } /* configure float charger options */ switch (chip->dt.float_option) { case 1: Loading Loading @@ -2230,6 +2247,8 @@ static int smb2_probe(struct platform_device *pdev) } batt_charge_type = val.intval; device_init_wakeup(chg->dev, true); pr_info("QPNP SMB2 probed successfully usb:present=%d type=%d batt:present = %d health = %d charge = %d\n", usb_present, chg->usb_psy_desc.type, batt_present, batt_health, batt_charge_type); Loading
drivers/power/supply/qcom/smb-lib.c +53 −63 Original line number Diff line number Diff line Loading @@ -654,10 +654,13 @@ static void smblib_uusb_removal(struct smb_charger *chg) { int rc; cancel_delayed_work_sync(&chg->pl_enable_work); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); /* reset both usbin current and voltage votes */ vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, false, 0); vote(chg->pl_enable_votable_indirect, USBIN_V_VOTER, false, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); Loading Loading @@ -795,29 +798,12 @@ static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count) return 0; } /********************* * VOTABLE CALLBACKS * *********************/ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, int suspend, const char *client) { struct smb_charger *chg = data; /* resume input if suspend is invalid */ if (suspend < 0) suspend = 0; return smblib_set_dc_suspend(chg, (bool)suspend); } #define USBIN_25MA 25000 #define USBIN_100MA 100000 #define USBIN_150MA 150000 #define USBIN_500MA 500000 #define USBIN_900MA 900000 static int set_sdp_current(struct smb_charger *chg, int icl_ua) { int rc; Loading Loading @@ -856,20 +842,18 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) return rc; } static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { struct smb_charger *chg = data; int rc = 0; bool override; union power_supply_propval pval; /* suspend and return if 25mA or less is requested */ if (client && (icl_ua < USBIN_25MA)) if (icl_ua < USBIN_25MA) return smblib_set_usb_suspend(chg, true); disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq); if (!client) if (icl_ua == INT_MAX) goto override_suspend_config; rc = smblib_get_prop_typec_mode(chg, &pval); Loading Loading @@ -898,7 +882,7 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, override_suspend_config: /* determine if override needs to be enforced */ override = true; if (client == NULL) { if (icl_ua == INT_MAX) { /* remove override if no voters - hw defaults is desired */ override = false; } else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { Loading Loading @@ -936,6 +920,22 @@ enable_icl_changed_interrupt: return rc; } /********************* * VOTABLE CALLBACKS * *********************/ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, int suspend, const char *client) { struct smb_charger *chg = data; /* resume input if suspend is invalid */ if (suspend < 0) suspend = 0; return smblib_set_dc_suspend(chg, (bool)suspend); } static int smblib_dc_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) { Loading Loading @@ -2618,16 +2618,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); return rc; } /* pd active set, parallel charger can be enabled now */ rc = vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); if (rc < 0) { smblib_err(chg, "Couldn't unvote PL_DELAY_HVDCP_VOTER rc=%d\n", rc); return rc; } } /* CC pin selection s/w override in PD session; h/w otherwise. */ Loading Loading @@ -3159,6 +3149,7 @@ irqreturn_t smblib_handle_usbin_uv(int irq, void *data) return IRQ_HANDLED; } #define PL_DELAY_MS 30000 irqreturn_t smblib_handle_usb_plugin(int irq, void *data) { struct smb_irq_data *irq_data = data; Loading Loading @@ -3197,6 +3188,11 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data) smblib_err(chg, "Couldn't enable dpdm regulator rc=%d\n", rc); } /* Schedule work to enable parallel charger */ vote(chg->awake_votable, PL_DELAY_VOTER, true, 0); schedule_delayed_work(&chg->pl_enable_work, msecs_to_jiffies(PL_DELAY_MS)); } else { if (chg->wa_flags & BOOST_BACK_WA) vote(chg->usb_icl_votable, BOOST_BACK_VOTER, false, 0); Loading Loading @@ -3374,9 +3370,6 @@ static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg, } } /* QC authentication done, parallel charger can be enabled now */ vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); smblib_dbg(chg, PR_INTERRUPT, "IRQ: hvdcp-3p0-auth-done rising; %s detected\n", apsd_result->name); } Loading Loading @@ -3406,15 +3399,6 @@ static void smblib_handle_hvdcp_check_timeout(struct smb_charger *chg, /* enforce DCP ICL if specified */ vote(chg->usb_icl_votable, DCP_VOTER, chg->dcp_icl_ua != -EINVAL, chg->dcp_icl_ua); /* * If adapter is not QC2.0/QC3.0 remove vote for parallel * disable. * Otherwise if adapter is QC2.0/QC3.0 wait for authentication * to complete. */ if (!qc_charger) vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); } smblib_dbg(chg, PR_INTERRUPT, "IRQ: smblib_handle_hvdcp_check_timeout %s\n", Loading Loading @@ -3486,13 +3470,9 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising) true); case OCP_CHARGER_BIT: case FLOAT_CHARGER_BIT: /* * if not DCP then no hvdcp timeout happens. Enable * pd/parallel here. */ /* if not DCP then no hvdcp timeout happens, Enable pd here. */ vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, false, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); break; case DCP_CHARGER_BIT: if (chg->wa_flags & QC_CHARGER_DETECTION_WA_BIT) Loading Loading @@ -3645,9 +3625,12 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) { int rc; cancel_delayed_work_sync(&chg->pl_enable_work); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, true, 0); vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER, true, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0); vote(chg->usb_irq_enable_votable, QC_VOTER, false, 0); Loading Loading @@ -3703,8 +3686,6 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg, if (rp == POWER_SUPPLY_TYPEC_SOURCE_HIGH || rp == POWER_SUPPLY_TYPEC_NON_COMPLIANT) { smblib_dbg(chg, PR_MISC, "VBUS & CC could be shorted; keeping HVDCP disabled\n"); /* HVDCP is not going to be enabled; enable parallel */ vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, false, 0); vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); } else { Loading Loading @@ -4210,6 +4191,16 @@ static void smblib_icl_change_work(struct work_struct *work) smblib_dbg(chg, PR_INTERRUPT, "icl_settled=%d\n", settled_ua); } static void smblib_pl_enable_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, pl_enable_work.work); smblib_dbg(chg, PR_PARALLEL, "timer expired, enabling parallel\n"); vote(chg->pl_disable_votable, PL_DELAY_VOTER, false, 0); vote(chg->awake_votable, PL_DELAY_VOTER, false, 0); } static int smblib_create_votables(struct smb_charger *chg) { int rc = 0; Loading @@ -4226,13 +4217,19 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } chg->usb_icl_votable = find_votable("USB_ICL"); if (!chg->usb_icl_votable) { rc = -EPROBE_DEFER; return rc; } chg->pl_disable_votable = find_votable("PL_DISABLE"); if (!chg->pl_disable_votable) { rc = -EPROBE_DEFER; return rc; } vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); vote(chg->pl_disable_votable, PL_DELAY_HVDCP_VOTER, true, 0); vote(chg->pl_disable_votable, PL_DELAY_VOTER, true, 0); chg->dc_suspend_votable = create_votable("DC_SUSPEND", VOTE_SET_ANY, smblib_dc_suspend_vote_callback, Loading @@ -4242,14 +4239,6 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, smblib_usb_icl_vote_callback, chg); if (IS_ERR(chg->usb_icl_votable)) { rc = PTR_ERR(chg->usb_icl_votable); return rc; } chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN, smblib_dc_icl_vote_callback, chg); Loading Loading @@ -4400,6 +4389,7 @@ int smblib_init(struct smb_charger *chg) INIT_WORK(&chg->vconn_oc_work, smblib_vconn_oc_work); INIT_DELAYED_WORK(&chg->otg_ss_done_work, smblib_otg_ss_done_work); INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work); INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work); chg->fake_capacity = -EINVAL; switch (chg->mode) { Loading
drivers/power/supply/qcom/smb-lib.h +3 −1 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ enum print_reason { #define MICRO_USB_VOTER "MICRO_USB_VOTER" #define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" #define PD_SUSPEND_SUPPORTED_VOTER "PD_SUSPEND_SUPPORTED_VOTER" #define PL_DELAY_HVDCP_VOTER "PL_DELAY_HVDCP_VOTER" #define PL_DELAY_VOTER "PL_DELAY_VOTER" #define CTM_VOTER "CTM_VOTER" #define SW_QC3_VOTER "SW_QC3_VOTER" #define AICL_RERUN_VOTER "AICL_RERUN_VOTER" Loading Loading @@ -288,6 +288,7 @@ struct smb_charger { struct work_struct vconn_oc_work; struct delayed_work otg_ss_done_work; struct delayed_work icl_change_work; struct delayed_work pl_enable_work; /* cached status */ int voltage_min_uv; Loading Loading @@ -491,6 +492,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_set_icl_reduction(struct smb_charger *chg, int reduction_ua); int smblib_dp_dm(struct smb_charger *chg, int val); int smblib_rerun_aicl(struct smb_charger *chg); int smblib_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); Loading