Loading drivers/power/supply/qcom/qpnp-smb5.c +17 −14 Original line number Diff line number Diff line Loading @@ -547,7 +547,6 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_TYPEC_MODE, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, POWER_SUPPLY_PROP_TYPEC_SRC_RP, POWER_SUPPLY_PROP_LOW_POWER, POWER_SUPPLY_PROP_PD_ACTIVE, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, Loading @@ -557,10 +556,8 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_CTM_CURRENT_MAX, POWER_SUPPLY_PROP_HW_CURRENT_MAX, POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_PR_SWAP, POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_CONNECTOR_TYPE, POWER_SUPPLY_PROP_CONNECTOR_HEALTH, POWER_SUPPLY_PROP_VOLTAGE_MAX, Loading Loading @@ -1798,15 +1795,6 @@ static int smb5_init_hw(struct smb5 *chip) } } /* Disable SMB Temperature ADC INT */ rc = smblib_masked_write(chg, MISC_THERMREG_SRC_CFG_REG, THERMREG_SMB_ADC_SRC_EN_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SMB thermal regulation rc=%d\n", rc); return rc; } /* * If SW thermal regulation WA is active then all the HW temperature * comparators need to be disabled to prevent HW thermal regulation, Loading @@ -1820,6 +1808,15 @@ static int smb5_init_hw(struct smb5 *chip) rc); return rc; } } else { /* Allows software thermal regulation only */ rc = smblib_write(chg, MISC_THERMREG_SRC_CFG_REG, THERMREG_SW_ICL_ADJUST_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SMB thermal regulation rc=%d\n", rc); return rc; } } /* Loading Loading @@ -1891,8 +1888,8 @@ static int smb5_init_hw(struct smb5 *chip) smblib_rerun_apsd_if_required(chg); } /* clear the ICL override if it is set */ rc = smblib_icl_override(chg, false); /* Use ICL results from HW */ rc = smblib_icl_override(chg, HW_AUTO_MODE); if (rc < 0) { pr_err("Couldn't disable ICL override rc=%d\n", rc); return rc; Loading Loading @@ -2436,8 +2433,14 @@ static struct smb_irq_info smb5_irqs[] = { [IMP_TRIGGER_IRQ] = { .name = "imp-trigger", }, /* * triggered when DIE or SKIN or CONNECTOR temperature across * either of the _REG_L, _REG_H, _RST, or _SHDN thresholds */ [TEMP_CHANGE_IRQ] = { .name = "temp-change", .handler = temp_change_irq_handler, .wake = true, }, [TEMP_CHANGE_SMB_IRQ] = { .name = "temp-change-smb", Loading drivers/power/supply/qcom/smb5-lib.c +89 −83 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ || typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH) \ && !chg->typec_legacy) static void update_sw_icl_max(struct smb_charger *chg, int pst); int smblib_read(struct smb_charger *chg, u16 addr, u8 *val) { unsigned int value; Loading Loading @@ -156,15 +158,50 @@ int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) return 0; } int smblib_icl_override(struct smb_charger *chg, bool override) int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode) { int rc; u8 usb51_mode, icl_override, apsd_override; rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG, ICL_OVERRIDE_AFTER_APSD_BIT, override ? ICL_OVERRIDE_AFTER_APSD_BIT : 0); if (rc < 0) switch (mode) { case SW_OVERRIDE_USB51_MODE: usb51_mode = 0; icl_override = ICL_OVERRIDE_BIT; apsd_override = 0; break; case SW_OVERRIDE_HC_MODE: usb51_mode = USBIN_MODE_CHG_BIT; icl_override = 0; apsd_override = ICL_OVERRIDE_AFTER_APSD_BIT; break; case HW_AUTO_MODE: default: usb51_mode = USBIN_MODE_CHG_BIT; icl_override = 0; apsd_override = 0; break; } rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, USBIN_MODE_CHG_BIT, usb51_mode); if (rc < 0) { smblib_err(chg, "Couldn't set USBIN_ICL_OPTIONS rc=%d\n", rc); return rc; } rc = smblib_masked_write(chg, CMD_ICL_OVERRIDE_REG, ICL_OVERRIDE_BIT, icl_override); if (rc < 0) { smblib_err(chg, "Couldn't override ICL rc=%d\n", rc); return rc; } rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG, ICL_OVERRIDE_AFTER_APSD_BIT, apsd_override); if (rc < 0) { smblib_err(chg, "Couldn't override ICL_AFTER_APSD rc=%d\n", rc); return rc; } return rc; } Loading Loading @@ -1166,42 +1203,25 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) } rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, CFG_USB3P0_SEL_BIT | USB51_MODE_BIT | USBIN_MODE_CHG_BIT, icl_options); CFG_USB3P0_SEL_BIT | USB51_MODE_BIT, icl_options); if (rc < 0) { smblib_err(chg, "Couldn't set ICL options rc=%d\n", rc); return rc; } return rc; } static int get_sdp_current(struct smb_charger *chg, int *icl_ua) { int rc; u8 icl_options; bool usb3 = false; rc = smblib_read(chg, USBIN_ICL_OPTIONS_REG, &icl_options); rc = smblib_icl_override(chg, SW_OVERRIDE_USB51_MODE); if (rc < 0) { smblib_err(chg, "Couldn't get ICL options rc=%d\n", rc); smblib_err(chg, "Couldn't set ICL override rc=%d\n", rc); return rc; } usb3 = (icl_options & CFG_USB3P0_SEL_BIT); if (icl_options & USB51_MODE_BIT) *icl_ua = usb3 ? USBIN_900MA : USBIN_500MA; else *icl_ua = usb3 ? USBIN_150MA : USBIN_100MA; return rc; } int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { int rc = 0; bool hc_mode = false, override = false; enum icl_override_mode icl_override = HW_AUTO_MODE; /* suspend if 25mA or less is requested */ bool suspend = (icl_ua <= USBIN_25MA); Loading Loading @@ -1249,25 +1269,11 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc); goto out; } hc_mode = true; /* * Micro USB mode follows ICL register independent of override * bit, configure override only for typeC mode. */ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) override = true; icl_override = SW_OVERRIDE_HC_MODE; } set_mode: rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, USBIN_MODE_CHG_BIT, hc_mode ? USBIN_MODE_CHG_BIT : 0); if (rc < 0) { smblib_err(chg, "Couldn't set USBIN_ICL_OPTIONS rc=%d\n", rc); goto out; } rc = smblib_icl_override(chg, override); rc = smblib_icl_override(chg, icl_override); if (rc < 0) { smblib_err(chg, "Couldn't set ICL override rc=%d\n", rc); goto out; Loading @@ -1289,38 +1295,13 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) { int rc = 0; u8 load_cfg; bool override; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) && (chg->usb_psy->desc->type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't get SDP ICL rc=%d\n", rc); return rc; } } else { rc = smblib_read(chg, USBIN_LOAD_CFG_REG, &load_cfg); if (rc < 0) { smblib_err(chg, "Couldn't get load cfg rc=%d\n", rc); return rc; } override = load_cfg & ICL_OVERRIDE_AFTER_APSD_BIT; if (!override) return INT_MAX; int rc; /* override is set */ rc = smblib_get_charge_param(chg, &chg->param.icl_max_stat, icl_ua); if (rc < 0) { rc = smblib_get_charge_param(chg, &chg->param.icl_max_stat, icl_ua); if (rc < 0) smblib_err(chg, "Couldn't get HC ICL rc=%d\n", rc); return rc; } } return 0; return rc; } int smblib_toggle_smb_en(struct smb_charger *chg, int toggle) Loading Loading @@ -3613,6 +3594,8 @@ int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, int smblib_set_prop_pd_active(struct smb_charger *chg, const union power_supply_propval *val) { const struct apsd_result *apsd = smblib_get_apsd_result(chg); int rc = 0; int sec_charger; Loading @@ -3620,6 +3603,8 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_apsd_enable(chg, !chg->pd_active); update_sw_icl_max(chg, apsd->pst); if (chg->pd_active) { vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0); Loading @@ -3646,7 +3631,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, rc); } } else { vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, SDP_100_MA); vote(chg->usb_icl_votable, PD_VOTER, false, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0); Loading Loading @@ -4359,10 +4343,8 @@ static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg, static void update_sw_icl_max(struct smb_charger *chg, int pst) { union power_supply_propval pval; int typec_mode; int rp_ua; int rc; /* while PD is active it should have complete ICL control */ if (chg->pd_active) Loading Loading @@ -4414,15 +4396,8 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) break; case POWER_SUPPLY_TYPE_UNKNOWN: default: rc = smblib_get_prop_usb_present(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); return; } vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, pval.intval ? SDP_CURRENT_UA : SDP_100_MA); SDP_100_MA); break; } } Loading Loading @@ -5106,6 +5081,37 @@ irqreturn_t wdog_bark_irq_handler(int irq, void *data) return IRQ_HANDLED; } static void smblib_die_rst_icl_regulate(struct smb_charger *chg) { int rc; u8 temp; rc = smblib_read(chg, DIE_TEMP_STATUS_REG, &temp); if (rc < 0) { smblib_err(chg, "Couldn't read DIE_TEMP_STATUS_REG rc=%d\n", rc); return; } /* Regulate ICL on die temp crossing DIE_RST threshold */ vote(chg->usb_icl_votable, DIE_TEMP_VOTER, temp & DIE_TEMP_RST_BIT, 500000); } /* * triggered when DIE or SKIN or CONNECTOR temperature across * either of the _REG_L, _REG_H, _RST, or _SHDN thresholds */ irqreturn_t temp_change_irq_handler(int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; smblib_die_rst_icl_regulate(chg); return IRQ_HANDLED; } /************** * Additional USB PSY getters/setters * that call interrupt functions Loading drivers/power/supply/qcom/smb5-lib.h +12 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ enum print_reason { #define CHG_STATE_VOTER "CHG_STATE_VOTER" #define TAPER_END_VOTER "TAPER_END_VOTER" #define THERMAL_DAEMON_VOTER "THERMAL_DAEMON_VOTER" #define DIE_TEMP_VOTER "DIE_TEMP_VOTER" #define BOOST_BACK_VOTER "BOOST_BACK_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" #define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" Loading Loading @@ -228,6 +229,15 @@ enum thermal_status_levels { TEMP_BELOW_RANGE, }; enum icl_override_mode { /* APSD/Type-C/QC auto */ HW_AUTO_MODE, /* 100/150/500/900mA */ SW_OVERRIDE_USB51_MODE, /* ICL other than USB51 */ SW_OVERRIDE_HC_MODE, }; /* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */ static const u32 smblib_extcon_exclusive[] = {0x3, 0}; Loading Loading @@ -518,6 +528,7 @@ irqreturn_t switcher_power_ok_irq_handler(int irq, void *data); irqreturn_t wdog_snarl_irq_handler(int irq, void *data); irqreturn_t wdog_bark_irq_handler(int irq, void *data); irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data); irqreturn_t temp_change_irq_handler(int irq, void *data); int smblib_get_prop_input_suspend(struct smb_charger *chg, union power_supply_propval *val); Loading Loading @@ -645,7 +656,7 @@ int smblib_get_iio_channel(struct smb_charger *chg, const char *propname, int smblib_read_iio_channel(struct smb_charger *chg, struct iio_channel *chan, int div, int *data); int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable); int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode); enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, ktime_t time); int smblib_toggle_smb_en(struct smb_charger *chg, int toggle); Loading drivers/power/supply/qcom/smb5-reg.h +4 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,9 @@ enum { #define CMD_APSD_REG (USBIN_BASE + 0x41) #define APSD_RERUN_BIT BIT(0) #define CMD_ICL_OVERRIDE_REG (USBIN_BASE + 0x42) #define ICL_OVERRIDE_BIT BIT(0) #define CMD_HVDCP_2_REG (USBIN_BASE + 0x43) #define FORCE_12V_BIT BIT(5) #define FORCE_9V_BIT BIT(4) Loading Loading @@ -459,6 +462,7 @@ enum { #define AICL_RERUN_TIME_12S_VAL 0x01 #define MISC_THERMREG_SRC_CFG_REG (MISC_BASE + 0x70) #define THERMREG_SW_ICL_ADJUST_BIT BIT(7) #define THERMREG_SMB_ADC_SRC_EN_BIT BIT(5) #define THERMREG_DIE_CMP_SRC_EN_BIT BIT(0) Loading Loading
drivers/power/supply/qcom/qpnp-smb5.c +17 −14 Original line number Diff line number Diff line Loading @@ -547,7 +547,6 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_TYPEC_MODE, POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, POWER_SUPPLY_PROP_TYPEC_SRC_RP, POWER_SUPPLY_PROP_LOW_POWER, POWER_SUPPLY_PROP_PD_ACTIVE, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, Loading @@ -557,10 +556,8 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_CTM_CURRENT_MAX, POWER_SUPPLY_PROP_HW_CURRENT_MAX, POWER_SUPPLY_PROP_REAL_TYPE, POWER_SUPPLY_PROP_PR_SWAP, POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, POWER_SUPPLY_PROP_SDP_CURRENT_MAX, POWER_SUPPLY_PROP_CONNECTOR_TYPE, POWER_SUPPLY_PROP_CONNECTOR_HEALTH, POWER_SUPPLY_PROP_VOLTAGE_MAX, Loading Loading @@ -1798,15 +1795,6 @@ static int smb5_init_hw(struct smb5 *chip) } } /* Disable SMB Temperature ADC INT */ rc = smblib_masked_write(chg, MISC_THERMREG_SRC_CFG_REG, THERMREG_SMB_ADC_SRC_EN_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SMB thermal regulation rc=%d\n", rc); return rc; } /* * If SW thermal regulation WA is active then all the HW temperature * comparators need to be disabled to prevent HW thermal regulation, Loading @@ -1820,6 +1808,15 @@ static int smb5_init_hw(struct smb5 *chip) rc); return rc; } } else { /* Allows software thermal regulation only */ rc = smblib_write(chg, MISC_THERMREG_SRC_CFG_REG, THERMREG_SW_ICL_ADJUST_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SMB thermal regulation rc=%d\n", rc); return rc; } } /* Loading Loading @@ -1891,8 +1888,8 @@ static int smb5_init_hw(struct smb5 *chip) smblib_rerun_apsd_if_required(chg); } /* clear the ICL override if it is set */ rc = smblib_icl_override(chg, false); /* Use ICL results from HW */ rc = smblib_icl_override(chg, HW_AUTO_MODE); if (rc < 0) { pr_err("Couldn't disable ICL override rc=%d\n", rc); return rc; Loading Loading @@ -2436,8 +2433,14 @@ static struct smb_irq_info smb5_irqs[] = { [IMP_TRIGGER_IRQ] = { .name = "imp-trigger", }, /* * triggered when DIE or SKIN or CONNECTOR temperature across * either of the _REG_L, _REG_H, _RST, or _SHDN thresholds */ [TEMP_CHANGE_IRQ] = { .name = "temp-change", .handler = temp_change_irq_handler, .wake = true, }, [TEMP_CHANGE_SMB_IRQ] = { .name = "temp-change-smb", Loading
drivers/power/supply/qcom/smb5-lib.c +89 −83 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ || typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH) \ && !chg->typec_legacy) static void update_sw_icl_max(struct smb_charger *chg, int pst); int smblib_read(struct smb_charger *chg, u16 addr, u8 *val) { unsigned int value; Loading Loading @@ -156,15 +158,50 @@ int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) return 0; } int smblib_icl_override(struct smb_charger *chg, bool override) int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode) { int rc; u8 usb51_mode, icl_override, apsd_override; rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG, ICL_OVERRIDE_AFTER_APSD_BIT, override ? ICL_OVERRIDE_AFTER_APSD_BIT : 0); if (rc < 0) switch (mode) { case SW_OVERRIDE_USB51_MODE: usb51_mode = 0; icl_override = ICL_OVERRIDE_BIT; apsd_override = 0; break; case SW_OVERRIDE_HC_MODE: usb51_mode = USBIN_MODE_CHG_BIT; icl_override = 0; apsd_override = ICL_OVERRIDE_AFTER_APSD_BIT; break; case HW_AUTO_MODE: default: usb51_mode = USBIN_MODE_CHG_BIT; icl_override = 0; apsd_override = 0; break; } rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, USBIN_MODE_CHG_BIT, usb51_mode); if (rc < 0) { smblib_err(chg, "Couldn't set USBIN_ICL_OPTIONS rc=%d\n", rc); return rc; } rc = smblib_masked_write(chg, CMD_ICL_OVERRIDE_REG, ICL_OVERRIDE_BIT, icl_override); if (rc < 0) { smblib_err(chg, "Couldn't override ICL rc=%d\n", rc); return rc; } rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG, ICL_OVERRIDE_AFTER_APSD_BIT, apsd_override); if (rc < 0) { smblib_err(chg, "Couldn't override ICL_AFTER_APSD rc=%d\n", rc); return rc; } return rc; } Loading Loading @@ -1166,42 +1203,25 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) } rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, CFG_USB3P0_SEL_BIT | USB51_MODE_BIT | USBIN_MODE_CHG_BIT, icl_options); CFG_USB3P0_SEL_BIT | USB51_MODE_BIT, icl_options); if (rc < 0) { smblib_err(chg, "Couldn't set ICL options rc=%d\n", rc); return rc; } return rc; } static int get_sdp_current(struct smb_charger *chg, int *icl_ua) { int rc; u8 icl_options; bool usb3 = false; rc = smblib_read(chg, USBIN_ICL_OPTIONS_REG, &icl_options); rc = smblib_icl_override(chg, SW_OVERRIDE_USB51_MODE); if (rc < 0) { smblib_err(chg, "Couldn't get ICL options rc=%d\n", rc); smblib_err(chg, "Couldn't set ICL override rc=%d\n", rc); return rc; } usb3 = (icl_options & CFG_USB3P0_SEL_BIT); if (icl_options & USB51_MODE_BIT) *icl_ua = usb3 ? USBIN_900MA : USBIN_500MA; else *icl_ua = usb3 ? USBIN_150MA : USBIN_100MA; return rc; } int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { int rc = 0; bool hc_mode = false, override = false; enum icl_override_mode icl_override = HW_AUTO_MODE; /* suspend if 25mA or less is requested */ bool suspend = (icl_ua <= USBIN_25MA); Loading Loading @@ -1249,25 +1269,11 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc); goto out; } hc_mode = true; /* * Micro USB mode follows ICL register independent of override * bit, configure override only for typeC mode. */ if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) override = true; icl_override = SW_OVERRIDE_HC_MODE; } set_mode: rc = smblib_masked_write(chg, USBIN_ICL_OPTIONS_REG, USBIN_MODE_CHG_BIT, hc_mode ? USBIN_MODE_CHG_BIT : 0); if (rc < 0) { smblib_err(chg, "Couldn't set USBIN_ICL_OPTIONS rc=%d\n", rc); goto out; } rc = smblib_icl_override(chg, override); rc = smblib_icl_override(chg, icl_override); if (rc < 0) { smblib_err(chg, "Couldn't set ICL override rc=%d\n", rc); goto out; Loading @@ -1289,38 +1295,13 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) { int rc = 0; u8 load_cfg; bool override; if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) && (chg->usb_psy->desc->type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't get SDP ICL rc=%d\n", rc); return rc; } } else { rc = smblib_read(chg, USBIN_LOAD_CFG_REG, &load_cfg); if (rc < 0) { smblib_err(chg, "Couldn't get load cfg rc=%d\n", rc); return rc; } override = load_cfg & ICL_OVERRIDE_AFTER_APSD_BIT; if (!override) return INT_MAX; int rc; /* override is set */ rc = smblib_get_charge_param(chg, &chg->param.icl_max_stat, icl_ua); if (rc < 0) { rc = smblib_get_charge_param(chg, &chg->param.icl_max_stat, icl_ua); if (rc < 0) smblib_err(chg, "Couldn't get HC ICL rc=%d\n", rc); return rc; } } return 0; return rc; } int smblib_toggle_smb_en(struct smb_charger *chg, int toggle) Loading Loading @@ -3613,6 +3594,8 @@ int smblib_set_prop_pd_voltage_max(struct smb_charger *chg, int smblib_set_prop_pd_active(struct smb_charger *chg, const union power_supply_propval *val) { const struct apsd_result *apsd = smblib_get_apsd_result(chg); int rc = 0; int sec_charger; Loading @@ -3620,6 +3603,8 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, smblib_apsd_enable(chg, !chg->pd_active); update_sw_icl_max(chg, apsd->pst); if (chg->pd_active) { vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0); Loading @@ -3646,7 +3631,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, rc); } } else { vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, SDP_100_MA); vote(chg->usb_icl_votable, PD_VOTER, false, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, false, 0); Loading Loading @@ -4359,10 +4343,8 @@ static void smblib_handle_hvdcp_detect_done(struct smb_charger *chg, static void update_sw_icl_max(struct smb_charger *chg, int pst) { union power_supply_propval pval; int typec_mode; int rp_ua; int rc; /* while PD is active it should have complete ICL control */ if (chg->pd_active) Loading Loading @@ -4414,15 +4396,8 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst) break; case POWER_SUPPLY_TYPE_UNKNOWN: default: rc = smblib_get_prop_usb_present(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); return; } vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, pval.intval ? SDP_CURRENT_UA : SDP_100_MA); SDP_100_MA); break; } } Loading Loading @@ -5106,6 +5081,37 @@ irqreturn_t wdog_bark_irq_handler(int irq, void *data) return IRQ_HANDLED; } static void smblib_die_rst_icl_regulate(struct smb_charger *chg) { int rc; u8 temp; rc = smblib_read(chg, DIE_TEMP_STATUS_REG, &temp); if (rc < 0) { smblib_err(chg, "Couldn't read DIE_TEMP_STATUS_REG rc=%d\n", rc); return; } /* Regulate ICL on die temp crossing DIE_RST threshold */ vote(chg->usb_icl_votable, DIE_TEMP_VOTER, temp & DIE_TEMP_RST_BIT, 500000); } /* * triggered when DIE or SKIN or CONNECTOR temperature across * either of the _REG_L, _REG_H, _RST, or _SHDN thresholds */ irqreturn_t temp_change_irq_handler(int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; smblib_die_rst_icl_regulate(chg); return IRQ_HANDLED; } /************** * Additional USB PSY getters/setters * that call interrupt functions Loading
drivers/power/supply/qcom/smb5-lib.h +12 −1 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ enum print_reason { #define CHG_STATE_VOTER "CHG_STATE_VOTER" #define TAPER_END_VOTER "TAPER_END_VOTER" #define THERMAL_DAEMON_VOTER "THERMAL_DAEMON_VOTER" #define DIE_TEMP_VOTER "DIE_TEMP_VOTER" #define BOOST_BACK_VOTER "BOOST_BACK_VOTER" #define MICRO_USB_VOTER "MICRO_USB_VOTER" #define DEBUG_BOARD_VOTER "DEBUG_BOARD_VOTER" Loading Loading @@ -228,6 +229,15 @@ enum thermal_status_levels { TEMP_BELOW_RANGE, }; enum icl_override_mode { /* APSD/Type-C/QC auto */ HW_AUTO_MODE, /* 100/150/500/900mA */ SW_OVERRIDE_USB51_MODE, /* ICL other than USB51 */ SW_OVERRIDE_HC_MODE, }; /* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */ static const u32 smblib_extcon_exclusive[] = {0x3, 0}; Loading Loading @@ -518,6 +528,7 @@ irqreturn_t switcher_power_ok_irq_handler(int irq, void *data); irqreturn_t wdog_snarl_irq_handler(int irq, void *data); irqreturn_t wdog_bark_irq_handler(int irq, void *data); irqreturn_t typec_or_rid_detection_change_irq_handler(int irq, void *data); irqreturn_t temp_change_irq_handler(int irq, void *data); int smblib_get_prop_input_suspend(struct smb_charger *chg, union power_supply_propval *val); Loading Loading @@ -645,7 +656,7 @@ int smblib_get_iio_channel(struct smb_charger *chg, const char *propname, int smblib_read_iio_channel(struct smb_charger *chg, struct iio_channel *chan, int div, int *data); int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable); int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_icl_override(struct smb_charger *chg, enum icl_override_mode mode); enum alarmtimer_restart smblib_lpd_recheck_timer(struct alarm *alarm, ktime_t time); int smblib_toggle_smb_en(struct smb_charger *chg, int toggle); Loading
drivers/power/supply/qcom/smb5-reg.h +4 −0 Original line number Diff line number Diff line Loading @@ -216,6 +216,9 @@ enum { #define CMD_APSD_REG (USBIN_BASE + 0x41) #define APSD_RERUN_BIT BIT(0) #define CMD_ICL_OVERRIDE_REG (USBIN_BASE + 0x42) #define ICL_OVERRIDE_BIT BIT(0) #define CMD_HVDCP_2_REG (USBIN_BASE + 0x43) #define FORCE_12V_BIT BIT(5) #define FORCE_9V_BIT BIT(4) Loading Loading @@ -459,6 +462,7 @@ enum { #define AICL_RERUN_TIME_12S_VAL 0x01 #define MISC_THERMREG_SRC_CFG_REG (MISC_BASE + 0x70) #define THERMREG_SW_ICL_ADJUST_BIT BIT(7) #define THERMREG_SMB_ADC_SRC_EN_BIT BIT(5) #define THERMREG_DIE_CMP_SRC_EN_BIT BIT(0) Loading