Loading drivers/power/supply/qcom/qpnp-smbcharger.c +70 −25 Original line number Diff line number Diff line Loading @@ -288,7 +288,7 @@ struct smbchg_chip { struct votable *hw_aicl_rerun_disable_votable; struct votable *hw_aicl_rerun_enable_indirect_votable; struct votable *aicl_deglitch_short_votable; struct votable *hvdcp_enable_votable; /* extcon for VBUS / ID notification to USB */ struct extcon_dev *extcon; }; Loading Loading @@ -414,6 +414,10 @@ enum wake_reason { "VARB_WRKARND_SHORT_DEGLITCH_VOTER" /* QC 2.0 */ #define HVDCP_SHORT_DEGLITCH_VOTER "HVDCP_SHORT_DEGLITCH_VOTER" /* Hvdcp enable voters*/ #define HVDCP_PMIC_VOTER "HVDCP_PMIC_VOTER" #define HVDCP_OTG_VOTER "HVDCP_OTG_VOTER" #define HVDCP_PULSING_VOTER "HVDCP_PULSING_VOTER" static const unsigned int smbchg_extcon_cable[] = { EXTCON_USB, Loading Loading @@ -2436,6 +2440,27 @@ static int dc_suspend_vote_cb(struct votable *votable, return rc; } #define HVDCP_EN_BIT BIT(3) static int smbchg_hvdcp_enable_cb(struct votable *votable, void *data, int enable, const char *client) { int rc = 0; struct smbchg_chip *chip = data; pr_err("smbchg_hvdcp_enable_cb HVDCP %s\n", enable ? "enabled" : "disabled"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, enable ? HVDCP_EN_BIT : 0); if (rc < 0) dev_err(chip->dev, "Couldn't %s HVDCP rc=%d\n", enable ? "enable" : "disable", rc); return rc; } static int set_fastchg_current_vote_cb(struct votable *votable, void *data, int fcc_ma, Loading Loading @@ -3796,7 +3821,6 @@ struct regulator_ops smbchg_otg_reg_ops = { #define USBIN_ADAPTER_9V 0x3 #define USBIN_ADAPTER_5V_9V_CONT 0x2 #define USBIN_ADAPTER_5V_UNREGULATED_9V 0x5 #define HVDCP_EN_BIT BIT(3) static int smbchg_external_otg_regulator_enable(struct regulator_dev *rdev) { int rc = 0; Loading @@ -3820,9 +3844,7 @@ static int smbchg_external_otg_regulator_enable(struct regulator_dev *rdev) * allowance to 9V, so that the audio boost operating in reverse never * gets detected as a valid input */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, 0); rc = vote(chip->hvdcp_enable_votable, HVDCP_OTG_VOTER, true, 0); if (rc < 0) { dev_err(chip->dev, "Couldn't disable HVDCP rc=%d\n", rc); return rc; Loading Loading @@ -3856,9 +3878,7 @@ static int smbchg_external_otg_regulator_disable(struct regulator_dev *rdev) * value in order to allow normal USBs to be recognized as a valid * input. */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, HVDCP_EN_BIT); rc = vote(chip->hvdcp_enable_votable, HVDCP_OTG_VOTER, false, 1); if (rc < 0) { dev_err(chip->dev, "Couldn't enable HVDCP rc=%d\n", rc); return rc; Loading Loading @@ -4436,10 +4456,13 @@ static int smbchg_change_usb_supply_type(struct smbchg_chip *chip, goto out; } /* otherwise if it is unknown, set type after the vote */ if (type == POWER_SUPPLY_TYPE_UNKNOWN) /* otherwise if it is unknown, set type after removing the vote */ if (type == POWER_SUPPLY_TYPE_UNKNOWN) { rc = vote(chip->usb_icl_votable, PSY_ICL_VOTER, true, 0); if (rc < 0) pr_err("Couldn't vote for new USB ICL rc=%d\n", rc); chip->usb_supply_type = type; } /* * Update TYPE property to DCP for HVDCP/HVDCP3 charger types * so that they can be recongized as AC chargers by healthd. Loading Loading @@ -4578,9 +4601,7 @@ static void restore_from_hvdcp_detection(struct smbchg_chip *chip) pr_err("Couldn't configure HVDCP 9V rc=%d\n", rc); /* enable HVDCP */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, HVDCP_EN_BIT); rc = vote(chip->hvdcp_enable_votable, HVDCP_PULSING_VOTER, false, 1); if (rc < 0) pr_err("Couldn't enable HVDCP rc=%d\n", rc); Loading Loading @@ -4648,6 +4669,7 @@ static void handle_usb_removal(struct smbchg_chip *chip) chip->typec_current_ma = 0; /* cancel/wait for hvdcp pending work if any */ cancel_delayed_work_sync(&chip->hvdcp_det_work); smbchg_relax(chip, PM_DETECT_HVDCP); smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN); extcon_set_cable_state_(chip->extcon, EXTCON_USB, chip->usb_present); if (chip->dpdm_reg) Loading Loading @@ -5119,8 +5141,7 @@ static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip) /* disable HVDCP */ pr_smb(PR_MISC, "Disable HVDCP\n"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, 0); rc = vote(chip->hvdcp_enable_votable, HVDCP_PULSING_VOTER, true, 0); if (rc < 0) { pr_err("Couldn't disable HVDCP rc=%d\n", rc); goto out; Loading Loading @@ -5229,9 +5250,7 @@ static int smbchg_unprepare_for_pulsing(struct smbchg_chip *chip) /* enable HVDCP */ pr_smb(PR_MISC, "Enable HVDCP\n"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, HVDCP_EN_BIT); rc = vote(chip->hvdcp_enable_votable, HVDCP_PULSING_VOTER, false, 1); if (rc < 0) { pr_err("Couldn't enable HVDCP rc=%d\n", rc); return rc; Loading Loading @@ -6255,6 +6274,7 @@ static irqreturn_t fastchg_handler(int irq, void *_chip) struct smbchg_chip *chip = _chip; pr_smb(PR_INTERRUPT, "p2f triggered\n"); if (is_usb_present(chip) || is_dc_present(chip)) smbchg_parallel_usb_check_ok(chip); if (chip->batt_psy) power_supply_changed(chip->batt_psy); Loading Loading @@ -6868,7 +6888,22 @@ static int smbchg_hw_init(struct smbchg_chip *chip) chip->revision[ANA_MAJOR], chip->revision[ANA_MINOR]); /* Setup 9V HVDCP */ if (!chip->hvdcp_not_supported) { if (chip->hvdcp_not_supported) { rc = vote(chip->hvdcp_enable_votable, HVDCP_PMIC_VOTER, true, 0); if (rc < 0) { dev_err(chip->dev, "Couldn't disable HVDCP rc=%d\n", rc); return rc; } } else { rc = vote(chip->hvdcp_enable_votable, HVDCP_PMIC_VOTER, true, 1); if (rc < 0) { dev_err(chip->dev, "Couldn't enable HVDCP rc=%d\n", rc); return rc; } rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_ADAPTER_SEL_MASK, HVDCP_9V); Loading Loading @@ -8222,6 +8257,15 @@ static int smbchg_probe(struct platform_device *pdev) goto votables_cleanup; } chip->hvdcp_enable_votable = create_votable( "HVDCP_ENABLE", VOTE_MIN, smbchg_hvdcp_enable_cb, chip); if (IS_ERR(chip->hvdcp_enable_votable)) { rc = PTR_ERR(chip->hvdcp_enable_votable); goto votables_cleanup; } INIT_WORK(&chip->usb_set_online_work, smbchg_usb_update_online_work); INIT_DELAYED_WORK(&chip->parallel_en_work, smbchg_parallel_usb_en_work); Loading Loading @@ -8408,6 +8452,7 @@ static int smbchg_probe(struct platform_device *pdev) rerun_hvdcp_det_if_necessary(chip); update_usb_status(chip, is_usb_present(chip), false); dump_regs(chip); create_debugfs_entries(chip); dev_info(chip->dev, Loading Loading @@ -8504,11 +8549,9 @@ static void smbchg_shutdown(struct platform_device *pdev) disable_irq(chip->otg_oc_irq); disable_irq(chip->power_ok_irq); disable_irq(chip->recharge_irq); disable_irq(chip->src_detect_irq); disable_irq(chip->taper_irq); disable_irq(chip->usbid_change_irq); disable_irq(chip->usbin_ov_irq); disable_irq(chip->usbin_uv_irq); disable_irq(chip->vbat_low_irq); disable_irq(chip->wdog_timeout_irq); Loading Loading @@ -8551,8 +8594,7 @@ static void smbchg_shutdown(struct platform_device *pdev) /* disable HVDCP */ pr_smb(PR_MISC, "Disable HVDCP\n"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, 0); rc = vote(chip->hvdcp_enable_votable, HVDCP_PMIC_VOTER, true, 0); if (rc < 0) pr_err("Couldn't disable HVDCP rc=%d\n", rc); Loading @@ -8569,6 +8611,9 @@ static void smbchg_shutdown(struct platform_device *pdev) if (rc < 0) pr_err("Couldn't fake insertion rc=%d\n", rc); disable_irq(chip->src_detect_irq); disable_irq(chip->usbin_uv_irq); pr_smb(PR_MISC, "Wait 1S to settle\n"); msleep(1000); chip->hvdcp_3_det_ignore_uv = false; Loading Loading
drivers/power/supply/qcom/qpnp-smbcharger.c +70 −25 Original line number Diff line number Diff line Loading @@ -288,7 +288,7 @@ struct smbchg_chip { struct votable *hw_aicl_rerun_disable_votable; struct votable *hw_aicl_rerun_enable_indirect_votable; struct votable *aicl_deglitch_short_votable; struct votable *hvdcp_enable_votable; /* extcon for VBUS / ID notification to USB */ struct extcon_dev *extcon; }; Loading Loading @@ -414,6 +414,10 @@ enum wake_reason { "VARB_WRKARND_SHORT_DEGLITCH_VOTER" /* QC 2.0 */ #define HVDCP_SHORT_DEGLITCH_VOTER "HVDCP_SHORT_DEGLITCH_VOTER" /* Hvdcp enable voters*/ #define HVDCP_PMIC_VOTER "HVDCP_PMIC_VOTER" #define HVDCP_OTG_VOTER "HVDCP_OTG_VOTER" #define HVDCP_PULSING_VOTER "HVDCP_PULSING_VOTER" static const unsigned int smbchg_extcon_cable[] = { EXTCON_USB, Loading Loading @@ -2436,6 +2440,27 @@ static int dc_suspend_vote_cb(struct votable *votable, return rc; } #define HVDCP_EN_BIT BIT(3) static int smbchg_hvdcp_enable_cb(struct votable *votable, void *data, int enable, const char *client) { int rc = 0; struct smbchg_chip *chip = data; pr_err("smbchg_hvdcp_enable_cb HVDCP %s\n", enable ? "enabled" : "disabled"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, enable ? HVDCP_EN_BIT : 0); if (rc < 0) dev_err(chip->dev, "Couldn't %s HVDCP rc=%d\n", enable ? "enable" : "disable", rc); return rc; } static int set_fastchg_current_vote_cb(struct votable *votable, void *data, int fcc_ma, Loading Loading @@ -3796,7 +3821,6 @@ struct regulator_ops smbchg_otg_reg_ops = { #define USBIN_ADAPTER_9V 0x3 #define USBIN_ADAPTER_5V_9V_CONT 0x2 #define USBIN_ADAPTER_5V_UNREGULATED_9V 0x5 #define HVDCP_EN_BIT BIT(3) static int smbchg_external_otg_regulator_enable(struct regulator_dev *rdev) { int rc = 0; Loading @@ -3820,9 +3844,7 @@ static int smbchg_external_otg_regulator_enable(struct regulator_dev *rdev) * allowance to 9V, so that the audio boost operating in reverse never * gets detected as a valid input */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, 0); rc = vote(chip->hvdcp_enable_votable, HVDCP_OTG_VOTER, true, 0); if (rc < 0) { dev_err(chip->dev, "Couldn't disable HVDCP rc=%d\n", rc); return rc; Loading Loading @@ -3856,9 +3878,7 @@ static int smbchg_external_otg_regulator_disable(struct regulator_dev *rdev) * value in order to allow normal USBs to be recognized as a valid * input. */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, HVDCP_EN_BIT); rc = vote(chip->hvdcp_enable_votable, HVDCP_OTG_VOTER, false, 1); if (rc < 0) { dev_err(chip->dev, "Couldn't enable HVDCP rc=%d\n", rc); return rc; Loading Loading @@ -4436,10 +4456,13 @@ static int smbchg_change_usb_supply_type(struct smbchg_chip *chip, goto out; } /* otherwise if it is unknown, set type after the vote */ if (type == POWER_SUPPLY_TYPE_UNKNOWN) /* otherwise if it is unknown, set type after removing the vote */ if (type == POWER_SUPPLY_TYPE_UNKNOWN) { rc = vote(chip->usb_icl_votable, PSY_ICL_VOTER, true, 0); if (rc < 0) pr_err("Couldn't vote for new USB ICL rc=%d\n", rc); chip->usb_supply_type = type; } /* * Update TYPE property to DCP for HVDCP/HVDCP3 charger types * so that they can be recongized as AC chargers by healthd. Loading Loading @@ -4578,9 +4601,7 @@ static void restore_from_hvdcp_detection(struct smbchg_chip *chip) pr_err("Couldn't configure HVDCP 9V rc=%d\n", rc); /* enable HVDCP */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, HVDCP_EN_BIT); rc = vote(chip->hvdcp_enable_votable, HVDCP_PULSING_VOTER, false, 1); if (rc < 0) pr_err("Couldn't enable HVDCP rc=%d\n", rc); Loading Loading @@ -4648,6 +4669,7 @@ static void handle_usb_removal(struct smbchg_chip *chip) chip->typec_current_ma = 0; /* cancel/wait for hvdcp pending work if any */ cancel_delayed_work_sync(&chip->hvdcp_det_work); smbchg_relax(chip, PM_DETECT_HVDCP); smbchg_change_usb_supply_type(chip, POWER_SUPPLY_TYPE_UNKNOWN); extcon_set_cable_state_(chip->extcon, EXTCON_USB, chip->usb_present); if (chip->dpdm_reg) Loading Loading @@ -5119,8 +5141,7 @@ static int smbchg_prepare_for_pulsing(struct smbchg_chip *chip) /* disable HVDCP */ pr_smb(PR_MISC, "Disable HVDCP\n"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, 0); rc = vote(chip->hvdcp_enable_votable, HVDCP_PULSING_VOTER, true, 0); if (rc < 0) { pr_err("Couldn't disable HVDCP rc=%d\n", rc); goto out; Loading Loading @@ -5229,9 +5250,7 @@ static int smbchg_unprepare_for_pulsing(struct smbchg_chip *chip) /* enable HVDCP */ pr_smb(PR_MISC, "Enable HVDCP\n"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, HVDCP_EN_BIT); rc = vote(chip->hvdcp_enable_votable, HVDCP_PULSING_VOTER, false, 1); if (rc < 0) { pr_err("Couldn't enable HVDCP rc=%d\n", rc); return rc; Loading Loading @@ -6255,6 +6274,7 @@ static irqreturn_t fastchg_handler(int irq, void *_chip) struct smbchg_chip *chip = _chip; pr_smb(PR_INTERRUPT, "p2f triggered\n"); if (is_usb_present(chip) || is_dc_present(chip)) smbchg_parallel_usb_check_ok(chip); if (chip->batt_psy) power_supply_changed(chip->batt_psy); Loading Loading @@ -6868,7 +6888,22 @@ static int smbchg_hw_init(struct smbchg_chip *chip) chip->revision[ANA_MAJOR], chip->revision[ANA_MINOR]); /* Setup 9V HVDCP */ if (!chip->hvdcp_not_supported) { if (chip->hvdcp_not_supported) { rc = vote(chip->hvdcp_enable_votable, HVDCP_PMIC_VOTER, true, 0); if (rc < 0) { dev_err(chip->dev, "Couldn't disable HVDCP rc=%d\n", rc); return rc; } } else { rc = vote(chip->hvdcp_enable_votable, HVDCP_PMIC_VOTER, true, 1); if (rc < 0) { dev_err(chip->dev, "Couldn't enable HVDCP rc=%d\n", rc); return rc; } rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_ADAPTER_SEL_MASK, HVDCP_9V); Loading Loading @@ -8222,6 +8257,15 @@ static int smbchg_probe(struct platform_device *pdev) goto votables_cleanup; } chip->hvdcp_enable_votable = create_votable( "HVDCP_ENABLE", VOTE_MIN, smbchg_hvdcp_enable_cb, chip); if (IS_ERR(chip->hvdcp_enable_votable)) { rc = PTR_ERR(chip->hvdcp_enable_votable); goto votables_cleanup; } INIT_WORK(&chip->usb_set_online_work, smbchg_usb_update_online_work); INIT_DELAYED_WORK(&chip->parallel_en_work, smbchg_parallel_usb_en_work); Loading Loading @@ -8408,6 +8452,7 @@ static int smbchg_probe(struct platform_device *pdev) rerun_hvdcp_det_if_necessary(chip); update_usb_status(chip, is_usb_present(chip), false); dump_regs(chip); create_debugfs_entries(chip); dev_info(chip->dev, Loading Loading @@ -8504,11 +8549,9 @@ static void smbchg_shutdown(struct platform_device *pdev) disable_irq(chip->otg_oc_irq); disable_irq(chip->power_ok_irq); disable_irq(chip->recharge_irq); disable_irq(chip->src_detect_irq); disable_irq(chip->taper_irq); disable_irq(chip->usbid_change_irq); disable_irq(chip->usbin_ov_irq); disable_irq(chip->usbin_uv_irq); disable_irq(chip->vbat_low_irq); disable_irq(chip->wdog_timeout_irq); Loading Loading @@ -8551,8 +8594,7 @@ static void smbchg_shutdown(struct platform_device *pdev) /* disable HVDCP */ pr_smb(PR_MISC, "Disable HVDCP\n"); rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_EN_BIT, 0); rc = vote(chip->hvdcp_enable_votable, HVDCP_PMIC_VOTER, true, 0); if (rc < 0) pr_err("Couldn't disable HVDCP rc=%d\n", rc); Loading @@ -8569,6 +8611,9 @@ static void smbchg_shutdown(struct platform_device *pdev) if (rc < 0) pr_err("Couldn't fake insertion rc=%d\n", rc); disable_irq(chip->src_detect_irq); disable_irq(chip->usbin_uv_irq); pr_smb(PR_MISC, "Wait 1S to settle\n"); msleep(1000); chip->hvdcp_3_det_ignore_uv = false; Loading