Loading drivers/power/supply/power_supply_sysfs.c +5 −0 Original line number Diff line number Diff line Loading @@ -451,6 +451,11 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(cc_soc), POWER_SUPPLY_ATTR(batt_age_level), POWER_SUPPLY_ATTR(scale_mode_en), POWER_SUPPLY_ATTR(voltage_vph), POWER_SUPPLY_ATTR(chip_version), POWER_SUPPLY_ATTR(therm_icl_limit), POWER_SUPPLY_ATTR(dc_reset), POWER_SUPPLY_ATTR(voltage_max_limit), /* Charge pump properties */ POWER_SUPPLY_ATTR(cp_status1), POWER_SUPPLY_ATTR(cp_status2), Loading drivers/power/supply/qcom/battery.c +11 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #define DRV_MAJOR_VERSION 1 #define DRV_MINOR_VERSION 0 #define BATT_PROFILE_VOTER "BATT_PROFILE_VOTER" #define CHG_STATE_VOTER "CHG_STATE_VOTER" #define TAPER_STEPPER_VOTER "TAPER_STEPPER_VOTER" #define TAPER_END_VOTER "TAPER_END_VOTER" Loading Loading @@ -571,11 +572,12 @@ static void pl_taper_work(struct work_struct *work) pl_taper_work); union power_supply_propval pval = {0, }; int rc; int eff_fcc_ua; int total_fcc_ua, master_fcc_ua, slave_fcc_ua = 0; int fcc_ua, total_fcc_ua, master_fcc_ua, slave_fcc_ua = 0; chip->taper_entry_fv = get_effective_result(chip->fv_votable); chip->taper_work_running = true; fcc_ua = get_client_vote(chip->fcc_votable, BATT_PROFILE_VOTER); vote(chip->fcc_votable, TAPER_STEPPER_VOTER, true, fcc_ua); while (true) { if (get_effective_result(chip->pl_disable_votable)) { /* Loading Loading @@ -624,21 +626,22 @@ static void pl_taper_work(struct work_struct *work) chip->charge_type = pval.intval; if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { eff_fcc_ua = get_effective_result(chip->fcc_votable); if (eff_fcc_ua < 0) { fcc_ua = get_client_vote(chip->fcc_votable, TAPER_STEPPER_VOTER); if (fcc_ua < 0) { pr_err("Couldn't get fcc, exiting taper work\n"); goto done; } eff_fcc_ua = eff_fcc_ua - TAPER_REDUCTION_UA; if (eff_fcc_ua < 0) { fcc_ua -= TAPER_REDUCTION_UA; if (fcc_ua < 0) { pr_err("Can't reduce FCC any more\n"); goto done; } pl_dbg(chip, PR_PARALLEL, "master is taper charging; reducing FCC to %dua\n", eff_fcc_ua); fcc_ua); vote(chip->fcc_votable, TAPER_STEPPER_VOTER, true, eff_fcc_ua); true, fcc_ua); } else { pl_dbg(chip, PR_PARALLEL, "master is fast charging; waiting for next taper\n"); } Loading drivers/power/supply/qcom/qpnp-smb5.c +52 −9 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ struct smb_dt_props { int auto_recharge_soc; int auto_recharge_vbat_mv; int wd_bark_time; int wd_snarl_time_cfg; int batt_profile_fcc_ua; int batt_profile_fv_uv; int term_current_src; Loading Loading @@ -448,6 +449,11 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node) if (rc < 0 || chip->dt.wd_bark_time < MIN_WD_BARK_TIME) chip->dt.wd_bark_time = DEFAULT_WD_BARK_TIME; rc = of_property_read_u32(node, "qcom,wd-snarl-time-config", &chip->dt.wd_snarl_time_cfg); if (rc < 0) chip->dt.wd_snarl_time_cfg = -EINVAL; chip->dt.no_battery = of_property_read_bool(node, "qcom,batteryless-platform"); Loading Loading @@ -724,6 +730,8 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_MOISTURE_DETECTED, POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, POWER_SUPPLY_PROP_QC_OPTI_DISABLE, POWER_SUPPLY_PROP_VOLTAGE_VPH, POWER_SUPPLY_PROP_THERM_ICL_LIMIT, }; static int smb5_usb_get_prop(struct power_supply *psy, Loading Loading @@ -845,6 +853,13 @@ static int smb5_usb_get_prop(struct power_supply *psy, if (chg->hw_connector_mitigation) val->intval |= POWER_SUPPLY_QC_CTM_DISABLE; break; case POWER_SUPPLY_PROP_VOLTAGE_VPH: rc = smblib_get_prop_vph_voltage_now(chg, val); break; case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: val->intval = get_client_vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading @@ -865,7 +880,7 @@ static int smb5_usb_set_prop(struct power_supply *psy, { struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; int icl, rc = 0; switch (psp) { case POWER_SUPPLY_PROP_PD_CURRENT_MAX: Loading Loading @@ -909,6 +924,14 @@ static int smb5_usb_set_prop(struct power_supply *psy, chg->connector_health = val->intval; power_supply_changed(chg->usb_psy); break; case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: icl = get_effective_result(chg->usb_icl_votable); if ((icl + val->intval) > 0) rc = vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER, true, icl + val->intval); else rc = -EINVAL; break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading @@ -924,6 +947,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: return 1; default: break; Loading Loading @@ -1890,9 +1914,18 @@ static int smb5_configure_typec(struct smb_charger *chg) rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG, USBIN_IN_COLLAPSE_GF_SEL_MASK | USBIN_AICL_STEP_TIMING_SEL_MASK, 0); if (rc < 0) if (rc < 0) { dev_err(chg->dev, "Couldn't set USBIN_LOAD_CFG_REG rc=%d\n", rc); return rc; } /* Set CC threshold to 1.6 V in source mode */ rc = smblib_masked_write(chg, TYPE_C_EXIT_STATE_CFG_REG, SEL_SRC_UPPER_REF_BIT, SEL_SRC_UPPER_REF_BIT); if (rc < 0) dev_err(chg->dev, "Couldn't configure CC threshold voltage rc=%d\n", rc); return rc; } Loading Loading @@ -2324,7 +2357,8 @@ static int smb5_init_hw(struct smb5 *chip) */ if (chg->wa_flags & SW_THERM_REGULATION_WA) { rc = smblib_write(chg, MISC_THERMREG_SRC_CFG_REG, THERMREG_DIE_CMP_SRC_EN_BIT); THERMREG_SW_ICL_ADJUST_BIT | THERMREG_DIE_CMP_SRC_EN_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't disable HW thermal regulation rc=%d\n", rc); Loading Loading @@ -2450,9 +2484,17 @@ static int smb5_init_hw(struct smb5 *chip) val = (ilog2(chip->dt.wd_bark_time / 16) << BARK_WDOG_TIMEOUT_SHIFT) & BARK_WDOG_TIMEOUT_MASK; val |= (BITE_WDOG_TIMEOUT_8S | BITE_WDOG_DISABLE_CHARGING_CFG_BIT); if (chip->dt.wd_snarl_time_cfg == -EINVAL) val |= SNARL_WDOG_TMOUT_8S; else val |= (chip->dt.wd_snarl_time_cfg << SNARL_WDOG_TIMEOUT_SHIFT) & SNARL_WDOG_TIMEOUT_MASK; rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG, BITE_WDOG_DISABLE_CHARGING_CFG_BIT | BARK_WDOG_TIMEOUT_MASK | BITE_WDOG_TIMEOUT_MASK, SNARL_WDOG_TIMEOUT_MASK | BARK_WDOG_TIMEOUT_MASK | BITE_WDOG_TIMEOUT_MASK, val); if (rc < 0) { pr_err("Couldn't configue WD config rc=%d\n", rc); Loading Loading @@ -2956,13 +2998,14 @@ static int smb5_request_interrupts(struct smb5 *chip) chg->usb_icl_change_irq_enabled = true; /* * WDOG_SNARL_IRQ is required for SW Thermal Regulation WA only. In * case the WA is not required, disable the WDOG_SNARL_IRQ to prevent * interrupt storm. * WDOG_SNARL_IRQ is required for SW Thermal Regulation WA. In case * the WA is not required and neither is the snarl timer configuration * defined, disable the WDOG_SNARL_IRQ to prevent interrupt storm. */ if (chg->irq_info[WDOG_SNARL_IRQ].irq && !(chg->wa_flags & SW_THERM_REGULATION_WA)) { if (chg->irq_info[WDOG_SNARL_IRQ].irq && (!(chg->wa_flags & SW_THERM_REGULATION_WA) && chip->dt.wd_snarl_time_cfg == -EINVAL)) { disable_irq_wake(chg->irq_info[WDOG_SNARL_IRQ].irq); disable_irq_nosync(chg->irq_info[WDOG_SNARL_IRQ].irq); } Loading drivers/power/supply/qcom/smb1355-charger.c +23 −3 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ struct smb1355 { int c_health; int c_charger_temp_max; int die_temp_deciDegC; int suspended_usb_icl; bool exit_die_temp; struct delayed_work die_temp_work; bool disabled; Loading Loading @@ -589,6 +590,7 @@ static int smb1355_get_prop_health(struct smb1355 *chip, int type) } #define MIN_PARALLEL_ICL_UA 250000 #define SUSPEND_CURRENT_UA 2000 static int smb1355_parallel_get_prop(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) Loading Loading @@ -665,11 +667,16 @@ static int smb1355_parallel_get_prop(struct power_supply *psy, val->intval = 0; break; case POWER_SUPPLY_PROP_CURRENT_MAX: if (IS_USBIN(chip->dt.pl_mode)) if (IS_USBIN(chip->dt.pl_mode)) { /* Report cached ICL until its configured correctly */ if (chip->suspended_usb_icl) val->intval = chip->suspended_usb_icl; else rc = smb1355_get_charge_param(chip, &chip->param.usb_icl, &val->intval); else } else { val->intval = 0; } break; case POWER_SUPPLY_PROP_MIN_ICL: val->intval = MIN_PARALLEL_ICL_UA; Loading Loading @@ -702,6 +709,18 @@ static int smb1355_set_parallel_charging(struct smb1355 *chip, bool disable) if (chip->disabled == disable) return 0; if (IS_USBIN(chip->dt.pl_mode)) { /* * Initialize ICL configuration to minimum value while * depending upon the set icl configuration method to properly * configure the ICL value. At the same time, cache the value * of ICL to be reported as 2mA. */ chip->suspended_usb_icl = SUSPEND_CURRENT_UA; smb1355_set_charge_param(chip, &chip->param.usb_icl, MIN_PARALLEL_ICL_UA); } rc = smb1355_masked_write(chip, WD_CFG_REG, WDOG_TIMER_EN_BIT, disable ? 0 : WDOG_TIMER_EN_BIT); if (rc < 0) { Loading Loading @@ -770,6 +789,7 @@ static int smb1355_set_current_max(struct smb1355 *chip, int curr) rc = smb1355_set_charge_param(chip, &chip->param.usb_icl, curr); chip->suspended_usb_icl = 0; } return rc; Loading drivers/power/supply/qcom/smb1390-charger-psy.c +87 −10 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/qpnp/qpnp-revid.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/of_irq.h> Loading Loading @@ -61,6 +62,10 @@ #define CORE_FTRIM_ILIM_REG 0x1030 #define CFG_ILIM_MASK GENMASK(4, 0) #define CORE_FTRIM_CTRL_REG 0x1031 #define TEMP_ALERT_LVL_MASK GENMASK(6, 5) #define TEMP_ALERT_LVL_SHIFT 5 #define CORE_FTRIM_LVL_REG 0x1033 #define CFG_WIN_HI_MASK GENMASK(3, 2) #define WIN_OV_LVL_1000MV 0x08 Loading @@ -85,6 +90,8 @@ #define SRC_VOTER "SRC_VOTER" #define SWITCHER_TOGGLE_VOTER "SWITCHER_TOGGLE_VOTER" #define THERMAL_SUSPEND_DECIDEGC 1400 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ if (chip->debug_mask & (reason)) \ Loading Loading @@ -130,6 +137,7 @@ struct smb1390 { struct notifier_block nb; struct wakeup_source *cp_ws; struct dentry *dfs_root; struct pmic_revid_data *pmic_rev_id; /* work structs */ struct work_struct status_change_work; Loading Loading @@ -161,6 +169,8 @@ struct smb1390 { int die_temp; bool suspended; u32 debug_mask; u32 min_ilim_ua; u32 max_temp_alarm_degc; }; struct smb_irq { Loading Loading @@ -493,8 +503,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data, return rc; } /* ILIM less than 1A is not accurate; disable charging */ if (ilim_uA < 1000000) { /* ILIM less than min_ilim_ua, disable charging */ if (ilim_uA < chip->min_ilim_ua) { smb1390_dbg(chip, PR_INFO, "ILIM %duA is too low to allow charging\n", ilim_uA); vote(chip->disable_votable, ILIM_VOTER, true, 0); Loading Loading @@ -660,7 +670,7 @@ static void smb1390_taper_work(struct work_struct *work) fcc_uA); vote(chip->fcc_votable, CP_VOTER, true, fcc_uA); if (fcc_uA < 2000000) { if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, true, 0); goto out; Loading @@ -687,6 +697,7 @@ static enum power_supply_property smb1390_charge_pump_props[] = { POWER_SUPPLY_PROP_CP_TOGGLE_SWITCHER, POWER_SUPPLY_PROP_CP_IRQ_STATUS, POWER_SUPPLY_PROP_CP_ILIM, POWER_SUPPLY_PROP_CHIP_VERSION, }; static int smb1390_get_prop(struct power_supply *psy, Loading Loading @@ -731,9 +742,24 @@ static int smb1390_get_prop(struct power_supply *psy, else rc = -ENODATA; } else { /* * Add a filter to the die temp value read: * If temp > THERMAL_SUSPEND_DECIDEGC then * - treat it as an error and report last valid * cached temperature. * - return -ENODATA if the cached value is * invalid. */ rc = smb1390_get_die_temp(chip, val); if (rc >= 0) if (rc >= 0) { if (val->intval <= THERMAL_SUSPEND_DECIDEGC) chip->die_temp = val->intval; else if (chip->die_temp == -ENODATA) rc = -ENODATA; else val->intval = chip->die_temp; } } break; case POWER_SUPPLY_PROP_CP_ISNS: Loading @@ -758,6 +784,9 @@ static int smb1390_get_prop(struct power_supply *psy, val->intval = ((status & CFG_ILIM_MASK) * 100000) + 500000; break; case POWER_SUPPLY_PROP_CHIP_VERSION: val->intval = chip->pmic_rev_id->rev4; break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply get prop %d not supported\n", prop); Loading Loading @@ -855,9 +884,19 @@ static int smb1390_parse_dt(struct smb1390 *chip) chip->iio.die_temp_chan = NULL; return rc; } } else { return rc; } return rc; chip->min_ilim_ua = 1000000; /* 1A */ of_property_read_u32(chip->dev->of_node, "qcom,min-ilim-ua", &chip->min_ilim_ua); chip->max_temp_alarm_degc = 110; of_property_read_u32(chip->dev->of_node, "qcom,max-temp-alarm-degc", &chip->max_temp_alarm_degc); return 0; } static void smb1390_release_channels(struct smb1390 *chip) Loading Loading @@ -903,7 +942,7 @@ static void smb1390_destroy_votables(struct smb1390 *chip) static int smb1390_init_hw(struct smb1390 *chip) { int rc; int rc = 0, val; /* * Improve ILIM accuracy: Loading @@ -920,8 +959,25 @@ static int smb1390_init_hw(struct smb1390 *chip) if (rc < 0) return rc; switch (chip->max_temp_alarm_degc) { case 125: val = 0x00; break; case 95: val = 0x02; break; case 85: val = 0x03; break; case 110: default: val = 0x01; break; } rc = smb1390_masked_write(chip, CORE_FTRIM_CTRL_REG, TEMP_ALERT_LVL_MASK, val << TEMP_ALERT_LVL_SHIFT); return 0; return rc; } static int smb1390_get_irq_index_byname(const char *irq_name) Loading Loading @@ -1023,8 +1079,28 @@ static void smb1390_create_debugfs(struct smb1390 *chip) static int smb1390_probe(struct platform_device *pdev) { struct smb1390 *chip; struct device_node *revid_dev_node; struct pmic_revid_data *pmic_rev_id; int rc; revid_dev_node = of_parse_phandle(pdev->dev.of_node, "qcom,pmic-revid", 0); if (!revid_dev_node) { pr_err("Missing qcom,pmic-revid property\n"); return -EINVAL; } pmic_rev_id = get_revid_data(revid_dev_node); of_node_put(revid_dev_node); if (IS_ERR_OR_NULL(pmic_rev_id)) { /* * the revid peripheral must be registered, any failure * here only indicates that the rev-id module has not * probed yet. */ return -EPROBE_DEFER; } chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; Loading @@ -1033,6 +1109,7 @@ static int smb1390_probe(struct platform_device *pdev) spin_lock_init(&chip->status_change_lock); mutex_init(&chip->die_chan_lock); chip->die_temp = -ENODATA; chip->pmic_rev_id = pmic_rev_id; platform_set_drvdata(pdev, chip); chip->regmap = dev_get_regmap(chip->dev->parent, NULL); Loading Loading @@ -1087,8 +1164,8 @@ static int smb1390_probe(struct platform_device *pdev) smb1390_create_debugfs(chip); pr_debug("smb1390 probed successfully\n"); pr_debug("smb1390 probed successfully chip_version=%d\n", chip->pmic_rev_id->rev4); return 0; out_notifier: Loading Loading
drivers/power/supply/power_supply_sysfs.c +5 −0 Original line number Diff line number Diff line Loading @@ -451,6 +451,11 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(cc_soc), POWER_SUPPLY_ATTR(batt_age_level), POWER_SUPPLY_ATTR(scale_mode_en), POWER_SUPPLY_ATTR(voltage_vph), POWER_SUPPLY_ATTR(chip_version), POWER_SUPPLY_ATTR(therm_icl_limit), POWER_SUPPLY_ATTR(dc_reset), POWER_SUPPLY_ATTR(voltage_max_limit), /* Charge pump properties */ POWER_SUPPLY_ATTR(cp_status1), POWER_SUPPLY_ATTR(cp_status2), Loading
drivers/power/supply/qcom/battery.c +11 −8 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #define DRV_MAJOR_VERSION 1 #define DRV_MINOR_VERSION 0 #define BATT_PROFILE_VOTER "BATT_PROFILE_VOTER" #define CHG_STATE_VOTER "CHG_STATE_VOTER" #define TAPER_STEPPER_VOTER "TAPER_STEPPER_VOTER" #define TAPER_END_VOTER "TAPER_END_VOTER" Loading Loading @@ -571,11 +572,12 @@ static void pl_taper_work(struct work_struct *work) pl_taper_work); union power_supply_propval pval = {0, }; int rc; int eff_fcc_ua; int total_fcc_ua, master_fcc_ua, slave_fcc_ua = 0; int fcc_ua, total_fcc_ua, master_fcc_ua, slave_fcc_ua = 0; chip->taper_entry_fv = get_effective_result(chip->fv_votable); chip->taper_work_running = true; fcc_ua = get_client_vote(chip->fcc_votable, BATT_PROFILE_VOTER); vote(chip->fcc_votable, TAPER_STEPPER_VOTER, true, fcc_ua); while (true) { if (get_effective_result(chip->pl_disable_votable)) { /* Loading Loading @@ -624,21 +626,22 @@ static void pl_taper_work(struct work_struct *work) chip->charge_type = pval.intval; if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) { eff_fcc_ua = get_effective_result(chip->fcc_votable); if (eff_fcc_ua < 0) { fcc_ua = get_client_vote(chip->fcc_votable, TAPER_STEPPER_VOTER); if (fcc_ua < 0) { pr_err("Couldn't get fcc, exiting taper work\n"); goto done; } eff_fcc_ua = eff_fcc_ua - TAPER_REDUCTION_UA; if (eff_fcc_ua < 0) { fcc_ua -= TAPER_REDUCTION_UA; if (fcc_ua < 0) { pr_err("Can't reduce FCC any more\n"); goto done; } pl_dbg(chip, PR_PARALLEL, "master is taper charging; reducing FCC to %dua\n", eff_fcc_ua); fcc_ua); vote(chip->fcc_votable, TAPER_STEPPER_VOTER, true, eff_fcc_ua); true, fcc_ua); } else { pl_dbg(chip, PR_PARALLEL, "master is fast charging; waiting for next taper\n"); } Loading
drivers/power/supply/qcom/qpnp-smb5.c +52 −9 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ struct smb_dt_props { int auto_recharge_soc; int auto_recharge_vbat_mv; int wd_bark_time; int wd_snarl_time_cfg; int batt_profile_fcc_ua; int batt_profile_fv_uv; int term_current_src; Loading Loading @@ -448,6 +449,11 @@ static int smb5_parse_dt_misc(struct smb5 *chip, struct device_node *node) if (rc < 0 || chip->dt.wd_bark_time < MIN_WD_BARK_TIME) chip->dt.wd_bark_time = DEFAULT_WD_BARK_TIME; rc = of_property_read_u32(node, "qcom,wd-snarl-time-config", &chip->dt.wd_snarl_time_cfg); if (rc < 0) chip->dt.wd_snarl_time_cfg = -EINVAL; chip->dt.no_battery = of_property_read_bool(node, "qcom,batteryless-platform"); Loading Loading @@ -724,6 +730,8 @@ static enum power_supply_property smb5_usb_props[] = { POWER_SUPPLY_PROP_MOISTURE_DETECTED, POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED, POWER_SUPPLY_PROP_QC_OPTI_DISABLE, POWER_SUPPLY_PROP_VOLTAGE_VPH, POWER_SUPPLY_PROP_THERM_ICL_LIMIT, }; static int smb5_usb_get_prop(struct power_supply *psy, Loading Loading @@ -845,6 +853,13 @@ static int smb5_usb_get_prop(struct power_supply *psy, if (chg->hw_connector_mitigation) val->intval |= POWER_SUPPLY_QC_CTM_DISABLE; break; case POWER_SUPPLY_PROP_VOLTAGE_VPH: rc = smblib_get_prop_vph_voltage_now(chg, val); break; case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: val->intval = get_client_vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER); break; default: pr_err("get prop %d is not supported in usb\n", psp); rc = -EINVAL; Loading @@ -865,7 +880,7 @@ static int smb5_usb_set_prop(struct power_supply *psy, { struct smb5 *chip = power_supply_get_drvdata(psy); struct smb_charger *chg = &chip->chg; int rc = 0; int icl, rc = 0; switch (psp) { case POWER_SUPPLY_PROP_PD_CURRENT_MAX: Loading Loading @@ -909,6 +924,14 @@ static int smb5_usb_set_prop(struct power_supply *psy, chg->connector_health = val->intval; power_supply_changed(chg->usb_psy); break; case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: icl = get_effective_result(chg->usb_icl_votable); if ((icl + val->intval) > 0) rc = vote(chg->usb_icl_votable, THERMAL_THROTTLE_VOTER, true, icl + val->intval); else rc = -EINVAL; break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; Loading @@ -924,6 +947,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_CTM_CURRENT_MAX: case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: case POWER_SUPPLY_PROP_THERM_ICL_LIMIT: return 1; default: break; Loading Loading @@ -1890,9 +1914,18 @@ static int smb5_configure_typec(struct smb_charger *chg) rc = smblib_masked_write(chg, USBIN_LOAD_CFG_REG, USBIN_IN_COLLAPSE_GF_SEL_MASK | USBIN_AICL_STEP_TIMING_SEL_MASK, 0); if (rc < 0) if (rc < 0) { dev_err(chg->dev, "Couldn't set USBIN_LOAD_CFG_REG rc=%d\n", rc); return rc; } /* Set CC threshold to 1.6 V in source mode */ rc = smblib_masked_write(chg, TYPE_C_EXIT_STATE_CFG_REG, SEL_SRC_UPPER_REF_BIT, SEL_SRC_UPPER_REF_BIT); if (rc < 0) dev_err(chg->dev, "Couldn't configure CC threshold voltage rc=%d\n", rc); return rc; } Loading Loading @@ -2324,7 +2357,8 @@ static int smb5_init_hw(struct smb5 *chip) */ if (chg->wa_flags & SW_THERM_REGULATION_WA) { rc = smblib_write(chg, MISC_THERMREG_SRC_CFG_REG, THERMREG_DIE_CMP_SRC_EN_BIT); THERMREG_SW_ICL_ADJUST_BIT | THERMREG_DIE_CMP_SRC_EN_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't disable HW thermal regulation rc=%d\n", rc); Loading Loading @@ -2450,9 +2484,17 @@ static int smb5_init_hw(struct smb5 *chip) val = (ilog2(chip->dt.wd_bark_time / 16) << BARK_WDOG_TIMEOUT_SHIFT) & BARK_WDOG_TIMEOUT_MASK; val |= (BITE_WDOG_TIMEOUT_8S | BITE_WDOG_DISABLE_CHARGING_CFG_BIT); if (chip->dt.wd_snarl_time_cfg == -EINVAL) val |= SNARL_WDOG_TMOUT_8S; else val |= (chip->dt.wd_snarl_time_cfg << SNARL_WDOG_TIMEOUT_SHIFT) & SNARL_WDOG_TIMEOUT_MASK; rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG, BITE_WDOG_DISABLE_CHARGING_CFG_BIT | BARK_WDOG_TIMEOUT_MASK | BITE_WDOG_TIMEOUT_MASK, SNARL_WDOG_TIMEOUT_MASK | BARK_WDOG_TIMEOUT_MASK | BITE_WDOG_TIMEOUT_MASK, val); if (rc < 0) { pr_err("Couldn't configue WD config rc=%d\n", rc); Loading Loading @@ -2956,13 +2998,14 @@ static int smb5_request_interrupts(struct smb5 *chip) chg->usb_icl_change_irq_enabled = true; /* * WDOG_SNARL_IRQ is required for SW Thermal Regulation WA only. In * case the WA is not required, disable the WDOG_SNARL_IRQ to prevent * interrupt storm. * WDOG_SNARL_IRQ is required for SW Thermal Regulation WA. In case * the WA is not required and neither is the snarl timer configuration * defined, disable the WDOG_SNARL_IRQ to prevent interrupt storm. */ if (chg->irq_info[WDOG_SNARL_IRQ].irq && !(chg->wa_flags & SW_THERM_REGULATION_WA)) { if (chg->irq_info[WDOG_SNARL_IRQ].irq && (!(chg->wa_flags & SW_THERM_REGULATION_WA) && chip->dt.wd_snarl_time_cfg == -EINVAL)) { disable_irq_wake(chg->irq_info[WDOG_SNARL_IRQ].irq); disable_irq_nosync(chg->irq_info[WDOG_SNARL_IRQ].irq); } Loading
drivers/power/supply/qcom/smb1355-charger.c +23 −3 Original line number Diff line number Diff line Loading @@ -243,6 +243,7 @@ struct smb1355 { int c_health; int c_charger_temp_max; int die_temp_deciDegC; int suspended_usb_icl; bool exit_die_temp; struct delayed_work die_temp_work; bool disabled; Loading Loading @@ -589,6 +590,7 @@ static int smb1355_get_prop_health(struct smb1355 *chip, int type) } #define MIN_PARALLEL_ICL_UA 250000 #define SUSPEND_CURRENT_UA 2000 static int smb1355_parallel_get_prop(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) Loading Loading @@ -665,11 +667,16 @@ static int smb1355_parallel_get_prop(struct power_supply *psy, val->intval = 0; break; case POWER_SUPPLY_PROP_CURRENT_MAX: if (IS_USBIN(chip->dt.pl_mode)) if (IS_USBIN(chip->dt.pl_mode)) { /* Report cached ICL until its configured correctly */ if (chip->suspended_usb_icl) val->intval = chip->suspended_usb_icl; else rc = smb1355_get_charge_param(chip, &chip->param.usb_icl, &val->intval); else } else { val->intval = 0; } break; case POWER_SUPPLY_PROP_MIN_ICL: val->intval = MIN_PARALLEL_ICL_UA; Loading Loading @@ -702,6 +709,18 @@ static int smb1355_set_parallel_charging(struct smb1355 *chip, bool disable) if (chip->disabled == disable) return 0; if (IS_USBIN(chip->dt.pl_mode)) { /* * Initialize ICL configuration to minimum value while * depending upon the set icl configuration method to properly * configure the ICL value. At the same time, cache the value * of ICL to be reported as 2mA. */ chip->suspended_usb_icl = SUSPEND_CURRENT_UA; smb1355_set_charge_param(chip, &chip->param.usb_icl, MIN_PARALLEL_ICL_UA); } rc = smb1355_masked_write(chip, WD_CFG_REG, WDOG_TIMER_EN_BIT, disable ? 0 : WDOG_TIMER_EN_BIT); if (rc < 0) { Loading Loading @@ -770,6 +789,7 @@ static int smb1355_set_current_max(struct smb1355 *chip, int curr) rc = smb1355_set_charge_param(chip, &chip->param.usb_icl, curr); chip->suspended_usb_icl = 0; } return rc; Loading
drivers/power/supply/qcom/smb1390-charger-psy.c +87 −10 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/qpnp/qpnp-revid.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/of_irq.h> Loading Loading @@ -61,6 +62,10 @@ #define CORE_FTRIM_ILIM_REG 0x1030 #define CFG_ILIM_MASK GENMASK(4, 0) #define CORE_FTRIM_CTRL_REG 0x1031 #define TEMP_ALERT_LVL_MASK GENMASK(6, 5) #define TEMP_ALERT_LVL_SHIFT 5 #define CORE_FTRIM_LVL_REG 0x1033 #define CFG_WIN_HI_MASK GENMASK(3, 2) #define WIN_OV_LVL_1000MV 0x08 Loading @@ -85,6 +90,8 @@ #define SRC_VOTER "SRC_VOTER" #define SWITCHER_TOGGLE_VOTER "SWITCHER_TOGGLE_VOTER" #define THERMAL_SUSPEND_DECIDEGC 1400 #define smb1390_dbg(chip, reason, fmt, ...) \ do { \ if (chip->debug_mask & (reason)) \ Loading Loading @@ -130,6 +137,7 @@ struct smb1390 { struct notifier_block nb; struct wakeup_source *cp_ws; struct dentry *dfs_root; struct pmic_revid_data *pmic_rev_id; /* work structs */ struct work_struct status_change_work; Loading Loading @@ -161,6 +169,8 @@ struct smb1390 { int die_temp; bool suspended; u32 debug_mask; u32 min_ilim_ua; u32 max_temp_alarm_degc; }; struct smb_irq { Loading Loading @@ -493,8 +503,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data, return rc; } /* ILIM less than 1A is not accurate; disable charging */ if (ilim_uA < 1000000) { /* ILIM less than min_ilim_ua, disable charging */ if (ilim_uA < chip->min_ilim_ua) { smb1390_dbg(chip, PR_INFO, "ILIM %duA is too low to allow charging\n", ilim_uA); vote(chip->disable_votable, ILIM_VOTER, true, 0); Loading Loading @@ -660,7 +670,7 @@ static void smb1390_taper_work(struct work_struct *work) fcc_uA); vote(chip->fcc_votable, CP_VOTER, true, fcc_uA); if (fcc_uA < 2000000) { if (fcc_uA < (chip->min_ilim_ua * 2)) { vote(chip->disable_votable, TAPER_END_VOTER, true, 0); goto out; Loading @@ -687,6 +697,7 @@ static enum power_supply_property smb1390_charge_pump_props[] = { POWER_SUPPLY_PROP_CP_TOGGLE_SWITCHER, POWER_SUPPLY_PROP_CP_IRQ_STATUS, POWER_SUPPLY_PROP_CP_ILIM, POWER_SUPPLY_PROP_CHIP_VERSION, }; static int smb1390_get_prop(struct power_supply *psy, Loading Loading @@ -731,9 +742,24 @@ static int smb1390_get_prop(struct power_supply *psy, else rc = -ENODATA; } else { /* * Add a filter to the die temp value read: * If temp > THERMAL_SUSPEND_DECIDEGC then * - treat it as an error and report last valid * cached temperature. * - return -ENODATA if the cached value is * invalid. */ rc = smb1390_get_die_temp(chip, val); if (rc >= 0) if (rc >= 0) { if (val->intval <= THERMAL_SUSPEND_DECIDEGC) chip->die_temp = val->intval; else if (chip->die_temp == -ENODATA) rc = -ENODATA; else val->intval = chip->die_temp; } } break; case POWER_SUPPLY_PROP_CP_ISNS: Loading @@ -758,6 +784,9 @@ static int smb1390_get_prop(struct power_supply *psy, val->intval = ((status & CFG_ILIM_MASK) * 100000) + 500000; break; case POWER_SUPPLY_PROP_CHIP_VERSION: val->intval = chip->pmic_rev_id->rev4; break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply get prop %d not supported\n", prop); Loading Loading @@ -855,9 +884,19 @@ static int smb1390_parse_dt(struct smb1390 *chip) chip->iio.die_temp_chan = NULL; return rc; } } else { return rc; } return rc; chip->min_ilim_ua = 1000000; /* 1A */ of_property_read_u32(chip->dev->of_node, "qcom,min-ilim-ua", &chip->min_ilim_ua); chip->max_temp_alarm_degc = 110; of_property_read_u32(chip->dev->of_node, "qcom,max-temp-alarm-degc", &chip->max_temp_alarm_degc); return 0; } static void smb1390_release_channels(struct smb1390 *chip) Loading Loading @@ -903,7 +942,7 @@ static void smb1390_destroy_votables(struct smb1390 *chip) static int smb1390_init_hw(struct smb1390 *chip) { int rc; int rc = 0, val; /* * Improve ILIM accuracy: Loading @@ -920,8 +959,25 @@ static int smb1390_init_hw(struct smb1390 *chip) if (rc < 0) return rc; switch (chip->max_temp_alarm_degc) { case 125: val = 0x00; break; case 95: val = 0x02; break; case 85: val = 0x03; break; case 110: default: val = 0x01; break; } rc = smb1390_masked_write(chip, CORE_FTRIM_CTRL_REG, TEMP_ALERT_LVL_MASK, val << TEMP_ALERT_LVL_SHIFT); return 0; return rc; } static int smb1390_get_irq_index_byname(const char *irq_name) Loading Loading @@ -1023,8 +1079,28 @@ static void smb1390_create_debugfs(struct smb1390 *chip) static int smb1390_probe(struct platform_device *pdev) { struct smb1390 *chip; struct device_node *revid_dev_node; struct pmic_revid_data *pmic_rev_id; int rc; revid_dev_node = of_parse_phandle(pdev->dev.of_node, "qcom,pmic-revid", 0); if (!revid_dev_node) { pr_err("Missing qcom,pmic-revid property\n"); return -EINVAL; } pmic_rev_id = get_revid_data(revid_dev_node); of_node_put(revid_dev_node); if (IS_ERR_OR_NULL(pmic_rev_id)) { /* * the revid peripheral must be registered, any failure * here only indicates that the rev-id module has not * probed yet. */ return -EPROBE_DEFER; } chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; Loading @@ -1033,6 +1109,7 @@ static int smb1390_probe(struct platform_device *pdev) spin_lock_init(&chip->status_change_lock); mutex_init(&chip->die_chan_lock); chip->die_temp = -ENODATA; chip->pmic_rev_id = pmic_rev_id; platform_set_drvdata(pdev, chip); chip->regmap = dev_get_regmap(chip->dev->parent, NULL); Loading Loading @@ -1087,8 +1164,8 @@ static int smb1390_probe(struct platform_device *pdev) smb1390_create_debugfs(chip); pr_debug("smb1390 probed successfully\n"); pr_debug("smb1390 probed successfully chip_version=%d\n", chip->pmic_rev_id->rev4); return 0; out_notifier: Loading