Loading drivers/power/supply/qcom/qpnp-smb2.c +16 −10 Original line number Diff line number Diff line Loading @@ -188,6 +188,11 @@ static int __weak_chg_icl_ua = 500000; module_param_named( weak_chg_icl_ua, __weak_chg_icl_ua, int, 0600); static int __try_sink_enabled = 1; module_param_named( try_sink_enabled, __try_sink_enabled, int, 0600 ); #define MICRO_1P5A 1500000 #define MICRO_P1A 100000 #define OTG_DEFAULT_DEGLITCH_TIME_MS 50 Loading Loading @@ -1037,7 +1042,10 @@ static int smb2_batt_get_prop(struct power_supply *psy, val->intval = 0; break; case POWER_SUPPLY_PROP_DIE_HEALTH: if (chg->die_health == -EINVAL) rc = smblib_get_prop_die_health(chg, val); else val->intval = chg->die_health; break; case POWER_SUPPLY_PROP_DP_DM: val->intval = chg->pulse_cnt; Loading Loading @@ -1145,6 +1153,10 @@ static int smb2_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: rc = smblib_set_prop_input_current_limited(chg, val); break; case POWER_SUPPLY_PROP_DIE_HEALTH: chg->die_health = val->intval; power_supply_changed(chg->batt_psy); break; default: rc = -EINVAL; } Loading @@ -1166,6 +1178,7 @@ static int smb2_batt_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_SW_JEITA_ENABLED: case POWER_SUPPLY_PROP_DIE_HEALTH: return 1; default: break; Loading Loading @@ -1647,15 +1660,6 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } /* disable SW STAT override */ rc = smblib_masked_write(chg, STAT_CFG_REG, STAT_SW_OVERRIDE_CFG_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't disable SW STAT override rc=%d\n", rc); return rc; } /* disable h/w autonomous parallel charging control */ rc = smblib_masked_write(chg, MISC_CFG_REG, STAT_PARALLEL_1400MA_EN_CFG_BIT, 0); Loading Loading @@ -2244,9 +2248,11 @@ static int smb2_probe(struct platform_device *pdev) chg->dev = &pdev->dev; chg->param = v1_params; chg->debug_mask = &__debug_mask; chg->try_sink_enabled = &__try_sink_enabled; chg->weak_chg_icl_ua = &__weak_chg_icl_ua; chg->mode = PARALLEL_MASTER; chg->irq_info = smb2_irqs; chg->die_health = -EINVAL; chg->name = "PMI"; chg->regmap = dev_get_regmap(chg->dev->parent, NULL); Loading drivers/power/supply/qcom/smb-lib.c +198 −3 Original line number Diff line number Diff line Loading @@ -143,6 +143,23 @@ int smblib_icl_override(struct smb_charger *chg, bool override) return rc; } int smblib_stat_sw_override_cfg(struct smb_charger *chg, bool override) { int rc; /* override = 1, SW STAT override; override = 0, HW auto mode */ rc = smblib_masked_write(chg, STAT_CFG_REG, STAT_SW_OVERRIDE_CFG_BIT, override ? STAT_SW_OVERRIDE_CFG_BIT : 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SW STAT override rc=%d\n", rc); return rc; } return rc; } /******************** * REGISTER GETTERS * ********************/ Loading Loading @@ -584,8 +601,10 @@ static int smblib_notifier_call(struct notifier_block *nb, schedule_work(&chg->bms_update_work); } if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel")) if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel")) { chg->pl.psy = psy; schedule_work(&chg->pl_update_work); } return NOTIFY_OK; } Loading Loading @@ -3773,8 +3792,165 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data) return IRQ_HANDLED; } static int typec_try_sink(struct smb_charger *chg) { union power_supply_propval val; bool debounce_done, vbus_detected, sink; u8 stat; int exit_mode = ATTACHED_SRC, rc; /* ignore typec interrupt while try.snk WIP */ chg->try_sink_active = true; /* force SNK mode */ val.intval = POWER_SUPPLY_TYPEC_PR_SINK; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) { smblib_err(chg, "Couldn't set UFP mode rc=%d\n", rc); goto try_sink_exit; } /* reduce Tccdebounce time to ~20ms */ rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, TCC_DEBOUNCE_20MS_BIT); if (rc < 0) { smblib_err(chg, "Couldn't set MISC_CFG_REG rc=%d\n", rc); goto try_sink_exit; } /* * give opportunity to the other side to be a SRC, * for tDRPTRY + Tccdebounce time */ msleep(100); rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); goto try_sink_exit; } debounce_done = stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT; if (!debounce_done) /* * The other side didn't switch to source, either it * is an adamant sink or is removed go back to showing Rp */ goto try_wait_src; /* * We are in force sink mode and the other side has switched to * showing Rp. Config DRP in case the other side removes Rp so we * can quickly (20ms) switch to showing our Rp. Note that the spec * needs us to show Rp for 80mS while the drp DFP residency is just * 54mS. But 54mS is plenty time for us to react and force Rp for * the remaining 26mS. */ val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) { smblib_err(chg, "Couldn't set DFP mode rc=%d\n", rc); goto try_sink_exit; } /* * while other side is Rp, wait for VBUS from it; exit if other side * removes Rp */ do { rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); goto try_sink_exit; } debounce_done = stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT; vbus_detected = stat & TYPEC_VBUS_STATUS_BIT; /* Successfully transitioned to ATTACHED.SNK */ if (vbus_detected && debounce_done) { exit_mode = ATTACHED_SINK; goto try_sink_exit; } /* * Ensure sink since drp may put us in source if other * side switches back to Rd */ sink = !(stat & UFP_DFP_MODE_STATUS_BIT); usleep_range(1000, 2000); } while (debounce_done && sink); try_wait_src: /* * Transition to trywait.SRC state. check if other side still wants * to be SNK or has been removed. */ val.intval = POWER_SUPPLY_TYPEC_PR_SOURCE; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) { smblib_err(chg, "Couldn't set UFP mode rc=%d\n", rc); goto try_sink_exit; } /* Need to be in this state for tDRPTRY time, 75ms~150ms */ msleep(80); rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); goto try_sink_exit; } debounce_done = stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT; if (debounce_done) /* the other side wants to be a sink */ exit_mode = ATTACHED_SRC; else /* the other side is detached */ exit_mode = UNATTACHED_SINK; try_sink_exit: /* release forcing of SRC/SNK mode */ val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) smblib_err(chg, "Couldn't set DFP mode rc=%d\n", rc); /* revert Tccdebounce time back to ~120ms */ rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, 0); if (rc < 0) smblib_err(chg, "Couldn't set MISC_CFG_REG rc=%d\n", rc); chg->try_sink_active = false; return exit_mode; } static void typec_sink_insertion(struct smb_charger *chg) { int exit_mode; /* * Try.SNK entry status - ATTACHWAIT.SRC state and detected Rd-open * or RD-Ra for TccDebounce time. */ if (*chg->try_sink_enabled) { exit_mode = typec_try_sink(chg); if (exit_mode != ATTACHED_SRC) { smblib_usb_typec_change(chg); return; } } /* when a sink is inserted we should not wait on hvdcp timeout to * enable pd */ Loading Loading @@ -4041,7 +4217,7 @@ static void smblib_handle_typec_cc_state_change(struct smb_charger *chg) smblib_typec_mode_name[chg->typec_mode]); } static void smblib_usb_typec_change(struct smb_charger *chg) void smblib_usb_typec_change(struct smb_charger *chg) { int rc; Loading Loading @@ -4077,7 +4253,8 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) return IRQ_HANDLED; } if (chg->cc2_detach_wa_active || chg->typec_en_dis_active) { if (chg->cc2_detach_wa_active || chg->typec_en_dis_active || chg->try_sink_active) { smblib_dbg(chg, PR_INTERRUPT, "Ignoring since %s active\n", chg->cc2_detach_wa_active ? "cc2_detach_wa" : "typec_en_dis"); Loading Loading @@ -4282,6 +4459,14 @@ static void bms_update_work(struct work_struct *work) power_supply_changed(chg->batt_psy); } static void pl_update_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, pl_update_work); smblib_stat_sw_override_cfg(chg, false); } static void clear_hdc_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, Loading Loading @@ -4812,6 +4997,7 @@ int smblib_init(struct smb_charger *chg) mutex_init(&chg->otg_oc_lock); mutex_init(&chg->vconn_oc_lock); INIT_WORK(&chg->bms_update_work, bms_update_work); INIT_WORK(&chg->pl_update_work, pl_update_work); INIT_WORK(&chg->rdstd_cc2_detach_work, rdstd_cc2_detach_work); INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work); INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work); Loading Loading @@ -4860,6 +5046,14 @@ int smblib_init(struct smb_charger *chg) chg->bms_psy = power_supply_get_by_name("bms"); chg->pl.psy = power_supply_get_by_name("parallel"); if (chg->pl.psy) { rc = smblib_stat_sw_override_cfg(chg, false); if (rc < 0) { smblib_err(chg, "Couldn't config stat sw rc=%d\n", rc); return rc; } } break; case PARALLEL_SLAVE: break; Loading @@ -4876,6 +5070,7 @@ int smblib_deinit(struct smb_charger *chg) switch (chg->mode) { case PARALLEL_MASTER: cancel_work_sync(&chg->bms_update_work); cancel_work_sync(&chg->pl_update_work); cancel_work_sync(&chg->rdstd_cc2_detach_work); cancel_delayed_work_sync(&chg->hvdcp_detect_work); cancel_delayed_work_sync(&chg->clear_hdc_work); Loading drivers/power/supply/qcom/smb-lib.h +13 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,12 @@ enum smb_irq_index { SMB_IRQ_MAX, }; enum try_sink_exit_mode { ATTACHED_SRC = 0, ATTACHED_SINK, UNATTACHED_SINK, }; struct smb_irq_info { const char *name; const irq_handler_t handler; Loading Loading @@ -232,6 +238,7 @@ struct smb_charger { struct smb_params param; struct smb_iio iio; int *debug_mask; int *try_sink_enabled; enum smb_mode mode; struct smb_chg_freq chg_freq; int smb_version; Loading Loading @@ -287,6 +294,7 @@ struct smb_charger { /* work */ struct work_struct bms_update_work; struct work_struct pl_update_work; struct work_struct rdstd_cc2_detach_work; struct delayed_work hvdcp_detect_work; struct delayed_work ps_change_timeout_work; Loading Loading @@ -342,6 +350,7 @@ struct smb_charger { u32 wa_flags; bool cc2_detach_wa_active; bool typec_en_dis_active; bool try_sink_active; int boost_current_ua; int temp_speed_reading_count; Loading @@ -355,6 +364,8 @@ struct smb_charger { /* qnovo */ int usb_icl_delta_ua; int pulse_cnt; int die_health; }; int smblib_read(struct smb_charger *chg, u16 addr, u8 *val); Loading Loading @@ -523,6 +534,8 @@ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, const union power_supply_propval *val); int smblib_stat_sw_override_cfg(struct smb_charger *chg, bool override); void smblib_usb_typec_change(struct smb_charger *chg); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); Loading drivers/power/supply/qcom/smb1355-charger.c +32 −3 Original line number Diff line number Diff line Loading @@ -146,6 +146,8 @@ struct smb1355 { struct power_supply *parallel_psy; struct pmic_revid_data *pmic_rev_id; int c_health; }; static bool is_secure(struct smb1355 *chip, int addr) Loading Loading @@ -434,7 +436,10 @@ static int smb1355_parallel_get_prop(struct power_supply *psy, val->intval = POWER_SUPPLY_PL_USBMID_USBMID; break; case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: if (chip->c_health == -EINVAL) val->intval = smb1355_get_prop_connector_health(chip); else val->intval = chip->c_health; break; default: pr_err_ratelimited("parallel psy get prop %d not supported\n", Loading Loading @@ -497,6 +502,10 @@ static int smb1355_parallel_set_prop(struct power_supply *psy, rc = smb1355_set_charge_param(chip, &chip->param.fcc, val->intval); break; case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: chip->c_health = val->intval; power_supply_changed(chip->parallel_psy); break; default: pr_debug("parallel power supply set prop %d not supported\n", prop); Loading @@ -509,6 +518,13 @@ static int smb1355_parallel_set_prop(struct power_supply *psy, static int smb1355_parallel_prop_is_writeable(struct power_supply *psy, enum power_supply_property prop) { switch (prop) { case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: return 1; default: break; } return 0; } Loading Loading @@ -714,6 +730,7 @@ static int smb1355_probe(struct platform_device *pdev) chip->dev = &pdev->dev; chip->param = v1_params; chip->c_health = -EINVAL; chip->name = "smb1355"; mutex_init(&chip->write_lock); Loading Loading @@ -763,6 +780,17 @@ static int smb1355_remove(struct platform_device *pdev) return 0; } static void smb1355_shutdown(struct platform_device *pdev) { struct smb1355 *chip = platform_get_drvdata(pdev); int rc; /* disable parallel charging path */ rc = smb1355_set_parallel_charging(chip, true); if (rc < 0) pr_err("Couldn't disable parallel path rc=%d\n", rc); } static struct platform_driver smb1355_driver = { .driver = { .name = "qcom,smb1355-charger", Loading @@ -771,6 +799,7 @@ static struct platform_driver smb1355_driver = { }, .probe = smb1355_probe, .remove = smb1355_remove, .shutdown = smb1355_shutdown, }; module_platform_driver(smb1355_driver); Loading Loading
drivers/power/supply/qcom/qpnp-smb2.c +16 −10 Original line number Diff line number Diff line Loading @@ -188,6 +188,11 @@ static int __weak_chg_icl_ua = 500000; module_param_named( weak_chg_icl_ua, __weak_chg_icl_ua, int, 0600); static int __try_sink_enabled = 1; module_param_named( try_sink_enabled, __try_sink_enabled, int, 0600 ); #define MICRO_1P5A 1500000 #define MICRO_P1A 100000 #define OTG_DEFAULT_DEGLITCH_TIME_MS 50 Loading Loading @@ -1037,7 +1042,10 @@ static int smb2_batt_get_prop(struct power_supply *psy, val->intval = 0; break; case POWER_SUPPLY_PROP_DIE_HEALTH: if (chg->die_health == -EINVAL) rc = smblib_get_prop_die_health(chg, val); else val->intval = chg->die_health; break; case POWER_SUPPLY_PROP_DP_DM: val->intval = chg->pulse_cnt; Loading Loading @@ -1145,6 +1153,10 @@ static int smb2_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: rc = smblib_set_prop_input_current_limited(chg, val); break; case POWER_SUPPLY_PROP_DIE_HEALTH: chg->die_health = val->intval; power_supply_changed(chg->batt_psy); break; default: rc = -EINVAL; } Loading @@ -1166,6 +1178,7 @@ static int smb2_batt_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED: case POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED: case POWER_SUPPLY_PROP_SW_JEITA_ENABLED: case POWER_SUPPLY_PROP_DIE_HEALTH: return 1; default: break; Loading Loading @@ -1647,15 +1660,6 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } /* disable SW STAT override */ rc = smblib_masked_write(chg, STAT_CFG_REG, STAT_SW_OVERRIDE_CFG_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't disable SW STAT override rc=%d\n", rc); return rc; } /* disable h/w autonomous parallel charging control */ rc = smblib_masked_write(chg, MISC_CFG_REG, STAT_PARALLEL_1400MA_EN_CFG_BIT, 0); Loading Loading @@ -2244,9 +2248,11 @@ static int smb2_probe(struct platform_device *pdev) chg->dev = &pdev->dev; chg->param = v1_params; chg->debug_mask = &__debug_mask; chg->try_sink_enabled = &__try_sink_enabled; chg->weak_chg_icl_ua = &__weak_chg_icl_ua; chg->mode = PARALLEL_MASTER; chg->irq_info = smb2_irqs; chg->die_health = -EINVAL; chg->name = "PMI"; chg->regmap = dev_get_regmap(chg->dev->parent, NULL); Loading
drivers/power/supply/qcom/smb-lib.c +198 −3 Original line number Diff line number Diff line Loading @@ -143,6 +143,23 @@ int smblib_icl_override(struct smb_charger *chg, bool override) return rc; } int smblib_stat_sw_override_cfg(struct smb_charger *chg, bool override) { int rc; /* override = 1, SW STAT override; override = 0, HW auto mode */ rc = smblib_masked_write(chg, STAT_CFG_REG, STAT_SW_OVERRIDE_CFG_BIT, override ? STAT_SW_OVERRIDE_CFG_BIT : 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SW STAT override rc=%d\n", rc); return rc; } return rc; } /******************** * REGISTER GETTERS * ********************/ Loading Loading @@ -584,8 +601,10 @@ static int smblib_notifier_call(struct notifier_block *nb, schedule_work(&chg->bms_update_work); } if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel")) if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel")) { chg->pl.psy = psy; schedule_work(&chg->pl_update_work); } return NOTIFY_OK; } Loading Loading @@ -3773,8 +3792,165 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data) return IRQ_HANDLED; } static int typec_try_sink(struct smb_charger *chg) { union power_supply_propval val; bool debounce_done, vbus_detected, sink; u8 stat; int exit_mode = ATTACHED_SRC, rc; /* ignore typec interrupt while try.snk WIP */ chg->try_sink_active = true; /* force SNK mode */ val.intval = POWER_SUPPLY_TYPEC_PR_SINK; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) { smblib_err(chg, "Couldn't set UFP mode rc=%d\n", rc); goto try_sink_exit; } /* reduce Tccdebounce time to ~20ms */ rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, TCC_DEBOUNCE_20MS_BIT); if (rc < 0) { smblib_err(chg, "Couldn't set MISC_CFG_REG rc=%d\n", rc); goto try_sink_exit; } /* * give opportunity to the other side to be a SRC, * for tDRPTRY + Tccdebounce time */ msleep(100); rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); goto try_sink_exit; } debounce_done = stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT; if (!debounce_done) /* * The other side didn't switch to source, either it * is an adamant sink or is removed go back to showing Rp */ goto try_wait_src; /* * We are in force sink mode and the other side has switched to * showing Rp. Config DRP in case the other side removes Rp so we * can quickly (20ms) switch to showing our Rp. Note that the spec * needs us to show Rp for 80mS while the drp DFP residency is just * 54mS. But 54mS is plenty time for us to react and force Rp for * the remaining 26mS. */ val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) { smblib_err(chg, "Couldn't set DFP mode rc=%d\n", rc); goto try_sink_exit; } /* * while other side is Rp, wait for VBUS from it; exit if other side * removes Rp */ do { rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); goto try_sink_exit; } debounce_done = stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT; vbus_detected = stat & TYPEC_VBUS_STATUS_BIT; /* Successfully transitioned to ATTACHED.SNK */ if (vbus_detected && debounce_done) { exit_mode = ATTACHED_SINK; goto try_sink_exit; } /* * Ensure sink since drp may put us in source if other * side switches back to Rd */ sink = !(stat & UFP_DFP_MODE_STATUS_BIT); usleep_range(1000, 2000); } while (debounce_done && sink); try_wait_src: /* * Transition to trywait.SRC state. check if other side still wants * to be SNK or has been removed. */ val.intval = POWER_SUPPLY_TYPEC_PR_SOURCE; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) { smblib_err(chg, "Couldn't set UFP mode rc=%d\n", rc); goto try_sink_exit; } /* Need to be in this state for tDRPTRY time, 75ms~150ms */ msleep(80); rc = smblib_read(chg, TYPE_C_STATUS_4_REG, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); goto try_sink_exit; } debounce_done = stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT; if (debounce_done) /* the other side wants to be a sink */ exit_mode = ATTACHED_SRC; else /* the other side is detached */ exit_mode = UNATTACHED_SINK; try_sink_exit: /* release forcing of SRC/SNK mode */ val.intval = POWER_SUPPLY_TYPEC_PR_DUAL; rc = smblib_set_prop_typec_power_role(chg, &val); if (rc < 0) smblib_err(chg, "Couldn't set DFP mode rc=%d\n", rc); /* revert Tccdebounce time back to ~120ms */ rc = smblib_masked_write(chg, MISC_CFG_REG, TCC_DEBOUNCE_20MS_BIT, 0); if (rc < 0) smblib_err(chg, "Couldn't set MISC_CFG_REG rc=%d\n", rc); chg->try_sink_active = false; return exit_mode; } static void typec_sink_insertion(struct smb_charger *chg) { int exit_mode; /* * Try.SNK entry status - ATTACHWAIT.SRC state and detected Rd-open * or RD-Ra for TccDebounce time. */ if (*chg->try_sink_enabled) { exit_mode = typec_try_sink(chg); if (exit_mode != ATTACHED_SRC) { smblib_usb_typec_change(chg); return; } } /* when a sink is inserted we should not wait on hvdcp timeout to * enable pd */ Loading Loading @@ -4041,7 +4217,7 @@ static void smblib_handle_typec_cc_state_change(struct smb_charger *chg) smblib_typec_mode_name[chg->typec_mode]); } static void smblib_usb_typec_change(struct smb_charger *chg) void smblib_usb_typec_change(struct smb_charger *chg) { int rc; Loading Loading @@ -4077,7 +4253,8 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data) return IRQ_HANDLED; } if (chg->cc2_detach_wa_active || chg->typec_en_dis_active) { if (chg->cc2_detach_wa_active || chg->typec_en_dis_active || chg->try_sink_active) { smblib_dbg(chg, PR_INTERRUPT, "Ignoring since %s active\n", chg->cc2_detach_wa_active ? "cc2_detach_wa" : "typec_en_dis"); Loading Loading @@ -4282,6 +4459,14 @@ static void bms_update_work(struct work_struct *work) power_supply_changed(chg->batt_psy); } static void pl_update_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, pl_update_work); smblib_stat_sw_override_cfg(chg, false); } static void clear_hdc_work(struct work_struct *work) { struct smb_charger *chg = container_of(work, struct smb_charger, Loading Loading @@ -4812,6 +4997,7 @@ int smblib_init(struct smb_charger *chg) mutex_init(&chg->otg_oc_lock); mutex_init(&chg->vconn_oc_lock); INIT_WORK(&chg->bms_update_work, bms_update_work); INIT_WORK(&chg->pl_update_work, pl_update_work); INIT_WORK(&chg->rdstd_cc2_detach_work, rdstd_cc2_detach_work); INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work); INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work); Loading Loading @@ -4860,6 +5046,14 @@ int smblib_init(struct smb_charger *chg) chg->bms_psy = power_supply_get_by_name("bms"); chg->pl.psy = power_supply_get_by_name("parallel"); if (chg->pl.psy) { rc = smblib_stat_sw_override_cfg(chg, false); if (rc < 0) { smblib_err(chg, "Couldn't config stat sw rc=%d\n", rc); return rc; } } break; case PARALLEL_SLAVE: break; Loading @@ -4876,6 +5070,7 @@ int smblib_deinit(struct smb_charger *chg) switch (chg->mode) { case PARALLEL_MASTER: cancel_work_sync(&chg->bms_update_work); cancel_work_sync(&chg->pl_update_work); cancel_work_sync(&chg->rdstd_cc2_detach_work); cancel_delayed_work_sync(&chg->hvdcp_detect_work); cancel_delayed_work_sync(&chg->clear_hdc_work); Loading
drivers/power/supply/qcom/smb-lib.h +13 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,12 @@ enum smb_irq_index { SMB_IRQ_MAX, }; enum try_sink_exit_mode { ATTACHED_SRC = 0, ATTACHED_SINK, UNATTACHED_SINK, }; struct smb_irq_info { const char *name; const irq_handler_t handler; Loading Loading @@ -232,6 +238,7 @@ struct smb_charger { struct smb_params param; struct smb_iio iio; int *debug_mask; int *try_sink_enabled; enum smb_mode mode; struct smb_chg_freq chg_freq; int smb_version; Loading Loading @@ -287,6 +294,7 @@ struct smb_charger { /* work */ struct work_struct bms_update_work; struct work_struct pl_update_work; struct work_struct rdstd_cc2_detach_work; struct delayed_work hvdcp_detect_work; struct delayed_work ps_change_timeout_work; Loading Loading @@ -342,6 +350,7 @@ struct smb_charger { u32 wa_flags; bool cc2_detach_wa_active; bool typec_en_dis_active; bool try_sink_active; int boost_current_ua; int temp_speed_reading_count; Loading @@ -355,6 +364,8 @@ struct smb_charger { /* qnovo */ int usb_icl_delta_ua; int pulse_cnt; int die_health; }; int smblib_read(struct smb_charger *chg, u16 addr, u8 *val); Loading Loading @@ -523,6 +534,8 @@ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, const union power_supply_propval *val); int smblib_stat_sw_override_cfg(struct smb_charger *chg, bool override); void smblib_usb_typec_change(struct smb_charger *chg); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); Loading
drivers/power/supply/qcom/smb1355-charger.c +32 −3 Original line number Diff line number Diff line Loading @@ -146,6 +146,8 @@ struct smb1355 { struct power_supply *parallel_psy; struct pmic_revid_data *pmic_rev_id; int c_health; }; static bool is_secure(struct smb1355 *chip, int addr) Loading Loading @@ -434,7 +436,10 @@ static int smb1355_parallel_get_prop(struct power_supply *psy, val->intval = POWER_SUPPLY_PL_USBMID_USBMID; break; case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: if (chip->c_health == -EINVAL) val->intval = smb1355_get_prop_connector_health(chip); else val->intval = chip->c_health; break; default: pr_err_ratelimited("parallel psy get prop %d not supported\n", Loading Loading @@ -497,6 +502,10 @@ static int smb1355_parallel_set_prop(struct power_supply *psy, rc = smb1355_set_charge_param(chip, &chip->param.fcc, val->intval); break; case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: chip->c_health = val->intval; power_supply_changed(chip->parallel_psy); break; default: pr_debug("parallel power supply set prop %d not supported\n", prop); Loading @@ -509,6 +518,13 @@ static int smb1355_parallel_set_prop(struct power_supply *psy, static int smb1355_parallel_prop_is_writeable(struct power_supply *psy, enum power_supply_property prop) { switch (prop) { case POWER_SUPPLY_PROP_CONNECTOR_HEALTH: return 1; default: break; } return 0; } Loading Loading @@ -714,6 +730,7 @@ static int smb1355_probe(struct platform_device *pdev) chip->dev = &pdev->dev; chip->param = v1_params; chip->c_health = -EINVAL; chip->name = "smb1355"; mutex_init(&chip->write_lock); Loading Loading @@ -763,6 +780,17 @@ static int smb1355_remove(struct platform_device *pdev) return 0; } static void smb1355_shutdown(struct platform_device *pdev) { struct smb1355 *chip = platform_get_drvdata(pdev); int rc; /* disable parallel charging path */ rc = smb1355_set_parallel_charging(chip, true); if (rc < 0) pr_err("Couldn't disable parallel path rc=%d\n", rc); } static struct platform_driver smb1355_driver = { .driver = { .name = "qcom,smb1355-charger", Loading @@ -771,6 +799,7 @@ static struct platform_driver smb1355_driver = { }, .probe = smb1355_probe, .remove = smb1355_remove, .shutdown = smb1355_shutdown, }; module_platform_driver(smb1355_driver); Loading