Loading drivers/power/supply/qcom/qpnp-smb5.c +27 −0 Original line number Diff line number Diff line Loading @@ -561,10 +561,17 @@ static int smb5_parse_dt(struct smb5 *chip) chg->hw_skin_temp_mitigation = of_property_read_bool(node, "qcom,hw-skin-temp-mitigation"); chg->en_skin_therm_mitigation = of_property_read_bool(node, "qcom,en-skin-therm-mitigation"); chg->connector_pull_up = -EINVAL; of_property_read_u32(node, "qcom,connector-internal-pull-kohm", &chg->connector_pull_up); chg->smb_pull_up = -EINVAL; of_property_read_u32(node, "qcom,smb-internal-pull-kohm", &chg->smb_pull_up); chip->dt.adc_based_aicl = of_property_read_bool(node, "qcom,adc-based-aicl"); Loading Loading @@ -682,6 +689,7 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_QC_OPTI_DISABLE, POWER_SUPPLY_PROP_VOLTAGE_VPH, POWER_SUPPLY_PROP_THERM_ICL_LIMIT, POWER_SUPPLY_PROP_SKIN_HEALTH, }; static int smb5_usb_get_prop(struct power_supply *psy, Loading Loading @@ -856,6 +864,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: val->intval = chg->adapter_cc_mode; break; case POWER_SUPPLY_PROP_SKIN_HEALTH: val->intval = smblib_get_skin_temp_status(chg); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -1117,6 +1128,7 @@ static enum power_supply_property smb5_usb_main_props[] = { POWER_SUPPLY_PROP_FORCE_MAIN_FCC, POWER_SUPPLY_PROP_FORCE_MAIN_ICL, POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, POWER_SUPPLY_PROP_HEALTH, }; static int smb5_usb_main_get_prop(struct power_supply *psy, Loading Loading @@ -1176,6 +1188,10 @@ static int smb5_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: val->intval = chg->comp_clamp_level; break; /* Use this property to report SMB health */ case POWER_SUPPLY_PROP_HEALTH: val->intval = smblib_get_prop_smb_health(chg); break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; Loading Loading @@ -2830,6 +2846,17 @@ static int smb5_init_hw(struct smb5 *chip) } } if (chg->smb_pull_up != -EINVAL) { rc = smb5_configure_internal_pull(chg, SMB_THERM, get_valid_pullup(chg->smb_pull_up)); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SMB pull-up rc=%d\n", rc); return rc; } } return rc; } Loading drivers/power/supply/qcom/smb1390-charger-psy.c +82 −11 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ #define CORE_FTRIM_CTRL_REG 0x1031 #define TEMP_ALERT_LVL_MASK GENMASK(6, 5) #define TEMP_ALERT_LVL_SHIFT 5 #define TEMP_BUFFER_OUTPUT_BIT BIT(7) #define CORE_FTRIM_LVL_REG 0x1033 #define CFG_WIN_HI_MASK GENMASK(3, 2) Loading @@ -81,6 +82,7 @@ #define CORE_FTRIM_MISC_REG 0x1034 #define TR_WIN_1P5X_BIT BIT(0) #define TR_IREV_BIT BIT(1) #define WINDOW_DETECTION_DELTA_X1P0 0 #define WINDOW_DETECTION_DELTA_X1P5 1 Loading @@ -104,6 +106,8 @@ #define SOC_LEVEL_VOTER "SOC_LEVEL_VOTER" #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define MAIN_DISABLE_VOTER "MAIN_DISABLE_VOTER" #define TAPER_MAIN_ICL_LIMIT_VOTER "TAPER_MAIN_ICL_LIMIT_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 Loading @@ -112,6 +116,7 @@ #define MAX_ILIM_DUAL_CP_UA 6400000 #define CC_MODE_TAPER_DELTA_UA 200000 #define DEFAULT_TAPER_DELTA_UA 100000 #define CC_MODE_TAPER_MAIN_ICL_UA 500000 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ Loading Loading @@ -180,6 +185,8 @@ struct smb1390 { struct votable *fcc_votable; struct votable *fv_votable; struct votable *cp_awake_votable; struct votable *slave_disable_votable; struct votable *usb_icl_votable; /* power supplies */ struct power_supply *cps_psy; Loading Loading @@ -208,6 +215,7 @@ struct smb1390 { enum isns_mode current_capability; bool batt_soc_validated; int cp_slave_thr_taper_ua; int cc_mode_taper_main_icl_ua; }; struct smb_cfg { Loading Loading @@ -327,6 +335,14 @@ static bool is_psy_voter_available(struct smb1390 *chip) } } if (!chip->usb_icl_votable) { chip->usb_icl_votable = find_votable("USB_ICL"); if (!chip->usb_icl_votable) { smb1390_dbg(chip, PR_EXT_DEPENDENCY, "Couldn't find ICL votable\n"); return false; } } if (!chip->disable_votable) { smb1390_dbg(chip, PR_MISC, "Couldn't find CP DISABLE votable\n"); return false; Loading Loading @@ -839,15 +855,16 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data, { struct smb1390 *chip = data; int rc = 0; u8 mask, val; if (!is_psy_voter_available(chip) || chip->suspended) return -EAGAIN; mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; val = is_cps_available(chip) ? mask : CMD_EN_SWITCHER_BIT; rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, mask, disable ? 0 : val); if (is_cps_available(chip)) vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, disable ? true : false, 0); rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SWITCHER_BIT, disable ? 0 : CMD_EN_SWITCHER_BIT); if (rc < 0) { pr_err("Couldn't write CORE_CONTROL1_REG, rc=%d\n", rc); return rc; Loading @@ -861,6 +878,21 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data, return rc; } static int smb1390_slave_disable_vote_cb(struct votable *votable, void *data, int disable, const char *client) { struct smb1390 *chip = data; int rc; rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SL_BIT, disable ? 0 : CMD_EN_SL_BIT); if (rc < 0) pr_err("Couldn't %s slave rc=%d\n", disable ? "disable" : "enable", rc); return rc; } static int smb1390_ilim_vote_cb(struct votable *votable, void *data, int ilim_uA, const char *client) { Loading Loading @@ -1081,6 +1113,10 @@ static void smb1390_status_change_work(struct work_struct *work) 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); vote(chip->slave_disable_votable, TAPER_END_VOTER, false, 0); vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, true, 0); vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, false, 0); } out: Loading @@ -1091,18 +1127,14 @@ static void smb1390_status_change_work(struct work_struct *work) 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; vote(chip->slave_disable_votable, TAPER_END_VOTER, true, 0); /* * Set ILIM of master SMB1390 to Max value = 3.2A once slave is * disabled to prevent ILIM irq storm. Loading @@ -1111,6 +1143,10 @@ static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) fcc_uA); vote_override(chip->ilim_votable, CC_MODE_VOTER, true, MAX_ILIM_DUAL_CP_UA); if (chip->usb_icl_votable) vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, true, chip->cc_mode_taper_main_icl_ua); } return rc; Loading Loading @@ -1163,6 +1199,15 @@ static void smb1390_taper_work(struct work_struct *work) if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, true, 0); /* * When master CP is disabled, reset all votes * on ICL to enable Main charger to pump * charging current. */ if (chip->usb_icl_votable) vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, false, 0); goto out; } } else { Loading Loading @@ -1415,6 +1460,12 @@ static int smb1390_parse_dt(struct smb1390 *chip) 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); chip->cc_mode_taper_main_icl_ua = CC_MODE_TAPER_MAIN_ICL_UA; of_property_read_u32(chip->dev->of_node, "qcom,cc-mode-taper-main-icl-ua", &chip->cc_mode_taper_main_icl_ua); return 0; } Loading @@ -1438,6 +1489,11 @@ static int smb1390_create_votables(struct smb1390 *chip) if (IS_ERR(chip->ilim_votable)) return PTR_ERR(chip->ilim_votable); chip->slave_disable_votable = create_votable("CP_SLAVE_DISABLE", VOTE_SET_ANY, smb1390_slave_disable_vote_cb, chip); if (IS_ERR(chip->slave_disable_votable)) return PTR_ERR(chip->slave_disable_votable); /* * charge pump is initially disabled; this indirectly votes to allow * traditional parallel charging if present Loading Loading @@ -1507,6 +1563,12 @@ static int smb1390_init_hw(struct smb1390 *chip) return rc; } /* Configure IREV threshold to 200mA */ rc = smb1390_masked_write(chip, CORE_FTRIM_MISC_REG, TR_IREV_BIT, 0); if (rc < 0) { pr_err("Couldn't configure IREV threshold rc=%d\n", rc); return rc; } /* * If the slave charger has registered, configure Master SMB1390 for * triple-chg config, else configure for dual. Later, if the slave Loading Loading @@ -1829,6 +1891,15 @@ static int smb1390_slave_probe(struct smb1390 *chip) if (rc < 0) return rc; /* Configure Slave CP Temp buffer O/P to High Impedance */ rc = smb1390_masked_write(chip, CORE_FTRIM_CTRL_REG, TEMP_BUFFER_OUTPUT_BIT, TEMP_BUFFER_OUTPUT_BIT); if (rc < 0) { pr_err("Couldn't configure Slave temp Buffer rc=%d\n", rc); return rc; } rc = smb1390_init_cps_psy(chip); if (rc < 0) pr_err("Couldn't initialize cps psy rc=%d\n", rc); Loading drivers/power/supply/qcom/smb5-lib.c +52 −1 Original line number Diff line number Diff line Loading @@ -3675,6 +3675,54 @@ int smblib_get_pe_start(struct smb_charger *chg, return 0; } int smblib_get_prop_smb_health(struct smb_charger *chg) { int rc; u8 stat; int input_present; rc = smblib_is_input_present(chg, &input_present); if (rc < 0) return rc; if (input_present == INPUT_NOT_PRESENT) return POWER_SUPPLY_HEALTH_UNKNOWN; if (chg->wa_flags & SW_THERM_REGULATION_WA) { if (chg->smb_temp == -ENODATA) return POWER_SUPPLY_HEALTH_UNKNOWN; if (chg->smb_temp > SMB_TEMP_RST_THRESH) return POWER_SUPPLY_HEALTH_OVERHEAT; if (chg->smb_temp > SMB_TEMP_REG_H_THRESH) return POWER_SUPPLY_HEALTH_HOT; if (chg->smb_temp > SMB_TEMP_REG_L_THRESH) return POWER_SUPPLY_HEALTH_WARM; return POWER_SUPPLY_HEALTH_COOL; } rc = smblib_read(chg, SMB_TEMP_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read SMB_TEMP_STATUS_REG, rc=%d\n", rc); return POWER_SUPPLY_HEALTH_UNKNOWN; } if (stat & SMB_TEMP_RST_BIT) return POWER_SUPPLY_HEALTH_OVERHEAT; if (stat & SMB_TEMP_UB_BIT) return POWER_SUPPLY_HEALTH_HOT; if (stat & SMB_TEMP_LB_BIT) return POWER_SUPPLY_HEALTH_WARM; return POWER_SUPPLY_HEALTH_COOL; } int smblib_get_prop_die_health(struct smb_charger *chg) { int rc; Loading Loading @@ -3763,11 +3811,14 @@ static int smblib_get_typec_connector_temp_status(struct smb_charger *chg) return POWER_SUPPLY_HEALTH_COOL; } static int smblib_get_skin_temp_status(struct smb_charger *chg) int smblib_get_skin_temp_status(struct smb_charger *chg) { int rc; u8 stat; if (!chg->en_skin_therm_mitigation) return POWER_SUPPLY_HEALTH_UNKNOWN; rc = smblib_read(chg, SKIN_TEMP_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read SKIN_TEMP_STATUS_REG, rc=%d\n", Loading drivers/power/supply/qcom/smb5-lib.h +4 −0 Original line number Diff line number Diff line Loading @@ -531,7 +531,9 @@ struct smb_charger { bool hw_die_temp_mitigation; bool hw_connector_mitigation; bool hw_skin_temp_mitigation; bool en_skin_therm_mitigation; int connector_pull_up; int smb_pull_up; int aicl_5v_threshold_mv; int default_aicl_5v_threshold_mv; int aicl_cont_threshold_mv; Loading Loading @@ -718,7 +720,9 @@ int smblib_get_pe_start(struct smb_charger *chg, int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_die_health(struct smb_charger *chg); int smblib_get_prop_smb_health(struct smb_charger *chg); int smblib_get_prop_connector_health(struct smb_charger *chg); int smblib_get_skin_temp_status(struct smb_charger *chg); int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, Loading drivers/power/supply/qcom/smb5-reg.h +6 −0 Original line number Diff line number Diff line Loading @@ -493,6 +493,12 @@ enum { #define CONNECTOR_TEMP_UB_BIT BIT(1) #define CONNECTOR_TEMP_LB_BIT BIT(0) #define SMB_TEMP_STATUS_REG (MISC_BASE + 0x0A) #define SMB_TEMP_SHDN_BIT BIT(3) #define SMB_TEMP_RST_BIT BIT(2) #define SMB_TEMP_UB_BIT BIT(1) #define SMB_TEMP_LB_BIT BIT(0) #define BARK_BITE_WDOG_PET_REG (MISC_BASE + 0x43) #define BARK_BITE_WDOG_PET_BIT BIT(0) Loading Loading
drivers/power/supply/qcom/qpnp-smb5.c +27 −0 Original line number Diff line number Diff line Loading @@ -561,10 +561,17 @@ static int smb5_parse_dt(struct smb5 *chip) chg->hw_skin_temp_mitigation = of_property_read_bool(node, "qcom,hw-skin-temp-mitigation"); chg->en_skin_therm_mitigation = of_property_read_bool(node, "qcom,en-skin-therm-mitigation"); chg->connector_pull_up = -EINVAL; of_property_read_u32(node, "qcom,connector-internal-pull-kohm", &chg->connector_pull_up); chg->smb_pull_up = -EINVAL; of_property_read_u32(node, "qcom,smb-internal-pull-kohm", &chg->smb_pull_up); chip->dt.adc_based_aicl = of_property_read_bool(node, "qcom,adc-based-aicl"); Loading Loading @@ -682,6 +689,7 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_QC_OPTI_DISABLE, POWER_SUPPLY_PROP_VOLTAGE_VPH, POWER_SUPPLY_PROP_THERM_ICL_LIMIT, POWER_SUPPLY_PROP_SKIN_HEALTH, }; static int smb5_usb_get_prop(struct power_supply *psy, Loading Loading @@ -856,6 +864,9 @@ static int smb5_usb_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_ADAPTER_CC_MODE: val->intval = chg->adapter_cc_mode; break; case POWER_SUPPLY_PROP_SKIN_HEALTH: val->intval = smblib_get_skin_temp_status(chg); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading Loading @@ -1117,6 +1128,7 @@ static enum power_supply_property smb5_usb_main_props[] = { POWER_SUPPLY_PROP_FORCE_MAIN_FCC, POWER_SUPPLY_PROP_FORCE_MAIN_ICL, POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL, POWER_SUPPLY_PROP_HEALTH, }; static int smb5_usb_main_get_prop(struct power_supply *psy, Loading Loading @@ -1176,6 +1188,10 @@ static int smb5_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL: val->intval = chg->comp_clamp_level; break; /* Use this property to report SMB health */ case POWER_SUPPLY_PROP_HEALTH: val->intval = smblib_get_prop_smb_health(chg); break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; Loading Loading @@ -2830,6 +2846,17 @@ static int smb5_init_hw(struct smb5 *chip) } } if (chg->smb_pull_up != -EINVAL) { rc = smb5_configure_internal_pull(chg, SMB_THERM, get_valid_pullup(chg->smb_pull_up)); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SMB pull-up rc=%d\n", rc); return rc; } } return rc; } Loading
drivers/power/supply/qcom/smb1390-charger-psy.c +82 −11 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ #define CORE_FTRIM_CTRL_REG 0x1031 #define TEMP_ALERT_LVL_MASK GENMASK(6, 5) #define TEMP_ALERT_LVL_SHIFT 5 #define TEMP_BUFFER_OUTPUT_BIT BIT(7) #define CORE_FTRIM_LVL_REG 0x1033 #define CFG_WIN_HI_MASK GENMASK(3, 2) Loading @@ -81,6 +82,7 @@ #define CORE_FTRIM_MISC_REG 0x1034 #define TR_WIN_1P5X_BIT BIT(0) #define TR_IREV_BIT BIT(1) #define WINDOW_DETECTION_DELTA_X1P0 0 #define WINDOW_DETECTION_DELTA_X1P5 1 Loading @@ -104,6 +106,8 @@ #define SOC_LEVEL_VOTER "SOC_LEVEL_VOTER" #define HW_DISABLE_VOTER "HW_DISABLE_VOTER" #define CC_MODE_VOTER "CC_MODE_VOTER" #define MAIN_DISABLE_VOTER "MAIN_DISABLE_VOTER" #define TAPER_MAIN_ICL_LIMIT_VOTER "TAPER_MAIN_ICL_LIMIT_VOTER" #define CP_MASTER 0 #define CP_SLAVE 1 Loading @@ -112,6 +116,7 @@ #define MAX_ILIM_DUAL_CP_UA 6400000 #define CC_MODE_TAPER_DELTA_UA 200000 #define DEFAULT_TAPER_DELTA_UA 100000 #define CC_MODE_TAPER_MAIN_ICL_UA 500000 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ Loading Loading @@ -180,6 +185,8 @@ struct smb1390 { struct votable *fcc_votable; struct votable *fv_votable; struct votable *cp_awake_votable; struct votable *slave_disable_votable; struct votable *usb_icl_votable; /* power supplies */ struct power_supply *cps_psy; Loading Loading @@ -208,6 +215,7 @@ struct smb1390 { enum isns_mode current_capability; bool batt_soc_validated; int cp_slave_thr_taper_ua; int cc_mode_taper_main_icl_ua; }; struct smb_cfg { Loading Loading @@ -327,6 +335,14 @@ static bool is_psy_voter_available(struct smb1390 *chip) } } if (!chip->usb_icl_votable) { chip->usb_icl_votable = find_votable("USB_ICL"); if (!chip->usb_icl_votable) { smb1390_dbg(chip, PR_EXT_DEPENDENCY, "Couldn't find ICL votable\n"); return false; } } if (!chip->disable_votable) { smb1390_dbg(chip, PR_MISC, "Couldn't find CP DISABLE votable\n"); return false; Loading Loading @@ -839,15 +855,16 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data, { struct smb1390 *chip = data; int rc = 0; u8 mask, val; if (!is_psy_voter_available(chip) || chip->suspended) return -EAGAIN; mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT; val = is_cps_available(chip) ? mask : CMD_EN_SWITCHER_BIT; rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, mask, disable ? 0 : val); if (is_cps_available(chip)) vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, disable ? true : false, 0); rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SWITCHER_BIT, disable ? 0 : CMD_EN_SWITCHER_BIT); if (rc < 0) { pr_err("Couldn't write CORE_CONTROL1_REG, rc=%d\n", rc); return rc; Loading @@ -861,6 +878,21 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data, return rc; } static int smb1390_slave_disable_vote_cb(struct votable *votable, void *data, int disable, const char *client) { struct smb1390 *chip = data; int rc; rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SL_BIT, disable ? 0 : CMD_EN_SL_BIT); if (rc < 0) pr_err("Couldn't %s slave rc=%d\n", disable ? "disable" : "enable", rc); return rc; } static int smb1390_ilim_vote_cb(struct votable *votable, void *data, int ilim_uA, const char *client) { Loading Loading @@ -1081,6 +1113,10 @@ static void smb1390_status_change_work(struct work_struct *work) 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); vote(chip->slave_disable_votable, TAPER_END_VOTER, false, 0); vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, true, 0); vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, false, 0); } out: Loading @@ -1091,18 +1127,14 @@ static void smb1390_status_change_work(struct work_struct *work) 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; vote(chip->slave_disable_votable, TAPER_END_VOTER, true, 0); /* * Set ILIM of master SMB1390 to Max value = 3.2A once slave is * disabled to prevent ILIM irq storm. Loading @@ -1111,6 +1143,10 @@ static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA) fcc_uA); vote_override(chip->ilim_votable, CC_MODE_VOTER, true, MAX_ILIM_DUAL_CP_UA); if (chip->usb_icl_votable) vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, true, chip->cc_mode_taper_main_icl_ua); } return rc; Loading Loading @@ -1163,6 +1199,15 @@ static void smb1390_taper_work(struct work_struct *work) if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, true, 0); /* * When master CP is disabled, reset all votes * on ICL to enable Main charger to pump * charging current. */ if (chip->usb_icl_votable) vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER, false, 0); goto out; } } else { Loading Loading @@ -1415,6 +1460,12 @@ static int smb1390_parse_dt(struct smb1390 *chip) 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); chip->cc_mode_taper_main_icl_ua = CC_MODE_TAPER_MAIN_ICL_UA; of_property_read_u32(chip->dev->of_node, "qcom,cc-mode-taper-main-icl-ua", &chip->cc_mode_taper_main_icl_ua); return 0; } Loading @@ -1438,6 +1489,11 @@ static int smb1390_create_votables(struct smb1390 *chip) if (IS_ERR(chip->ilim_votable)) return PTR_ERR(chip->ilim_votable); chip->slave_disable_votable = create_votable("CP_SLAVE_DISABLE", VOTE_SET_ANY, smb1390_slave_disable_vote_cb, chip); if (IS_ERR(chip->slave_disable_votable)) return PTR_ERR(chip->slave_disable_votable); /* * charge pump is initially disabled; this indirectly votes to allow * traditional parallel charging if present Loading Loading @@ -1507,6 +1563,12 @@ static int smb1390_init_hw(struct smb1390 *chip) return rc; } /* Configure IREV threshold to 200mA */ rc = smb1390_masked_write(chip, CORE_FTRIM_MISC_REG, TR_IREV_BIT, 0); if (rc < 0) { pr_err("Couldn't configure IREV threshold rc=%d\n", rc); return rc; } /* * If the slave charger has registered, configure Master SMB1390 for * triple-chg config, else configure for dual. Later, if the slave Loading Loading @@ -1829,6 +1891,15 @@ static int smb1390_slave_probe(struct smb1390 *chip) if (rc < 0) return rc; /* Configure Slave CP Temp buffer O/P to High Impedance */ rc = smb1390_masked_write(chip, CORE_FTRIM_CTRL_REG, TEMP_BUFFER_OUTPUT_BIT, TEMP_BUFFER_OUTPUT_BIT); if (rc < 0) { pr_err("Couldn't configure Slave temp Buffer rc=%d\n", rc); return rc; } rc = smb1390_init_cps_psy(chip); if (rc < 0) pr_err("Couldn't initialize cps psy rc=%d\n", rc); Loading
drivers/power/supply/qcom/smb5-lib.c +52 −1 Original line number Diff line number Diff line Loading @@ -3675,6 +3675,54 @@ int smblib_get_pe_start(struct smb_charger *chg, return 0; } int smblib_get_prop_smb_health(struct smb_charger *chg) { int rc; u8 stat; int input_present; rc = smblib_is_input_present(chg, &input_present); if (rc < 0) return rc; if (input_present == INPUT_NOT_PRESENT) return POWER_SUPPLY_HEALTH_UNKNOWN; if (chg->wa_flags & SW_THERM_REGULATION_WA) { if (chg->smb_temp == -ENODATA) return POWER_SUPPLY_HEALTH_UNKNOWN; if (chg->smb_temp > SMB_TEMP_RST_THRESH) return POWER_SUPPLY_HEALTH_OVERHEAT; if (chg->smb_temp > SMB_TEMP_REG_H_THRESH) return POWER_SUPPLY_HEALTH_HOT; if (chg->smb_temp > SMB_TEMP_REG_L_THRESH) return POWER_SUPPLY_HEALTH_WARM; return POWER_SUPPLY_HEALTH_COOL; } rc = smblib_read(chg, SMB_TEMP_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read SMB_TEMP_STATUS_REG, rc=%d\n", rc); return POWER_SUPPLY_HEALTH_UNKNOWN; } if (stat & SMB_TEMP_RST_BIT) return POWER_SUPPLY_HEALTH_OVERHEAT; if (stat & SMB_TEMP_UB_BIT) return POWER_SUPPLY_HEALTH_HOT; if (stat & SMB_TEMP_LB_BIT) return POWER_SUPPLY_HEALTH_WARM; return POWER_SUPPLY_HEALTH_COOL; } int smblib_get_prop_die_health(struct smb_charger *chg) { int rc; Loading Loading @@ -3763,11 +3811,14 @@ static int smblib_get_typec_connector_temp_status(struct smb_charger *chg) return POWER_SUPPLY_HEALTH_COOL; } static int smblib_get_skin_temp_status(struct smb_charger *chg) int smblib_get_skin_temp_status(struct smb_charger *chg) { int rc; u8 stat; if (!chg->en_skin_therm_mitigation) return POWER_SUPPLY_HEALTH_UNKNOWN; rc = smblib_read(chg, SKIN_TEMP_STATUS_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read SKIN_TEMP_STATUS_REG, rc=%d\n", Loading
drivers/power/supply/qcom/smb5-lib.h +4 −0 Original line number Diff line number Diff line Loading @@ -531,7 +531,9 @@ struct smb_charger { bool hw_die_temp_mitigation; bool hw_connector_mitigation; bool hw_skin_temp_mitigation; bool en_skin_therm_mitigation; int connector_pull_up; int smb_pull_up; int aicl_5v_threshold_mv; int default_aicl_5v_threshold_mv; int aicl_cont_threshold_mv; Loading Loading @@ -718,7 +720,9 @@ int smblib_get_pe_start(struct smb_charger *chg, int smblib_get_prop_charger_temp(struct smb_charger *chg, union power_supply_propval *val); int smblib_get_prop_die_health(struct smb_charger *chg); int smblib_get_prop_smb_health(struct smb_charger *chg); int smblib_get_prop_connector_health(struct smb_charger *chg); int smblib_get_skin_temp_status(struct smb_charger *chg); int smblib_get_prop_vph_voltage_now(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pd_current_max(struct smb_charger *chg, Loading
drivers/power/supply/qcom/smb5-reg.h +6 −0 Original line number Diff line number Diff line Loading @@ -493,6 +493,12 @@ enum { #define CONNECTOR_TEMP_UB_BIT BIT(1) #define CONNECTOR_TEMP_LB_BIT BIT(0) #define SMB_TEMP_STATUS_REG (MISC_BASE + 0x0A) #define SMB_TEMP_SHDN_BIT BIT(3) #define SMB_TEMP_RST_BIT BIT(2) #define SMB_TEMP_UB_BIT BIT(1) #define SMB_TEMP_LB_BIT BIT(0) #define BARK_BITE_WDOG_PET_REG (MISC_BASE + 0x43) #define BARK_BITE_WDOG_PET_BIT BIT(0) Loading