Loading Documentation/devicetree/bindings/power/qpnp-smbcharger.txt +6 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ Parent node required properties: sub node devices. - #address-cells: Must be <1> - #size-cells: Must be <1> - qcom,pmic-revid: Should specify the phandle of PMIC revid module. This is used to identify the PMIC subtype. Sub node required properties: - reg: The SPMI address for this peripheral Loading Loading @@ -261,6 +266,7 @@ Optional Properties: - 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. - qcom,enable-hvdcp-9v A bool property to enable 9V HVDCP 2.0 detection. Example: qcom,qpnp-smbcharger { Loading arch/arm/boot/dts/qcom/msm-pmi8950.dtsi +2 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,8 @@ qcom,parallel-usb-min-current-ma = <1400>; qcom,parallel-usb-9v-min-current-ma = <900>; qcom,parallel-allowed-lowering-ma = <500>; qcom,enable-hvdcp-9v; qcom,pmic-revid = <&pmi8950_revid>; qcom,chgr@1000 { reg = <0x1000 0x100>; Loading arch/arm/boot/dts/qcom/msm-pmi8994.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,7 @@ qcom,parallel-usb-9v-min-current-ma = <900>; qcom,parallel-allowed-lowering-ma = <500>; qcom,autoadjust-vfloat; qcom,pmic-revid = <&pmi8994_revid>; qcom,chgr@1000 { reg = <0x1000 0x100>; Loading drivers/power/qpnp-smbcharger.c +93 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ struct smbchg_chip { bool cfg_chg_led_sw_ctrl; bool vbat_above_headroom; bool force_aicl_rerun; bool enable_hvdcp_9v; u8 original_usbin_allowance; struct parallel_usb_cfg parallel; struct delayed_work parallel_en_work; Loading Loading @@ -170,6 +171,7 @@ struct smbchg_chip { const char *battery_type; bool very_weak_charger; bool parallel_charger_detected; u32 wa_flags; /* jeita and temperature */ bool batt_hot; Loading Loading @@ -254,6 +256,16 @@ static char *version_str[] = { [QPNP_SCHG_LITE] = "SCHG_LITE", }; enum pmic_subtype { PMI8994 = 10, PMI8950 = 17, }; enum smbchg_wa { SMBCHG_AICL_DEGLITCH_WA = BIT(0), SMBCHG_HVDCP_9V_EN_WA = BIT(1), }; enum print_reason { PR_REGISTER = BIT(0), PR_INTERRUPT = BIT(1), Loading Loading @@ -2931,6 +2943,9 @@ static void smbchg_aicl_deglitch_wa_check(struct smbchg_chip *chip) u8 reg; bool low_volt_chgr = true; if (!(chip->wa_flags & SMBCHG_AICL_DEGLITCH_WA)) return; if (!is_usb_present(chip) && !is_dc_present(chip)) { pr_smb(PR_STATUS, "Charger removed\n"); smbchg_aicl_deglitch_wa_en(chip, false); Loading Loading @@ -5569,6 +5584,11 @@ static inline int get_bpd(const char *name) #define AICL_WL_SEL_45S 0 #define CHGR_CCMP_CFG 0xFA #define JEITA_TEMP_HARD_LIMIT_BIT BIT(5) #define HVDCP_ADAPTER_SEL_MASK SMB_MASK(5, 4) #define HVDCP_ADAPTER_SEL_9V_BIT BIT(4) #define HVDCP_AUTH_ALG_EN_BIT BIT(6) #define CMD_APSD 0x41 #define APSD_RERUN_BIT BIT(0) static int smbchg_hw_init(struct smbchg_chip *chip) { int rc, i; Loading Loading @@ -5624,6 +5644,33 @@ static int smbchg_hw_init(struct smbchg_chip *chip) return rc; } if (chip->enable_hvdcp_9v && (chip->wa_flags & SMBCHG_HVDCP_9V_EN_WA)) { /* enable the 9V HVDCP configuration */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + TR_RID_REG, HVDCP_AUTH_ALG_EN_BIT, HVDCP_AUTH_ALG_EN_BIT); if (rc) { dev_err(chip->dev, "Couldn't enable hvdcp_alg rc=%d\n", rc); return rc; } rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_ADAPTER_SEL_MASK, HVDCP_ADAPTER_SEL_9V_BIT); if (rc) { dev_err(chip->dev, "Couldn't set hvdcp config in chgpath_chg rc=%d\n", rc); return rc; } if (is_usb_present(chip)) { rc = smbchg_masked_write(chip, chip->usb_chgpth_base + CMD_APSD, APSD_RERUN_BIT, APSD_RERUN_BIT); if (rc) pr_err("Unable to re-run APSD rc=%d\n", rc); } } /* * set chg en by cmd register, set chg en by writing bit 1, * enable auto pre to fast, enable auto recharge by default. Loading Loading @@ -6138,6 +6185,8 @@ static int smb_parse_dt(struct smbchg_chip *chip) "qcom,low-volt-dcin"); chip->force_aicl_rerun = of_property_read_bool(node, "qcom,force-aicl-rerun"); chip->enable_hvdcp_9v = of_property_read_bool(node, "qcom,enable-hvdcp-9v"); /* parse the battery missing detection pin source */ rc = of_property_read_string(chip->spmi->dev.of_node, Loading Loading @@ -6555,6 +6604,46 @@ static int create_debugfs_entries(struct smbchg_chip *chip) return 0; } static int smbchg_wa_config(struct smbchg_chip *chip) { struct pmic_revid_data *pmic_rev_id; struct device_node *revid_dev_node; int rc; revid_dev_node = of_parse_phandle(chip->spmi->dev.of_node, "qcom,pmic-revid", 0); if (!revid_dev_node) { pr_err("Missing qcom,pmic-revid property - driver failed\n"); return -EINVAL; } pmic_rev_id = get_revid_data(revid_dev_node); if (IS_ERR(pmic_rev_id)) { rc = PTR_ERR(revid_dev_node); if (rc != -EPROBE_DEFER) pr_err("Unable to get pmic_revid rc=%d\n", rc); return rc; } switch (pmic_rev_id->pmic_subtype) { case PMI8994: chip->wa_flags |= SMBCHG_AICL_DEGLITCH_WA; case PMI8950: if (pmic_rev_id->rev4 < 2) /* PMI8950 1.0 */ chip->wa_flags |= SMBCHG_AICL_DEGLITCH_WA; else /* rev > PMI8950 v1.0 */ chip->wa_flags |= SMBCHG_HVDCP_9V_EN_WA; break; default: pr_err("PMIC subtype %d not supported, WA flags not set\n", pmic_rev_id->pmic_subtype); } pr_debug("wa_flags=0x%x\n", chip->wa_flags); return 0; } static int smbchg_check_chg_version(struct smbchg_chip *chip) { int rc; Loading Loading @@ -6583,6 +6672,10 @@ static int smbchg_check_chg_version(struct smbchg_chip *chip) break; } rc = smbchg_wa_config(chip); if (rc != -EPROBE_DEFER) pr_err("Charger WA flags not configured rc=%d\n", rc); return rc; } Loading Loading
Documentation/devicetree/bindings/power/qpnp-smbcharger.txt +6 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ Parent node required properties: sub node devices. - #address-cells: Must be <1> - #size-cells: Must be <1> - qcom,pmic-revid: Should specify the phandle of PMIC revid module. This is used to identify the PMIC subtype. Sub node required properties: - reg: The SPMI address for this peripheral Loading Loading @@ -261,6 +266,7 @@ Optional Properties: - 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. - qcom,enable-hvdcp-9v A bool property to enable 9V HVDCP 2.0 detection. Example: qcom,qpnp-smbcharger { Loading
arch/arm/boot/dts/qcom/msm-pmi8950.dtsi +2 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,8 @@ qcom,parallel-usb-min-current-ma = <1400>; qcom,parallel-usb-9v-min-current-ma = <900>; qcom,parallel-allowed-lowering-ma = <500>; qcom,enable-hvdcp-9v; qcom,pmic-revid = <&pmi8950_revid>; qcom,chgr@1000 { reg = <0x1000 0x100>; Loading
arch/arm/boot/dts/qcom/msm-pmi8994.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,7 @@ qcom,parallel-usb-9v-min-current-ma = <900>; qcom,parallel-allowed-lowering-ma = <500>; qcom,autoadjust-vfloat; qcom,pmic-revid = <&pmi8994_revid>; qcom,chgr@1000 { reg = <0x1000 0x100>; Loading
drivers/power/qpnp-smbcharger.c +93 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ struct smbchg_chip { bool cfg_chg_led_sw_ctrl; bool vbat_above_headroom; bool force_aicl_rerun; bool enable_hvdcp_9v; u8 original_usbin_allowance; struct parallel_usb_cfg parallel; struct delayed_work parallel_en_work; Loading Loading @@ -170,6 +171,7 @@ struct smbchg_chip { const char *battery_type; bool very_weak_charger; bool parallel_charger_detected; u32 wa_flags; /* jeita and temperature */ bool batt_hot; Loading Loading @@ -254,6 +256,16 @@ static char *version_str[] = { [QPNP_SCHG_LITE] = "SCHG_LITE", }; enum pmic_subtype { PMI8994 = 10, PMI8950 = 17, }; enum smbchg_wa { SMBCHG_AICL_DEGLITCH_WA = BIT(0), SMBCHG_HVDCP_9V_EN_WA = BIT(1), }; enum print_reason { PR_REGISTER = BIT(0), PR_INTERRUPT = BIT(1), Loading Loading @@ -2931,6 +2943,9 @@ static void smbchg_aicl_deglitch_wa_check(struct smbchg_chip *chip) u8 reg; bool low_volt_chgr = true; if (!(chip->wa_flags & SMBCHG_AICL_DEGLITCH_WA)) return; if (!is_usb_present(chip) && !is_dc_present(chip)) { pr_smb(PR_STATUS, "Charger removed\n"); smbchg_aicl_deglitch_wa_en(chip, false); Loading Loading @@ -5569,6 +5584,11 @@ static inline int get_bpd(const char *name) #define AICL_WL_SEL_45S 0 #define CHGR_CCMP_CFG 0xFA #define JEITA_TEMP_HARD_LIMIT_BIT BIT(5) #define HVDCP_ADAPTER_SEL_MASK SMB_MASK(5, 4) #define HVDCP_ADAPTER_SEL_9V_BIT BIT(4) #define HVDCP_AUTH_ALG_EN_BIT BIT(6) #define CMD_APSD 0x41 #define APSD_RERUN_BIT BIT(0) static int smbchg_hw_init(struct smbchg_chip *chip) { int rc, i; Loading Loading @@ -5624,6 +5644,33 @@ static int smbchg_hw_init(struct smbchg_chip *chip) return rc; } if (chip->enable_hvdcp_9v && (chip->wa_flags & SMBCHG_HVDCP_9V_EN_WA)) { /* enable the 9V HVDCP configuration */ rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + TR_RID_REG, HVDCP_AUTH_ALG_EN_BIT, HVDCP_AUTH_ALG_EN_BIT); if (rc) { dev_err(chip->dev, "Couldn't enable hvdcp_alg rc=%d\n", rc); return rc; } rc = smbchg_sec_masked_write(chip, chip->usb_chgpth_base + CHGPTH_CFG, HVDCP_ADAPTER_SEL_MASK, HVDCP_ADAPTER_SEL_9V_BIT); if (rc) { dev_err(chip->dev, "Couldn't set hvdcp config in chgpath_chg rc=%d\n", rc); return rc; } if (is_usb_present(chip)) { rc = smbchg_masked_write(chip, chip->usb_chgpth_base + CMD_APSD, APSD_RERUN_BIT, APSD_RERUN_BIT); if (rc) pr_err("Unable to re-run APSD rc=%d\n", rc); } } /* * set chg en by cmd register, set chg en by writing bit 1, * enable auto pre to fast, enable auto recharge by default. Loading Loading @@ -6138,6 +6185,8 @@ static int smb_parse_dt(struct smbchg_chip *chip) "qcom,low-volt-dcin"); chip->force_aicl_rerun = of_property_read_bool(node, "qcom,force-aicl-rerun"); chip->enable_hvdcp_9v = of_property_read_bool(node, "qcom,enable-hvdcp-9v"); /* parse the battery missing detection pin source */ rc = of_property_read_string(chip->spmi->dev.of_node, Loading Loading @@ -6555,6 +6604,46 @@ static int create_debugfs_entries(struct smbchg_chip *chip) return 0; } static int smbchg_wa_config(struct smbchg_chip *chip) { struct pmic_revid_data *pmic_rev_id; struct device_node *revid_dev_node; int rc; revid_dev_node = of_parse_phandle(chip->spmi->dev.of_node, "qcom,pmic-revid", 0); if (!revid_dev_node) { pr_err("Missing qcom,pmic-revid property - driver failed\n"); return -EINVAL; } pmic_rev_id = get_revid_data(revid_dev_node); if (IS_ERR(pmic_rev_id)) { rc = PTR_ERR(revid_dev_node); if (rc != -EPROBE_DEFER) pr_err("Unable to get pmic_revid rc=%d\n", rc); return rc; } switch (pmic_rev_id->pmic_subtype) { case PMI8994: chip->wa_flags |= SMBCHG_AICL_DEGLITCH_WA; case PMI8950: if (pmic_rev_id->rev4 < 2) /* PMI8950 1.0 */ chip->wa_flags |= SMBCHG_AICL_DEGLITCH_WA; else /* rev > PMI8950 v1.0 */ chip->wa_flags |= SMBCHG_HVDCP_9V_EN_WA; break; default: pr_err("PMIC subtype %d not supported, WA flags not set\n", pmic_rev_id->pmic_subtype); } pr_debug("wa_flags=0x%x\n", chip->wa_flags); return 0; } static int smbchg_check_chg_version(struct smbchg_chip *chip) { int rc; Loading Loading @@ -6583,6 +6672,10 @@ static int smbchg_check_chg_version(struct smbchg_chip *chip) break; } rc = smbchg_wa_config(chip); if (rc != -EPROBE_DEFER) pr_err("Charger WA flags not configured rc=%d\n", rc); return rc; } Loading