Loading Documentation/devicetree/bindings/power/qpnp-smbcharger.txt +3 −0 Original line number Diff line number Diff line Loading @@ -258,6 +258,9 @@ Optional Properties: - qcom,chg-led-support A bool property to support the charger led feature. - qcom,chg-led-sw-controls A bool property to allow the software to control the charger led without a valid charger. - qcom,skip-usb-notification A boolean property to be used when usb gets present and type from other means. Especially true on liquid hardware, where usb presence is detected based on GPIO. Example: qcom,qpnp-smbcharger { Loading drivers/power/qpnp-smbcharger.c +57 −40 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ struct smbchg_chip { struct completion usbin_uv_raised; int pulse_cnt; struct led_classdev led_cdev; bool skip_usb_notification; }; enum qpnp_schg { Loading Loading @@ -3833,10 +3834,12 @@ static void smbchg_hvdcp_det_work(struct work_struct *work) struct smbchg_chip, hvdcp_det_work.work); if (is_hvdcp_present(chip)) { if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_USB_HVDCP); power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB_HVDCP); } if (chip->psy_registered) power_supply_changed(&chip->batt_psy); smbchg_aicl_deglitch_wa_check(chip); Loading Loading @@ -3926,7 +3929,7 @@ static void handle_usb_removal(struct smbchg_chip *chip) /* Clear the OV detected status set before */ if (chip->usb_ov_det) chip->usb_ov_det = false; if (chip->usb_psy) { if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_UNKNOWN); power_supply_set_supply_type(chip->usb_psy, Loading @@ -3934,16 +3937,17 @@ static void handle_usb_removal(struct smbchg_chip *chip) pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); } set_usb_psy_dp_dm(chip, POWER_SUPPLY_DP_DM_DPR_DMR); schedule_work(&chip->usb_set_online_work); pr_smb(PR_MISC, "setting usb psy health UNKNOWN\n"); rc = power_supply_set_health_state(chip->usb_psy, POWER_SUPPLY_HEALTH_UNKNOWN); if (rc) if (rc < 0) pr_smb(PR_STATUS, "usb psy does not allow updating prop %d rc = %d\n", POWER_SUPPLY_HEALTH_UNKNOWN, rc); } if (parallel_psy && chip->parallel_charger_detected) power_supply_set_present(parallel_psy, false); if (chip->parallel.avail && chip->aicl_done_irq Loading Loading @@ -4005,13 +4009,15 @@ static void handle_usb_insertion(struct smbchg_chip *chip) "inserted type = %d (%s)", usb_supply_type, usb_type_name); smbchg_aicl_deglitch_wa_check(chip); if (chip->usb_psy) { if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy type = %d\n", usb_supply_type); power_supply_set_supply_type(chip->usb_psy, usb_supply_type); pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); } /* Notify the USB psy if OV condition is not present */ if (!chip->usb_ov_det) { /* Loading @@ -4026,13 +4032,12 @@ static void handle_usb_insertion(struct smbchg_chip *chip) chip->very_weak_charger ? POWER_SUPPLY_HEALTH_UNSPEC_FAILURE : POWER_SUPPLY_HEALTH_GOOD); if (rc) if (rc < 0) pr_smb(PR_STATUS, "usb psy does not allow updating prop %d rc = %d\n", POWER_SUPPLY_HEALTH_GOOD, rc); } schedule_work(&chip->usb_set_online_work); } if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP) schedule_delayed_work(&chip->hvdcp_det_work, Loading Loading @@ -4593,8 +4598,10 @@ static int smbchg_hvdcp3_confirmed(struct smbchg_chip *chip) pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_USB_HVDCP_3); if (!chip->skip_usb_notification) { power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB_HVDCP_3); } return 0; } Loading Loading @@ -5458,10 +5465,14 @@ static int determine_initial_status(struct smbchg_chip *chip) chip->usb_present = is_usb_present(chip); chip->dc_present = is_dc_present(chip); if (chip->usb_present) if (chip->usb_present) { pr_smb(PR_MISC, "setting usb psy dp=f dm=f\n"); power_supply_set_dp_dm(chip->usb_psy, POWER_SUPPLY_DP_DM_DPF_DMF); handle_usb_insertion(chip); else } else { handle_usb_removal(chip); } return 0; } Loading Loading @@ -6213,6 +6224,9 @@ static int smb_parse_dt(struct smbchg_chip *chip) } } chip->skip_usb_notification = of_property_read_bool(node, "qcom,skip-usb-notification"); return 0; } Loading Loading @@ -6732,8 +6746,11 @@ static int smbchg_probe(struct spmi_device *spmi) goto unregister_led_class; } pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); } dump_regs(chip); create_debugfs_entries(chip); Loading Loading
Documentation/devicetree/bindings/power/qpnp-smbcharger.txt +3 −0 Original line number Diff line number Diff line Loading @@ -258,6 +258,9 @@ Optional Properties: - qcom,chg-led-support A bool property to support the charger led feature. - qcom,chg-led-sw-controls A bool property to allow the software to control the charger led without a valid charger. - qcom,skip-usb-notification A boolean property to be used when usb gets present and type from other means. Especially true on liquid hardware, where usb presence is detected based on GPIO. Example: qcom,qpnp-smbcharger { Loading
drivers/power/qpnp-smbcharger.c +57 −40 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ struct smbchg_chip { struct completion usbin_uv_raised; int pulse_cnt; struct led_classdev led_cdev; bool skip_usb_notification; }; enum qpnp_schg { Loading Loading @@ -3833,10 +3834,12 @@ static void smbchg_hvdcp_det_work(struct work_struct *work) struct smbchg_chip, hvdcp_det_work.work); if (is_hvdcp_present(chip)) { if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_USB_HVDCP); power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB_HVDCP); } if (chip->psy_registered) power_supply_changed(&chip->batt_psy); smbchg_aicl_deglitch_wa_check(chip); Loading Loading @@ -3926,7 +3929,7 @@ static void handle_usb_removal(struct smbchg_chip *chip) /* Clear the OV detected status set before */ if (chip->usb_ov_det) chip->usb_ov_det = false; if (chip->usb_psy) { if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_UNKNOWN); power_supply_set_supply_type(chip->usb_psy, Loading @@ -3934,16 +3937,17 @@ static void handle_usb_removal(struct smbchg_chip *chip) pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); } set_usb_psy_dp_dm(chip, POWER_SUPPLY_DP_DM_DPR_DMR); schedule_work(&chip->usb_set_online_work); pr_smb(PR_MISC, "setting usb psy health UNKNOWN\n"); rc = power_supply_set_health_state(chip->usb_psy, POWER_SUPPLY_HEALTH_UNKNOWN); if (rc) if (rc < 0) pr_smb(PR_STATUS, "usb psy does not allow updating prop %d rc = %d\n", POWER_SUPPLY_HEALTH_UNKNOWN, rc); } if (parallel_psy && chip->parallel_charger_detected) power_supply_set_present(parallel_psy, false); if (chip->parallel.avail && chip->aicl_done_irq Loading Loading @@ -4005,13 +4009,15 @@ static void handle_usb_insertion(struct smbchg_chip *chip) "inserted type = %d (%s)", usb_supply_type, usb_type_name); smbchg_aicl_deglitch_wa_check(chip); if (chip->usb_psy) { if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy type = %d\n", usb_supply_type); power_supply_set_supply_type(chip->usb_psy, usb_supply_type); pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); } /* Notify the USB psy if OV condition is not present */ if (!chip->usb_ov_det) { /* Loading @@ -4026,13 +4032,12 @@ static void handle_usb_insertion(struct smbchg_chip *chip) chip->very_weak_charger ? POWER_SUPPLY_HEALTH_UNSPEC_FAILURE : POWER_SUPPLY_HEALTH_GOOD); if (rc) if (rc < 0) pr_smb(PR_STATUS, "usb psy does not allow updating prop %d rc = %d\n", POWER_SUPPLY_HEALTH_GOOD, rc); } schedule_work(&chip->usb_set_online_work); } if (usb_supply_type == POWER_SUPPLY_TYPE_USB_DCP) schedule_delayed_work(&chip->hvdcp_det_work, Loading Loading @@ -4593,8 +4598,10 @@ static int smbchg_hvdcp3_confirmed(struct smbchg_chip *chip) pr_smb(PR_MISC, "setting usb psy type = %d\n", POWER_SUPPLY_TYPE_USB_HVDCP_3); if (!chip->skip_usb_notification) { power_supply_set_supply_type(chip->usb_psy, POWER_SUPPLY_TYPE_USB_HVDCP_3); } return 0; } Loading Loading @@ -5458,10 +5465,14 @@ static int determine_initial_status(struct smbchg_chip *chip) chip->usb_present = is_usb_present(chip); chip->dc_present = is_dc_present(chip); if (chip->usb_present) if (chip->usb_present) { pr_smb(PR_MISC, "setting usb psy dp=f dm=f\n"); power_supply_set_dp_dm(chip->usb_psy, POWER_SUPPLY_DP_DM_DPF_DMF); handle_usb_insertion(chip); else } else { handle_usb_removal(chip); } return 0; } Loading Loading @@ -6213,6 +6224,9 @@ static int smb_parse_dt(struct smbchg_chip *chip) } } chip->skip_usb_notification = of_property_read_bool(node, "qcom,skip-usb-notification"); return 0; } Loading Loading @@ -6732,8 +6746,11 @@ static int smbchg_probe(struct spmi_device *spmi) goto unregister_led_class; } pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); if (!chip->skip_usb_notification) { pr_smb(PR_MISC, "setting usb psy present = %d\n", chip->usb_present); power_supply_set_present(chip->usb_psy, chip->usb_present); } dump_regs(chip); create_debugfs_entries(chip); Loading