Loading drivers/power/supply/qcom/qpnp-smb5.c +44 −10 Original line number Diff line number Diff line Loading @@ -243,6 +243,8 @@ static int smb5_chg_config_init(struct smb5 *chip) chg->param = smb5_pmi632_params; chg->use_extcon = true; chg->name = "pmi632_charger"; /* PMI632 does not support PD */ __pd_disabled = 1; chg->hw_max_icl_ua = (chip->dt.usb_icl_ua > 0) ? chip->dt.usb_icl_ua : PMI632_MAX_ICL_UA; Loading Loading @@ -1431,11 +1433,38 @@ static int smb5_init_vconn_regulator(struct smb5 *chip) static int smb5_configure_typec(struct smb_charger *chg) { int rc; u8 val = 0; rc = smblib_read(chg, LEGACY_CABLE_STATUS_REG, &val); if (rc < 0) { dev_err(chg->dev, "Couldn't read Legacy status rc=%d\n", rc); return rc; } /* * If Legacy cable is detected re-trigger Legacy detection * by disabling/enabling typeC mode. */ if (val & TYPEC_LEGACY_CABLE_STATUS_BIT) { rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_DISABLE_CMD_BIT, TYPEC_DISABLE_CMD_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't disable TYPEC rc=%d\n", rc); return rc; } /* delay before enabling typeC */ msleep(500); rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_DISABLE_CMD_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't enable TYPEC rc=%d\n", rc); return rc; } } /* disable apsd */ rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, 0); rc = smblib_configure_hvdcp_apsd(chg, false); if (rc < 0) { dev_err(chg->dev, "Couldn't disable APSD rc=%d\n", rc); return rc; Loading Loading @@ -1548,7 +1577,6 @@ static int smb5_init_hw(struct smb5 *chip) if (type) { chg->connector_type = POWER_SUPPLY_CONNECTOR_MICRO_USB; smblib_rerun_apsd_if_required(chg); rc = smb5_configure_micro_usb(chg); } else { chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC; Loading @@ -1562,10 +1590,14 @@ static int smb5_init_hw(struct smb5 *chip) /* * PMI632 based hw init: * - Rerun APSD to ensure proper charger detection if device * boots with charger connected. * - Initialize flash module for PMI632 */ if (chg->smb_version == PMI632_SUBTYPE) if (chg->smb_version == PMI632_SUBTYPE) { schgm_flash_init(chg); smblib_rerun_apsd_if_required(chg); } /* vote 0mA on usb_icl for non battery platforms */ vote(chg->usb_icl_votable, Loading @@ -1589,14 +1621,16 @@ static int smb5_init_hw(struct smb5 *chip) /* * AICL configuration: * start from min and AICL ADC disable * AICL ADC disable */ if (chg->smb_version != PMI632_SUBTYPE) { rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG, USBIN_AICL_ADC_EN_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure AICL rc=%d\n", rc); dev_err(chg->dev, "Couldn't config AICL rc=%d\n", rc); return rc; } } /* enable the charging path */ rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0); Loading drivers/power/supply/qcom/smb5-lib.c +37 −23 Original line number Diff line number Diff line Loading @@ -512,6 +512,23 @@ static int smblib_set_usb_pd_allowed_voltage(struct smb_charger *chg, /******************** * HELPER FUNCTIONS * ********************/ int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable) { int rc; u8 mask = HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT; if (chg->pd_disabled) return 0; rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, mask, enable ? mask : 0); if (rc < 0) smblib_err(chg, "failed to write USBIN_OPTIONS_1_CFG rc=%d\n", rc); return rc; } static int smblib_request_dpdm(struct smb_charger *chg, bool enable) { int rc = 0; Loading Loading @@ -2320,15 +2337,13 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, /* PD hard resets failed, rerun apsd */ if (chg->ok_to_pd) { chg->ok_to_pd = false; rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT); rc = smblib_configure_hvdcp_apsd(chg, true); if (rc < 0) { dev_err(chg->dev, "Couldn't disable APSD rc=%d\n", rc); "Couldn't enable APSD rc=%d\n", rc); return rc; } smblib_rerun_apsd(chg); smblib_rerun_apsd_if_required(chg); } } Loading Loading @@ -3003,7 +3018,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) * charger-mis-detection. */ chg->uusb_apsd_rerun_done = true; smblib_rerun_apsd(chg); smblib_rerun_apsd_if_required(chg); return IRQ_HANDLED; } Loading Loading @@ -3072,21 +3087,25 @@ static void typec_src_insertion(struct smb_charger *chg) chg->ok_to_pd = !(chg->typec_legacy || *chg->pd_disabled) || chg->early_usb_attach; if (!chg->ok_to_pd) { rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT); rc = smblib_configure_hvdcp_apsd(chg, true); if (rc < 0) { dev_err(chg->dev, "Couldn't disable APSD rc=%d\n", rc); "Couldn't enable APSD rc=%d\n", rc); return; } smblib_rerun_apsd(chg); smblib_rerun_apsd_if_required(chg); } } static void typec_sink_removal(struct smb_charger *chg) { vote(chg->usb_icl_votable, OTG_VOTER, false, 0); if (chg->use_extcon) { if (chg->otg_present) smblib_notify_usb_host(chg, false); chg->otg_present = false; } } static void typec_src_removal(struct smb_charger *chg) Loading @@ -3096,12 +3115,9 @@ static void typec_src_removal(struct smb_charger *chg) struct storm_watch *wdata; /* disable apsd */ rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, 0); rc = smblib_configure_hvdcp_apsd(chg, false); if (rc < 0) smblib_err(chg, "Couldn't disable APSD rc=%d\n", rc); smblib_err(chg, "Couldn't disable APSD rc=%d\n", rc); smblib_update_usb_type(chg); Loading Loading @@ -3158,14 +3174,9 @@ static void typec_src_removal(struct smb_charger *chg) smblib_err(chg, "Couldn't set USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V rc=%d\n", rc); if (chg->use_extcon) { if (chg->otg_present) smblib_notify_usb_host(chg, false); else if (chg->use_extcon) smblib_notify_device_mode(chg, false); } chg->otg_present = false; chg->typec_legacy = false; } Loading Loading @@ -3495,6 +3506,9 @@ static void smblib_uusb_otg_work(struct work_struct *work) otg = !!(stat & U_USB_GROUND_NOVBUS_BIT); if (chg->otg_present != otg) smblib_notify_usb_host(chg, otg); else goto out; chg->otg_present = otg; if (!otg) chg->boost_current_ua = 0; Loading drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -536,6 +536,7 @@ int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, int smblib_stat_sw_override_cfg(struct smb_charger *chg, bool override); int smblib_configure_wdog(struct smb_charger *chg, bool enable); int smblib_force_vbus_voltage(struct smb_charger *chg, u8 val); int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); Loading drivers/power/supply/qcom/smb5-reg.h +2 −2 Original line number Diff line number Diff line Loading @@ -283,7 +283,7 @@ enum { #define U_USB_GROUND_BIT BIT(4) #define TYPE_C_MODE_CFG_REG (TYPEC_BASE + 0x44) #define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 0) #define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 1) #define EN_SRC_ONLY_BIT BIT(2) #define EN_SNK_ONLY_BIT BIT(1) #define TYPEC_DISABLE_CMD_BIT BIT(0) Loading Loading @@ -327,7 +327,7 @@ enum { #define TYPEC_U_USB_CFG_REG (TYPEC_BASE + 0x70) #define EN_MICRO_USB_MODE_BIT BIT(0) #define TYPEC_MICRO_USB_MODE_REG (TYPEC_BASE + 0x70) #define TYPEC_MICRO_USB_MODE_REG (TYPEC_BASE + 0x73) #define MICRO_USB_MODE_ONLY_BIT BIT(0) /******************************** * MISC Peripheral Registers * Loading Loading
drivers/power/supply/qcom/qpnp-smb5.c +44 −10 Original line number Diff line number Diff line Loading @@ -243,6 +243,8 @@ static int smb5_chg_config_init(struct smb5 *chip) chg->param = smb5_pmi632_params; chg->use_extcon = true; chg->name = "pmi632_charger"; /* PMI632 does not support PD */ __pd_disabled = 1; chg->hw_max_icl_ua = (chip->dt.usb_icl_ua > 0) ? chip->dt.usb_icl_ua : PMI632_MAX_ICL_UA; Loading Loading @@ -1431,11 +1433,38 @@ static int smb5_init_vconn_regulator(struct smb5 *chip) static int smb5_configure_typec(struct smb_charger *chg) { int rc; u8 val = 0; rc = smblib_read(chg, LEGACY_CABLE_STATUS_REG, &val); if (rc < 0) { dev_err(chg->dev, "Couldn't read Legacy status rc=%d\n", rc); return rc; } /* * If Legacy cable is detected re-trigger Legacy detection * by disabling/enabling typeC mode. */ if (val & TYPEC_LEGACY_CABLE_STATUS_BIT) { rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_DISABLE_CMD_BIT, TYPEC_DISABLE_CMD_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't disable TYPEC rc=%d\n", rc); return rc; } /* delay before enabling typeC */ msleep(500); rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, TYPEC_DISABLE_CMD_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't enable TYPEC rc=%d\n", rc); return rc; } } /* disable apsd */ rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, 0); rc = smblib_configure_hvdcp_apsd(chg, false); if (rc < 0) { dev_err(chg->dev, "Couldn't disable APSD rc=%d\n", rc); return rc; Loading Loading @@ -1548,7 +1577,6 @@ static int smb5_init_hw(struct smb5 *chip) if (type) { chg->connector_type = POWER_SUPPLY_CONNECTOR_MICRO_USB; smblib_rerun_apsd_if_required(chg); rc = smb5_configure_micro_usb(chg); } else { chg->connector_type = POWER_SUPPLY_CONNECTOR_TYPEC; Loading @@ -1562,10 +1590,14 @@ static int smb5_init_hw(struct smb5 *chip) /* * PMI632 based hw init: * - Rerun APSD to ensure proper charger detection if device * boots with charger connected. * - Initialize flash module for PMI632 */ if (chg->smb_version == PMI632_SUBTYPE) if (chg->smb_version == PMI632_SUBTYPE) { schgm_flash_init(chg); smblib_rerun_apsd_if_required(chg); } /* vote 0mA on usb_icl for non battery platforms */ vote(chg->usb_icl_votable, Loading @@ -1589,14 +1621,16 @@ static int smb5_init_hw(struct smb5 *chip) /* * AICL configuration: * start from min and AICL ADC disable * AICL ADC disable */ if (chg->smb_version != PMI632_SUBTYPE) { rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG, USBIN_AICL_ADC_EN_BIT, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure AICL rc=%d\n", rc); dev_err(chg->dev, "Couldn't config AICL rc=%d\n", rc); return rc; } } /* enable the charging path */ rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0); Loading
drivers/power/supply/qcom/smb5-lib.c +37 −23 Original line number Diff line number Diff line Loading @@ -512,6 +512,23 @@ static int smblib_set_usb_pd_allowed_voltage(struct smb_charger *chg, /******************** * HELPER FUNCTIONS * ********************/ int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable) { int rc; u8 mask = HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT; if (chg->pd_disabled) return 0; rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, mask, enable ? mask : 0); if (rc < 0) smblib_err(chg, "failed to write USBIN_OPTIONS_1_CFG rc=%d\n", rc); return rc; } static int smblib_request_dpdm(struct smb_charger *chg, bool enable) { int rc = 0; Loading Loading @@ -2320,15 +2337,13 @@ int smblib_set_prop_pd_active(struct smb_charger *chg, /* PD hard resets failed, rerun apsd */ if (chg->ok_to_pd) { chg->ok_to_pd = false; rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT); rc = smblib_configure_hvdcp_apsd(chg, true); if (rc < 0) { dev_err(chg->dev, "Couldn't disable APSD rc=%d\n", rc); "Couldn't enable APSD rc=%d\n", rc); return rc; } smblib_rerun_apsd(chg); smblib_rerun_apsd_if_required(chg); } } Loading Loading @@ -3003,7 +3018,7 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) * charger-mis-detection. */ chg->uusb_apsd_rerun_done = true; smblib_rerun_apsd(chg); smblib_rerun_apsd_if_required(chg); return IRQ_HANDLED; } Loading Loading @@ -3072,21 +3087,25 @@ static void typec_src_insertion(struct smb_charger *chg) chg->ok_to_pd = !(chg->typec_legacy || *chg->pd_disabled) || chg->early_usb_attach; if (!chg->ok_to_pd) { rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT); rc = smblib_configure_hvdcp_apsd(chg, true); if (rc < 0) { dev_err(chg->dev, "Couldn't disable APSD rc=%d\n", rc); "Couldn't enable APSD rc=%d\n", rc); return; } smblib_rerun_apsd(chg); smblib_rerun_apsd_if_required(chg); } } static void typec_sink_removal(struct smb_charger *chg) { vote(chg->usb_icl_votable, OTG_VOTER, false, 0); if (chg->use_extcon) { if (chg->otg_present) smblib_notify_usb_host(chg, false); chg->otg_present = false; } } static void typec_src_removal(struct smb_charger *chg) Loading @@ -3096,12 +3115,9 @@ static void typec_src_removal(struct smb_charger *chg) struct storm_watch *wdata; /* disable apsd */ rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_EN_BIT | BC1P2_SRC_DETECT_BIT, 0); rc = smblib_configure_hvdcp_apsd(chg, false); if (rc < 0) smblib_err(chg, "Couldn't disable APSD rc=%d\n", rc); smblib_err(chg, "Couldn't disable APSD rc=%d\n", rc); smblib_update_usb_type(chg); Loading Loading @@ -3158,14 +3174,9 @@ static void typec_src_removal(struct smb_charger *chg) smblib_err(chg, "Couldn't set USBIN_ADAPTER_ALLOW_5V_OR_9V_TO_12V rc=%d\n", rc); if (chg->use_extcon) { if (chg->otg_present) smblib_notify_usb_host(chg, false); else if (chg->use_extcon) smblib_notify_device_mode(chg, false); } chg->otg_present = false; chg->typec_legacy = false; } Loading Loading @@ -3495,6 +3506,9 @@ static void smblib_uusb_otg_work(struct work_struct *work) otg = !!(stat & U_USB_GROUND_NOVBUS_BIT); if (chg->otg_present != otg) smblib_notify_usb_host(chg, otg); else goto out; chg->otg_present = otg; if (!otg) chg->boost_current_ua = 0; Loading
drivers/power/supply/qcom/smb5-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -536,6 +536,7 @@ int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, int smblib_stat_sw_override_cfg(struct smb_charger *chg, bool override); int smblib_configure_wdog(struct smb_charger *chg, bool enable); int smblib_force_vbus_voltage(struct smb_charger *chg, u8 val); int smblib_configure_hvdcp_apsd(struct smb_charger *chg, bool enable); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); Loading
drivers/power/supply/qcom/smb5-reg.h +2 −2 Original line number Diff line number Diff line Loading @@ -283,7 +283,7 @@ enum { #define U_USB_GROUND_BIT BIT(4) #define TYPE_C_MODE_CFG_REG (TYPEC_BASE + 0x44) #define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 0) #define TYPEC_POWER_ROLE_CMD_MASK GENMASK(2, 1) #define EN_SRC_ONLY_BIT BIT(2) #define EN_SNK_ONLY_BIT BIT(1) #define TYPEC_DISABLE_CMD_BIT BIT(0) Loading Loading @@ -327,7 +327,7 @@ enum { #define TYPEC_U_USB_CFG_REG (TYPEC_BASE + 0x70) #define EN_MICRO_USB_MODE_BIT BIT(0) #define TYPEC_MICRO_USB_MODE_REG (TYPEC_BASE + 0x70) #define TYPEC_MICRO_USB_MODE_REG (TYPEC_BASE + 0x73) #define MICRO_USB_MODE_ONLY_BIT BIT(0) /******************************** * MISC Peripheral Registers * Loading