Loading drivers/power/supply/power_supply_sysfs.c +1 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(ctm_current_max), POWER_SUPPLY_ATTR(hw_current_max), POWER_SUPPLY_ATTR(real_type), POWER_SUPPLY_ATTR(pr_swap), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ Loading drivers/power/supply/qcom/battery.c +0 −5 Original line number Diff line number Diff line Loading @@ -551,8 +551,6 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, power_supply_set_property(chip->main_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &pval); /* wait for ICL change */ msleep(100); } /* set the effective ICL */ Loading @@ -560,9 +558,6 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, power_supply_set_property(chip->main_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &pval); if (rerun_aicl) /* wait for ICL change */ msleep(100); vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0); Loading drivers/power/supply/qcom/qpnp-fg-gen3.c +12 −6 Original line number Diff line number Diff line Loading @@ -491,7 +491,7 @@ static void fg_encode_default(struct fg_sram_param *sp, int i, mask = 0xff; int64_t temp; temp = DIV_ROUND_CLOSEST(val * sp[id].numrtr, sp[id].denmtr); temp = (int64_t)div_s64((s64)val * sp[id].numrtr, sp[id].denmtr); pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val); for (i = 0; i < sp[id].len; i++) { buf[i] = temp & mask; Loading Loading @@ -1320,9 +1320,16 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip) return rc; } cc_soc_delta_pct = DIV_ROUND_CLOSEST( abs(cc_soc_sw - chip->cl.init_cc_soc_sw) * 100, cc_soc_delta_pct = div64_s64((int64_t)(cc_soc_sw - chip->cl.init_cc_soc_sw) * 100, CC_SOC_30BIT); /* If the delta is < 50%, then skip processing full data */ if (cc_soc_delta_pct < 50) { pr_err("cc_soc_delta_pct: %d\n", cc_soc_delta_pct); return -ERANGE; } delta_cc_uah = div64_s64(chip->cl.learned_cc_uah * cc_soc_delta_pct, 100); chip->cl.final_cc_uah = chip->cl.init_cc_uah + delta_cc_uah; Loading Loading @@ -1392,7 +1399,6 @@ static int fg_cap_learning_done(struct fg_chip *chip) return rc; } #define FULL_SOC_RAW 255 static void fg_cap_learning_update(struct fg_chip *chip) { int rc, batt_soc, batt_soc_msb; Loading Loading @@ -3937,7 +3943,7 @@ static int fg_parse_ki_coefficients(struct fg_chip *chip) } #define DEFAULT_CUTOFF_VOLT_MV 3200 #define DEFAULT_EMPTY_VOLT_MV 2800 #define DEFAULT_EMPTY_VOLT_MV 2850 #define DEFAULT_RECHARGE_VOLT_MV 4250 #define DEFAULT_CHG_TERM_CURR_MA 100 #define DEFAULT_CHG_TERM_BASE_CURR_MA 75 Loading drivers/power/supply/qcom/qpnp-smb2.c +10 −5 Original line number Diff line number Diff line Loading @@ -432,6 +432,7 @@ static enum power_supply_property smb2_usb_props[] = { POWER_SUPPLY_PROP_CTM_CURRENT_MAX, POWER_SUPPLY_PROP_HW_CURRENT_MAX, POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_PR_SWAP, }; static int smb2_usb_get_prop(struct power_supply *psy, Loading @@ -454,8 +455,7 @@ static int smb2_usb_get_prop(struct power_supply *psy, if (!val->intval) break; rc = smblib_get_prop_typec_mode(chg, val); if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) val->intval = 0; Loading Loading @@ -492,7 +492,7 @@ static int smb2_usb_get_prop(struct power_supply *psy, else if (chip->bad_part) val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; else rc = smblib_get_prop_typec_mode(chg, val); val->intval = chg->typec_mode; break; case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: if (chg->micro_usb_mode) Loading Loading @@ -536,6 +536,9 @@ static int smb2_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_HW_CURRENT_MAX: rc = smblib_get_charge_current(chg, &val->intval); break; case POWER_SUPPLY_PROP_PR_SWAP: rc = smblib_get_prop_pr_swap_in_progress(chg, val); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -594,6 +597,9 @@ static int smb2_usb_set_prop(struct power_supply *psy, rc = vote(chg->usb_icl_votable, CTM_VOTER, val->intval >= 0, val->intval); break; case POWER_SUPPLY_PROP_PR_SWAP: rc = smblib_set_prop_pr_swap_in_progress(chg, val); break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading Loading @@ -671,8 +677,7 @@ static int smb2_usb_port_get_prop(struct power_supply *psy, if (!val->intval) break; rc = smblib_get_prop_typec_mode(chg, val); if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) val->intval = 1; Loading drivers/power/supply/qcom/smb-lib.c +133 −114 Original line number Diff line number Diff line Loading @@ -637,6 +637,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) /* 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->usb_icl_votable, SW_QC3_VOTER, false, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); Loading Loading @@ -839,7 +840,6 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { int rc = 0; bool override; union power_supply_propval pval; /* suspend and return if 25mA or less is requested */ if (icl_ua < USBIN_25MA) Loading @@ -849,14 +849,8 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) if (icl_ua == INT_MAX) goto override_suspend_config; rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc); goto enable_icl_changed_interrupt; } /* configure current */ if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) { rc = set_sdp_current(chg, icl_ua); if (rc < 0) { Loading @@ -864,6 +858,7 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) goto enable_icl_changed_interrupt; } } else { set_sdp_current(chg, 100000); rc = smblib_set_charge_param(chg, &chg->param.usb_icl, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc); Loading @@ -877,7 +872,7 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) 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) { } else if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB) /* For std cable with type = SDP never override */ override = false; Loading Loading @@ -917,15 +912,8 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) int rc = 0; u8 load_cfg; bool override; union power_supply_propval pval; rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc); return rc; } if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); Loading Loading @@ -1895,8 +1883,6 @@ int smblib_rerun_aicl(struct smb_charger *chg) return rc; smblib_dbg(chg, PR_MISC, "re-running AICL\n"); switch (chg->smb_version) { case PMI8998_SUBTYPE: rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &settled_icl_ua); if (rc < 0) { Loading @@ -1908,24 +1894,6 @@ int smblib_rerun_aicl(struct smb_charger *chg) max(settled_icl_ua - chg->param.usb_icl.step_u, chg->param.usb_icl.step_u)); vote(chg->usb_icl_votable, AICL_RERUN_VOTER, false, 0); break; case PM660_SUBTYPE: /* * Use restart_AICL instead of trigger_AICL as it runs the * complete AICL instead of starting from the last settled * value. */ rc = smblib_masked_write(chg, CMD_HVDCP_2_REG, RESTART_AICL_BIT, RESTART_AICL_BIT); if (rc < 0) smblib_err(chg, "Couldn't write to CMD_HVDCP_2_REG rc=%d\n", rc); break; default: smblib_dbg(chg, PR_PARALLEL, "unknown SMB chip %d\n", chg->smb_version); return -EINVAL; } return 0; } Loading Loading @@ -1961,6 +1929,7 @@ static int smblib_dm_pulse(struct smb_charger *chg) int smblib_dp_dm(struct smb_charger *chg, int val) { int target_icl_ua, rc = 0; union power_supply_propval pval; switch (val) { case POWER_SUPPLY_DP_DM_DP_PULSE: Loading @@ -1978,10 +1947,35 @@ int smblib_dp_dm(struct smb_charger *chg, int val) rc, chg->pulse_cnt); break; case POWER_SUPPLY_DP_DM_ICL_DOWN: chg->usb_icl_delta_ua -= 100000; target_icl_ua = get_effective_result(chg->usb_icl_votable); if (target_icl_ua < 0) { /* no client vote, get the ICL from charger */ rc = power_supply_get_property(chg->usb_psy, POWER_SUPPLY_PROP_HW_CURRENT_MAX, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get max current rc=%d\n", rc); return rc; } target_icl_ua = pval.intval; } /* * Check if any other voter voted on USB_ICL in case of * voter other than SW_QC3_VOTER reset and restart reduction * again. */ if (target_icl_ua != get_client_vote(chg->usb_icl_votable, SW_QC3_VOTER)) chg->usb_icl_delta_ua = 0; chg->usb_icl_delta_ua += 100000; vote(chg->usb_icl_votable, SW_QC3_VOTER, true, target_icl_ua + chg->usb_icl_delta_ua); target_icl_ua - 100000); smblib_dbg(chg, PR_PARALLEL, "ICL DOWN ICL=%d reduction=%d\n", target_icl_ua, chg->usb_icl_delta_ua); break; case POWER_SUPPLY_DP_DM_ICL_UP: default: Loading Loading @@ -2217,8 +2211,6 @@ static const char * const smblib_typec_mode_name[] = { static int smblib_get_prop_ufp_mode(struct smb_charger *chg) { switch (chg->typec_status[0]) { case 0: return POWER_SUPPLY_TYPEC_NONE; case UFP_TYPEC_RDSTD_BIT: return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; case UFP_TYPEC_RD1P5_BIT: Loading @@ -2229,7 +2221,7 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg) break; } return POWER_SUPPLY_TYPEC_NON_COMPLIANT; return POWER_SUPPLY_TYPEC_NONE; } static int smblib_get_prop_dfp_mode(struct smb_charger *chg) Loading @@ -2243,8 +2235,6 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg) return POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE; case DFP_RD_OPEN_BIT: return POWER_SUPPLY_TYPEC_SINK; case DFP_RA_OPEN_BIT: return POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY; default: break; } Loading @@ -2252,20 +2242,12 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg) return POWER_SUPPLY_TYPEC_NONE; } int smblib_get_prop_typec_mode(struct smb_charger *chg, union power_supply_propval *val) static int smblib_get_prop_typec_mode(struct smb_charger *chg) { if (!(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT)) { val->intval = POWER_SUPPLY_TYPEC_NONE; return 0; } if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) val->intval = smblib_get_prop_dfp_mode(chg); return smblib_get_prop_dfp_mode(chg); else val->intval = smblib_get_prop_ufp_mode(chg); return 0; return smblib_get_prop_ufp_mode(chg); } int smblib_get_prop_typec_power_role(struct smb_charger *chg, Loading Loading @@ -2553,24 +2535,12 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, const union power_supply_propval *val) { int rc; bool orientation, cc_debounced, sink_attached, hvdcp; bool orientation, sink_attached, hvdcp; u8 stat; if (!get_effective_result(chg->pd_allowed_votable)) return -EINVAL; rc = smblib_read(chg, APSD_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read APSD status rc=%d\n", rc); return rc; } cc_debounced = (bool) (chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT); sink_attached = (bool) (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT); hvdcp = stat & QC_CHARGER_BIT; chg->pd_active = val->intval; if (chg->pd_active) { vote(chg->apsd_disable_votable, PD_VOTER, true, 0); Loading Loading @@ -2622,6 +2592,14 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, if (rc < 0) smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); } else { rc = smblib_read(chg, APSD_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read APSD status rc=%d\n", rc); return rc; } hvdcp = stat & QC_CHARGER_BIT; vote(chg->apsd_disable_votable, PD_VOTER, false, 0); vote(chg->pd_allowed_votable, PD_VOTER, true, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0); Loading @@ -2641,8 +2619,8 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, * and data could be interrupted. Non-legacy DCP could also draw * more, but it may impact compliance. */ if (!chg->typec_legacy_valid && cc_debounced && !sink_attached && hvdcp) sink_attached = chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT; if (!chg->typec_legacy_valid && !sink_attached && hvdcp) schedule_work(&chg->legacy_detection_work); } Loading Loading @@ -2764,6 +2742,7 @@ static int smblib_cc2_sink_removal_enter(struct smb_charger *chg) smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); return rc; } ccout = (stat & CC_ATTACHED_BIT) ? (!!(stat & CC_ORIENTATION_BIT) + 1) : 0; ufp_mode = (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT) ? Loading Loading @@ -3600,6 +3579,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); vote(chg->usb_icl_votable, DCP_VOTER, false, 0); vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0); vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0); /* reset hvdcp voters */ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); Loading Loading @@ -3630,6 +3610,11 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) chg->pd_hard_reset = 0; chg->typec_legacy_valid = false; /* reset back to 120mS tCC debounce */ rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, 0); if (rc < 0) smblib_err(chg, "Couldn't set 120mS tCC debounce rc=%d\n", rc); /* enable APSD CC trigger for next insertion */ rc = smblib_masked_write(chg, TYPE_C_CFG_REG, APSD_START_ON_CC_BIT, APSD_START_ON_CC_BIT); Loading Loading @@ -3670,12 +3655,29 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) if (rc < 0) smblib_err(chg, "Couldn't restore crude sensor rc=%d\n", rc); mutex_lock(&chg->vconn_oc_lock); if (!chg->vconn_en) goto unlock; smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, VCONN_EN_VALUE_BIT, 0); chg->vconn_en = false; unlock: mutex_unlock(&chg->vconn_oc_lock); /* clear exit sink based on cc */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, EXIT_SNK_BASED_ON_CC_BIT, 0); if (rc < 0) smblib_err(chg, "Couldn't clear exit_sink_based_on_cc rc=%d\n", rc); typec_sink_removal(chg); smblib_update_usb_type(chg); } static void smblib_handle_typec_insertion(struct smb_charger *chg, bool sink_attached) static void smblib_handle_typec_insertion(struct smb_charger *chg) { int rc; Loading @@ -3687,45 +3689,37 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg, smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n", rc); if (sink_attached) if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) typec_sink_insertion(chg); else typec_sink_removal(chg); } static void smblib_handle_typec_debounce_done(struct smb_charger *chg, bool rising, bool sink_attached) static void smblib_handle_typec_cc_state_change(struct smb_charger *chg) { int rc; union power_supply_propval pval = {0, }; if (chg->pr_swap_in_progress) return; if (rising) { if (!chg->typec_present) { chg->typec_mode = smblib_get_prop_typec_mode(chg); if (!chg->typec_present && chg->typec_mode != POWER_SUPPLY_TYPEC_NONE) { chg->typec_present = true; smblib_dbg(chg, PR_MISC, "TypeC insertion\n"); smblib_handle_typec_insertion(chg, sink_attached); } } else { if (chg->typec_present) { smblib_dbg(chg, PR_MISC, "TypeC %s insertion\n", smblib_typec_mode_name[chg->typec_mode]); smblib_handle_typec_insertion(chg); } else if (chg->typec_present && chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) { chg->typec_present = false; smblib_dbg(chg, PR_MISC, "TypeC removal\n"); smblib_handle_typec_removal(chg); } } rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc); smblib_dbg(chg, PR_INTERRUPT, "IRQ: debounce-done %s; Type-C %s detected\n", rising ? "rising" : "falling", smblib_typec_mode_name[pval.intval]); smblib_dbg(chg, PR_INTERRUPT, "IRQ: cc-state-change; Type-C %s detected\n", smblib_typec_mode_name[chg->typec_mode]); } static void smblib_usb_typec_change(struct smb_charger *chg) { int rc; bool debounce_done, sink_attached; rc = smblib_multibyte_read(chg, TYPE_C_STATUS_1_REG, chg->typec_status, 5); Loading @@ -3734,12 +3728,7 @@ static void smblib_usb_typec_change(struct smb_charger *chg) return; } debounce_done = (bool)(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT); sink_attached = (bool)(chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT); smblib_handle_typec_debounce_done(chg, debounce_done, sink_attached); smblib_handle_typec_cc_state_change(chg); if (chg->typec_status[3] & TYPEC_VBUS_ERROR_STATUS_BIT) smblib_dbg(chg, PR_INTERRUPT, "IRQ: vbus-error\n"); Loading Loading @@ -3842,6 +3831,36 @@ irqreturn_t smblib_handle_wdog_bark(int irq, void *data) return IRQ_HANDLED; } /************** * Additional USB PSY getters/setters * that call interrupt functions ***************/ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, union power_supply_propval *val) { val->intval = chg->pr_swap_in_progress; return 0; } int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, const union power_supply_propval *val) { int rc; chg->pr_swap_in_progress = val->intval; /* * call the cc changed irq to handle real removals while * PR_SWAP was in progress */ smblib_usb_typec_change(chg); rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, val->intval ? TCC_DEBOUNCE_20MS_BIT : 0); if (rc < 0) smblib_err(chg, "Couldn't set tCC debounce rc=%d\n", rc); return 0; } /*************** * Work Queues * ***************/ Loading Loading @@ -4230,14 +4249,14 @@ static void smblib_legacy_detection_work(struct work_struct *work) chg->typec_legacy_valid = true; vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0); legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT; rp_high = smblib_get_prop_ufp_mode(chg) == POWER_SUPPLY_TYPEC_SOURCE_HIGH; rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH; if (!legacy || !rp_high) vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, false, 0); unlock: chg->typec_en_dis_active = 0; smblib_usb_typec_change(chg); mutex_unlock(&chg->lock); } Loading Loading
drivers/power/supply/power_supply_sysfs.c +1 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(ctm_current_max), POWER_SUPPLY_ATTR(hw_current_max), POWER_SUPPLY_ATTR(real_type), POWER_SUPPLY_ATTR(pr_swap), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ Loading
drivers/power/supply/qcom/battery.c +0 −5 Original line number Diff line number Diff line Loading @@ -551,8 +551,6 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, power_supply_set_property(chip->main_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &pval); /* wait for ICL change */ msleep(100); } /* set the effective ICL */ Loading @@ -560,9 +558,6 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, power_supply_set_property(chip->main_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &pval); if (rerun_aicl) /* wait for ICL change */ msleep(100); vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0); Loading
drivers/power/supply/qcom/qpnp-fg-gen3.c +12 −6 Original line number Diff line number Diff line Loading @@ -491,7 +491,7 @@ static void fg_encode_default(struct fg_sram_param *sp, int i, mask = 0xff; int64_t temp; temp = DIV_ROUND_CLOSEST(val * sp[id].numrtr, sp[id].denmtr); temp = (int64_t)div_s64((s64)val * sp[id].numrtr, sp[id].denmtr); pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val); for (i = 0; i < sp[id].len; i++) { buf[i] = temp & mask; Loading Loading @@ -1320,9 +1320,16 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip) return rc; } cc_soc_delta_pct = DIV_ROUND_CLOSEST( abs(cc_soc_sw - chip->cl.init_cc_soc_sw) * 100, cc_soc_delta_pct = div64_s64((int64_t)(cc_soc_sw - chip->cl.init_cc_soc_sw) * 100, CC_SOC_30BIT); /* If the delta is < 50%, then skip processing full data */ if (cc_soc_delta_pct < 50) { pr_err("cc_soc_delta_pct: %d\n", cc_soc_delta_pct); return -ERANGE; } delta_cc_uah = div64_s64(chip->cl.learned_cc_uah * cc_soc_delta_pct, 100); chip->cl.final_cc_uah = chip->cl.init_cc_uah + delta_cc_uah; Loading Loading @@ -1392,7 +1399,6 @@ static int fg_cap_learning_done(struct fg_chip *chip) return rc; } #define FULL_SOC_RAW 255 static void fg_cap_learning_update(struct fg_chip *chip) { int rc, batt_soc, batt_soc_msb; Loading Loading @@ -3937,7 +3943,7 @@ static int fg_parse_ki_coefficients(struct fg_chip *chip) } #define DEFAULT_CUTOFF_VOLT_MV 3200 #define DEFAULT_EMPTY_VOLT_MV 2800 #define DEFAULT_EMPTY_VOLT_MV 2850 #define DEFAULT_RECHARGE_VOLT_MV 4250 #define DEFAULT_CHG_TERM_CURR_MA 100 #define DEFAULT_CHG_TERM_BASE_CURR_MA 75 Loading
drivers/power/supply/qcom/qpnp-smb2.c +10 −5 Original line number Diff line number Diff line Loading @@ -432,6 +432,7 @@ static enum power_supply_property smb2_usb_props[] = { POWER_SUPPLY_PROP_CTM_CURRENT_MAX, POWER_SUPPLY_PROP_HW_CURRENT_MAX, POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_PR_SWAP, }; static int smb2_usb_get_prop(struct power_supply *psy, Loading @@ -454,8 +455,7 @@ static int smb2_usb_get_prop(struct power_supply *psy, if (!val->intval) break; rc = smblib_get_prop_typec_mode(chg, val); if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) val->intval = 0; Loading Loading @@ -492,7 +492,7 @@ static int smb2_usb_get_prop(struct power_supply *psy, else if (chip->bad_part) val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; else rc = smblib_get_prop_typec_mode(chg, val); val->intval = chg->typec_mode; break; case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: if (chg->micro_usb_mode) Loading Loading @@ -536,6 +536,9 @@ static int smb2_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_HW_CURRENT_MAX: rc = smblib_get_charge_current(chg, &val->intval); break; case POWER_SUPPLY_PROP_PR_SWAP: rc = smblib_get_prop_pr_swap_in_progress(chg, val); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -594,6 +597,9 @@ static int smb2_usb_set_prop(struct power_supply *psy, rc = vote(chg->usb_icl_votable, CTM_VOTER, val->intval >= 0, val->intval); break; case POWER_SUPPLY_PROP_PR_SWAP: rc = smblib_set_prop_pr_swap_in_progress(chg, val); break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading Loading @@ -671,8 +677,7 @@ static int smb2_usb_port_get_prop(struct power_supply *psy, if (!val->intval) break; rc = smblib_get_prop_typec_mode(chg, val); if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && chg->real_charger_type == POWER_SUPPLY_TYPE_USB) val->intval = 1; Loading
drivers/power/supply/qcom/smb-lib.c +133 −114 Original line number Diff line number Diff line Loading @@ -637,6 +637,7 @@ static void smblib_uusb_removal(struct smb_charger *chg) /* 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->usb_icl_votable, SW_QC3_VOTER, false, 0); cancel_delayed_work_sync(&chg->hvdcp_detect_work); Loading Loading @@ -839,7 +840,6 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { int rc = 0; bool override; union power_supply_propval pval; /* suspend and return if 25mA or less is requested */ if (icl_ua < USBIN_25MA) Loading @@ -849,14 +849,8 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) if (icl_ua == INT_MAX) goto override_suspend_config; rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc); goto enable_icl_changed_interrupt; } /* configure current */ if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) { rc = set_sdp_current(chg, icl_ua); if (rc < 0) { Loading @@ -864,6 +858,7 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) goto enable_icl_changed_interrupt; } } else { set_sdp_current(chg, 100000); rc = smblib_set_charge_param(chg, &chg->param.usb_icl, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc); Loading @@ -877,7 +872,7 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) 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) { } else if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB) /* For std cable with type = SDP never override */ override = false; Loading Loading @@ -917,15 +912,8 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) int rc = 0; u8 load_cfg; bool override; union power_supply_propval pval; rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc); return rc; } if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); Loading Loading @@ -1895,8 +1883,6 @@ int smblib_rerun_aicl(struct smb_charger *chg) return rc; smblib_dbg(chg, PR_MISC, "re-running AICL\n"); switch (chg->smb_version) { case PMI8998_SUBTYPE: rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &settled_icl_ua); if (rc < 0) { Loading @@ -1908,24 +1894,6 @@ int smblib_rerun_aicl(struct smb_charger *chg) max(settled_icl_ua - chg->param.usb_icl.step_u, chg->param.usb_icl.step_u)); vote(chg->usb_icl_votable, AICL_RERUN_VOTER, false, 0); break; case PM660_SUBTYPE: /* * Use restart_AICL instead of trigger_AICL as it runs the * complete AICL instead of starting from the last settled * value. */ rc = smblib_masked_write(chg, CMD_HVDCP_2_REG, RESTART_AICL_BIT, RESTART_AICL_BIT); if (rc < 0) smblib_err(chg, "Couldn't write to CMD_HVDCP_2_REG rc=%d\n", rc); break; default: smblib_dbg(chg, PR_PARALLEL, "unknown SMB chip %d\n", chg->smb_version); return -EINVAL; } return 0; } Loading Loading @@ -1961,6 +1929,7 @@ static int smblib_dm_pulse(struct smb_charger *chg) int smblib_dp_dm(struct smb_charger *chg, int val) { int target_icl_ua, rc = 0; union power_supply_propval pval; switch (val) { case POWER_SUPPLY_DP_DM_DP_PULSE: Loading @@ -1978,10 +1947,35 @@ int smblib_dp_dm(struct smb_charger *chg, int val) rc, chg->pulse_cnt); break; case POWER_SUPPLY_DP_DM_ICL_DOWN: chg->usb_icl_delta_ua -= 100000; target_icl_ua = get_effective_result(chg->usb_icl_votable); if (target_icl_ua < 0) { /* no client vote, get the ICL from charger */ rc = power_supply_get_property(chg->usb_psy, POWER_SUPPLY_PROP_HW_CURRENT_MAX, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get max current rc=%d\n", rc); return rc; } target_icl_ua = pval.intval; } /* * Check if any other voter voted on USB_ICL in case of * voter other than SW_QC3_VOTER reset and restart reduction * again. */ if (target_icl_ua != get_client_vote(chg->usb_icl_votable, SW_QC3_VOTER)) chg->usb_icl_delta_ua = 0; chg->usb_icl_delta_ua += 100000; vote(chg->usb_icl_votable, SW_QC3_VOTER, true, target_icl_ua + chg->usb_icl_delta_ua); target_icl_ua - 100000); smblib_dbg(chg, PR_PARALLEL, "ICL DOWN ICL=%d reduction=%d\n", target_icl_ua, chg->usb_icl_delta_ua); break; case POWER_SUPPLY_DP_DM_ICL_UP: default: Loading Loading @@ -2217,8 +2211,6 @@ static const char * const smblib_typec_mode_name[] = { static int smblib_get_prop_ufp_mode(struct smb_charger *chg) { switch (chg->typec_status[0]) { case 0: return POWER_SUPPLY_TYPEC_NONE; case UFP_TYPEC_RDSTD_BIT: return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; case UFP_TYPEC_RD1P5_BIT: Loading @@ -2229,7 +2221,7 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg) break; } return POWER_SUPPLY_TYPEC_NON_COMPLIANT; return POWER_SUPPLY_TYPEC_NONE; } static int smblib_get_prop_dfp_mode(struct smb_charger *chg) Loading @@ -2243,8 +2235,6 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg) return POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE; case DFP_RD_OPEN_BIT: return POWER_SUPPLY_TYPEC_SINK; case DFP_RA_OPEN_BIT: return POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY; default: break; } Loading @@ -2252,20 +2242,12 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg) return POWER_SUPPLY_TYPEC_NONE; } int smblib_get_prop_typec_mode(struct smb_charger *chg, union power_supply_propval *val) static int smblib_get_prop_typec_mode(struct smb_charger *chg) { if (!(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT)) { val->intval = POWER_SUPPLY_TYPEC_NONE; return 0; } if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) val->intval = smblib_get_prop_dfp_mode(chg); return smblib_get_prop_dfp_mode(chg); else val->intval = smblib_get_prop_ufp_mode(chg); return 0; return smblib_get_prop_ufp_mode(chg); } int smblib_get_prop_typec_power_role(struct smb_charger *chg, Loading Loading @@ -2553,24 +2535,12 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, const union power_supply_propval *val) { int rc; bool orientation, cc_debounced, sink_attached, hvdcp; bool orientation, sink_attached, hvdcp; u8 stat; if (!get_effective_result(chg->pd_allowed_votable)) return -EINVAL; rc = smblib_read(chg, APSD_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read APSD status rc=%d\n", rc); return rc; } cc_debounced = (bool) (chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT); sink_attached = (bool) (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT); hvdcp = stat & QC_CHARGER_BIT; chg->pd_active = val->intval; if (chg->pd_active) { vote(chg->apsd_disable_votable, PD_VOTER, true, 0); Loading Loading @@ -2622,6 +2592,14 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, if (rc < 0) smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); } else { rc = smblib_read(chg, APSD_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read APSD status rc=%d\n", rc); return rc; } hvdcp = stat & QC_CHARGER_BIT; vote(chg->apsd_disable_votable, PD_VOTER, false, 0); vote(chg->pd_allowed_votable, PD_VOTER, true, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0); Loading @@ -2641,8 +2619,8 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, * and data could be interrupted. Non-legacy DCP could also draw * more, but it may impact compliance. */ if (!chg->typec_legacy_valid && cc_debounced && !sink_attached && hvdcp) sink_attached = chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT; if (!chg->typec_legacy_valid && !sink_attached && hvdcp) schedule_work(&chg->legacy_detection_work); } Loading Loading @@ -2764,6 +2742,7 @@ static int smblib_cc2_sink_removal_enter(struct smb_charger *chg) smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); return rc; } ccout = (stat & CC_ATTACHED_BIT) ? (!!(stat & CC_ORIENTATION_BIT) + 1) : 0; ufp_mode = (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT) ? Loading Loading @@ -3600,6 +3579,7 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0); vote(chg->usb_icl_votable, DCP_VOTER, false, 0); vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0); vote(chg->usb_icl_votable, SW_QC3_VOTER, false, 0); /* reset hvdcp voters */ vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, true, 0); Loading Loading @@ -3630,6 +3610,11 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) chg->pd_hard_reset = 0; chg->typec_legacy_valid = false; /* reset back to 120mS tCC debounce */ rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, 0); if (rc < 0) smblib_err(chg, "Couldn't set 120mS tCC debounce rc=%d\n", rc); /* enable APSD CC trigger for next insertion */ rc = smblib_masked_write(chg, TYPE_C_CFG_REG, APSD_START_ON_CC_BIT, APSD_START_ON_CC_BIT); Loading Loading @@ -3670,12 +3655,29 @@ static void smblib_handle_typec_removal(struct smb_charger *chg) if (rc < 0) smblib_err(chg, "Couldn't restore crude sensor rc=%d\n", rc); mutex_lock(&chg->vconn_oc_lock); if (!chg->vconn_en) goto unlock; smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, VCONN_EN_VALUE_BIT, 0); chg->vconn_en = false; unlock: mutex_unlock(&chg->vconn_oc_lock); /* clear exit sink based on cc */ rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG, EXIT_SNK_BASED_ON_CC_BIT, 0); if (rc < 0) smblib_err(chg, "Couldn't clear exit_sink_based_on_cc rc=%d\n", rc); typec_sink_removal(chg); smblib_update_usb_type(chg); } static void smblib_handle_typec_insertion(struct smb_charger *chg, bool sink_attached) static void smblib_handle_typec_insertion(struct smb_charger *chg) { int rc; Loading @@ -3687,45 +3689,37 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg, smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n", rc); if (sink_attached) if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) typec_sink_insertion(chg); else typec_sink_removal(chg); } static void smblib_handle_typec_debounce_done(struct smb_charger *chg, bool rising, bool sink_attached) static void smblib_handle_typec_cc_state_change(struct smb_charger *chg) { int rc; union power_supply_propval pval = {0, }; if (chg->pr_swap_in_progress) return; if (rising) { if (!chg->typec_present) { chg->typec_mode = smblib_get_prop_typec_mode(chg); if (!chg->typec_present && chg->typec_mode != POWER_SUPPLY_TYPEC_NONE) { chg->typec_present = true; smblib_dbg(chg, PR_MISC, "TypeC insertion\n"); smblib_handle_typec_insertion(chg, sink_attached); } } else { if (chg->typec_present) { smblib_dbg(chg, PR_MISC, "TypeC %s insertion\n", smblib_typec_mode_name[chg->typec_mode]); smblib_handle_typec_insertion(chg); } else if (chg->typec_present && chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) { chg->typec_present = false; smblib_dbg(chg, PR_MISC, "TypeC removal\n"); smblib_handle_typec_removal(chg); } } rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc); smblib_dbg(chg, PR_INTERRUPT, "IRQ: debounce-done %s; Type-C %s detected\n", rising ? "rising" : "falling", smblib_typec_mode_name[pval.intval]); smblib_dbg(chg, PR_INTERRUPT, "IRQ: cc-state-change; Type-C %s detected\n", smblib_typec_mode_name[chg->typec_mode]); } static void smblib_usb_typec_change(struct smb_charger *chg) { int rc; bool debounce_done, sink_attached; rc = smblib_multibyte_read(chg, TYPE_C_STATUS_1_REG, chg->typec_status, 5); Loading @@ -3734,12 +3728,7 @@ static void smblib_usb_typec_change(struct smb_charger *chg) return; } debounce_done = (bool)(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT); sink_attached = (bool)(chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT); smblib_handle_typec_debounce_done(chg, debounce_done, sink_attached); smblib_handle_typec_cc_state_change(chg); if (chg->typec_status[3] & TYPEC_VBUS_ERROR_STATUS_BIT) smblib_dbg(chg, PR_INTERRUPT, "IRQ: vbus-error\n"); Loading Loading @@ -3842,6 +3831,36 @@ irqreturn_t smblib_handle_wdog_bark(int irq, void *data) return IRQ_HANDLED; } /************** * Additional USB PSY getters/setters * that call interrupt functions ***************/ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, union power_supply_propval *val) { val->intval = chg->pr_swap_in_progress; return 0; } int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, const union power_supply_propval *val) { int rc; chg->pr_swap_in_progress = val->intval; /* * call the cc changed irq to handle real removals while * PR_SWAP was in progress */ smblib_usb_typec_change(chg); rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, val->intval ? TCC_DEBOUNCE_20MS_BIT : 0); if (rc < 0) smblib_err(chg, "Couldn't set tCC debounce rc=%d\n", rc); return 0; } /*************** * Work Queues * ***************/ Loading Loading @@ -4230,14 +4249,14 @@ static void smblib_legacy_detection_work(struct work_struct *work) chg->typec_legacy_valid = true; vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0); legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT; rp_high = smblib_get_prop_ufp_mode(chg) == POWER_SUPPLY_TYPEC_SOURCE_HIGH; rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH; if (!legacy || !rp_high) vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, false, 0); unlock: chg->typec_en_dis_active = 0; smblib_usb_typec_change(chg); mutex_unlock(&chg->lock); } Loading