Loading Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +12 −4 Original line number Diff line number Diff line Loading @@ -109,10 +109,18 @@ Charger specific properties: - qcom,auto-recharge-soc Usage: optional Value type: <empty> Definition: Specifies if automatic recharge needs to be based off battery SOC. If this property is not specified, then auto recharge will be based off battery voltage. Value type: <u32> Definition: Specifies the SOC threshold at which the charger will restart charging after termination. The value specified ranges from 0 - 100. The feature is enabled if this property is specified with a valid SOC value. - qcom,auto-recharge-vbat-mv Usage: optional Value type: <u32> Definition: Specifies the battery voltage threshold at which the charger will restart charging after termination. The value specified is in milli-volts. - qcom,suspend-input-on-debug-batt Usage: optional Loading drivers/power/supply/qcom/qpnp-smb5.c +78 −7 Original line number Diff line number Diff line Loading @@ -158,7 +158,8 @@ struct smb_dt_props { int chg_inhibit_thr_mv; bool no_battery; bool hvdcp_disable; bool auto_recharge_soc; int auto_recharge_soc; int auto_recharge_vbat_mv; int wd_bark_time; int batt_profile_fcc_ua; int batt_profile_fv_uv; Loading Loading @@ -329,8 +330,23 @@ static int smb5_parse_dt(struct smb5 *chip) return -EINVAL; } chip->dt.auto_recharge_soc = of_property_read_bool(node, "qcom,auto-recharge-soc"); chip->dt.auto_recharge_soc = -EINVAL; rc = of_property_read_u32(node, "qcom,auto-recharge-soc", &chip->dt.auto_recharge_soc); if (!rc && (chip->dt.auto_recharge_soc < 0 || chip->dt.auto_recharge_soc > 100)) { pr_err("qcom,auto-recharge-soc is incorrect\n"); return -EINVAL; } chg->auto_recharge_soc = chip->dt.auto_recharge_soc; chip->dt.auto_recharge_vbat_mv = -EINVAL; rc = of_property_read_u32(node, "qcom,auto-recharge-vbat-mv", &chip->dt.auto_recharge_vbat_mv); if (!rc && (chip->dt.auto_recharge_vbat_mv < 0)) { pr_err("qcom,auto-recharge-vbat-mv is incorrect\n"); return -EINVAL; } chg->dcp_icl_ua = chip->dt.usb_icl_ua; Loading Loading @@ -956,6 +972,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_RECHARGE_SOC, }; static int smb5_batt_get_prop(struct power_supply *psy, Loading Loading @@ -1045,6 +1062,9 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_COUNTER: rc = smblib_get_prop_batt_charge_counter(chg, val); break; case POWER_SUPPLY_PROP_RECHARGE_SOC: val->intval = chg->auto_recharge_soc; break; default: pr_err("batt power supply prop %d not supported\n", psp); return -EINVAL; Loading Loading @@ -1555,14 +1575,65 @@ static int smb5_init_hw(struct smb5 *chip) return rc; } rc = smblib_masked_write(chg, CHGR_CFG2_REG, SOC_BASED_RECHG_BIT, chip->dt.auto_recharge_soc ? SOC_BASED_RECHG_BIT : 0); rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK, (chip->dt.auto_recharge_vbat_mv != -EINVAL) ? VBAT_BASED_RECHG_BIT : 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure VBAT-rechg CHG_CFG2_REG rc=%d\n", rc); return rc; } /* program the auto-recharge VBAT threshold */ if (chip->dt.auto_recharge_vbat_mv != -EINVAL) { u32 temp = VBAT_TO_VRAW_ADC(chip->dt.auto_recharge_vbat_mv); temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8); rc = smblib_batch_write(chg, CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2); if (rc < 0) { dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n", rc); return rc; } /* Program the sample count for VBAT based recharge to 3 */ rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG, NO_OF_SAMPLE_FOR_RCHG, 2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT); if (rc < 0) { dev_err(chg->dev, "Couldn't configure FG_UPDATE_CFG2_SEL_REG rc=%d\n", dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n", rc); return rc; } } rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK, (chip->dt.auto_recharge_soc != -EINVAL) ? SOC_BASED_RECHG_BIT : VBAT_BASED_RECHG_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SOC-rechg CHG_CFG2_REG rc=%d\n", rc); return rc; } /* program the auto-recharge threshold */ if (chip->dt.auto_recharge_soc != -EINVAL) { rc = smblib_write(chg, CHARGE_RCHG_SOC_THRESHOLD_CFG_REG, (chip->dt.auto_recharge_soc * 255) / 100); if (rc < 0) { dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n", rc); return rc; } /* Program the sample count for SOC based recharge to 1 */ rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG, NO_OF_SAMPLE_FOR_RCHG, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n", rc); return rc; } } if (chg->sw_jeita_enabled) { rc = smblib_disable_hw_jeita(chg, true); Loading drivers/power/supply/qcom/smb5-lib.c +6 −2 Original line number Diff line number Diff line Loading @@ -62,11 +62,15 @@ int smblib_write(struct smb_charger *chg, u16 addr, u8 val) return regmap_write(chg->regmap, addr, val); } int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val) int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val, int count) { return regmap_bulk_write(chg->regmap, addr, val, count); } int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val) { return regmap_update_bits(chg->regmap, addr, mask, val); } int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) Loading drivers/power/supply/qcom/smb5-lib.h +5 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ enum print_reason { #define BOOST_BACK_STORM_COUNT 3 #define WEAK_CHG_STORM_COUNT 8 #define VBAT_TO_VRAW_ADC(v) div_u64((u64)v * 1000000UL, 194637UL) enum smb_mode { PARALLEL_MASTER = 0, PARALLEL_SLAVE, Loading Loading @@ -344,6 +346,7 @@ struct smb_charger { bool use_extcon; bool otg_present; int hw_max_icl_ua; int auto_recharge_soc; /* workaround flag */ u32 wa_flags; Loading Loading @@ -372,6 +375,8 @@ struct smb_charger { int smblib_read(struct smb_charger *chg, u16 addr, u8 *val); int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val); int smblib_write(struct smb_charger *chg, u16 addr, u8 val); int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val, int count); int smblib_batch_read(struct smb_charger *chg, u16 addr, u8 *val, int count); int smblib_get_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int *val_u); Loading drivers/power/supply/qcom/smb5-reg.h +13 −1 Original line number Diff line number Diff line Loading @@ -66,11 +66,17 @@ enum { #define CHARGING_ENABLE_CMD_BIT BIT(0) #define CHGR_CFG2_REG (CHGR_BASE + 0x51) #define SOC_BASED_RECHG_BIT BIT(1) #define RECHG_MASK GENMASK(2, 1) #define VBAT_BASED_RECHG_BIT BIT(2) #define SOC_BASED_RECHG_BIT GENMASK(2, 1) #define CHARGER_INHIBIT_BIT BIT(0) #define CHGR_FAST_CHARGE_CURRENT_CFG_REG (CHGR_BASE + 0x61) #define CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG (CHGR_BASE + 0x6B) #define NO_OF_SAMPLE_FOR_RCHG_SHIFT 2 #define NO_OF_SAMPLE_FOR_RCHG GENMASK(3, 2) #define CHGR_FLOAT_VOLTAGE_CFG_REG (CHGR_BASE + 0x70) #define CHARGE_INHIBIT_THRESHOLD_CFG_REG (CHGR_BASE + 0x72) Loading @@ -80,6 +86,12 @@ enum { #define INHIBIT_ANALOG_VFLT_MINUS_200MV 2 #define INHIBIT_ANALOG_VFLT_MINUS_300MV 3 #define CHARGE_RCHG_SOC_THRESHOLD_CFG_REG (CHGR_BASE + 0x7D) #define CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG (CHGR_BASE + 0x7E) #define CHGR_ADC_RECHARGE_THRESHOLD_LSB_REG (CHGR_BASE + 0x7F) #define JEITA_EN_CFG_REG (CHGR_BASE + 0x90) #define JEITA_EN_HOT_SL_FCV_BIT BIT(3) #define JEITA_EN_COLD_SL_FCV_BIT BIT(2) Loading Loading
Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt +12 −4 Original line number Diff line number Diff line Loading @@ -109,10 +109,18 @@ Charger specific properties: - qcom,auto-recharge-soc Usage: optional Value type: <empty> Definition: Specifies if automatic recharge needs to be based off battery SOC. If this property is not specified, then auto recharge will be based off battery voltage. Value type: <u32> Definition: Specifies the SOC threshold at which the charger will restart charging after termination. The value specified ranges from 0 - 100. The feature is enabled if this property is specified with a valid SOC value. - qcom,auto-recharge-vbat-mv Usage: optional Value type: <u32> Definition: Specifies the battery voltage threshold at which the charger will restart charging after termination. The value specified is in milli-volts. - qcom,suspend-input-on-debug-batt Usage: optional Loading
drivers/power/supply/qcom/qpnp-smb5.c +78 −7 Original line number Diff line number Diff line Loading @@ -158,7 +158,8 @@ struct smb_dt_props { int chg_inhibit_thr_mv; bool no_battery; bool hvdcp_disable; bool auto_recharge_soc; int auto_recharge_soc; int auto_recharge_vbat_mv; int wd_bark_time; int batt_profile_fcc_ua; int batt_profile_fv_uv; Loading Loading @@ -329,8 +330,23 @@ static int smb5_parse_dt(struct smb5 *chip) return -EINVAL; } chip->dt.auto_recharge_soc = of_property_read_bool(node, "qcom,auto-recharge-soc"); chip->dt.auto_recharge_soc = -EINVAL; rc = of_property_read_u32(node, "qcom,auto-recharge-soc", &chip->dt.auto_recharge_soc); if (!rc && (chip->dt.auto_recharge_soc < 0 || chip->dt.auto_recharge_soc > 100)) { pr_err("qcom,auto-recharge-soc is incorrect\n"); return -EINVAL; } chg->auto_recharge_soc = chip->dt.auto_recharge_soc; chip->dt.auto_recharge_vbat_mv = -EINVAL; rc = of_property_read_u32(node, "qcom,auto-recharge-vbat-mv", &chip->dt.auto_recharge_vbat_mv); if (!rc && (chip->dt.auto_recharge_vbat_mv < 0)) { pr_err("qcom,auto-recharge-vbat-mv is incorrect\n"); return -EINVAL; } chg->dcp_icl_ua = chip->dt.usb_icl_ua; Loading Loading @@ -956,6 +972,7 @@ static enum power_supply_property smb5_batt_props[] = { POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_RECHARGE_SOC, }; static int smb5_batt_get_prop(struct power_supply *psy, Loading Loading @@ -1045,6 +1062,9 @@ static int smb5_batt_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CHARGE_COUNTER: rc = smblib_get_prop_batt_charge_counter(chg, val); break; case POWER_SUPPLY_PROP_RECHARGE_SOC: val->intval = chg->auto_recharge_soc; break; default: pr_err("batt power supply prop %d not supported\n", psp); return -EINVAL; Loading Loading @@ -1555,14 +1575,65 @@ static int smb5_init_hw(struct smb5 *chip) return rc; } rc = smblib_masked_write(chg, CHGR_CFG2_REG, SOC_BASED_RECHG_BIT, chip->dt.auto_recharge_soc ? SOC_BASED_RECHG_BIT : 0); rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK, (chip->dt.auto_recharge_vbat_mv != -EINVAL) ? VBAT_BASED_RECHG_BIT : 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure VBAT-rechg CHG_CFG2_REG rc=%d\n", rc); return rc; } /* program the auto-recharge VBAT threshold */ if (chip->dt.auto_recharge_vbat_mv != -EINVAL) { u32 temp = VBAT_TO_VRAW_ADC(chip->dt.auto_recharge_vbat_mv); temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8); rc = smblib_batch_write(chg, CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2); if (rc < 0) { dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n", rc); return rc; } /* Program the sample count for VBAT based recharge to 3 */ rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG, NO_OF_SAMPLE_FOR_RCHG, 2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT); if (rc < 0) { dev_err(chg->dev, "Couldn't configure FG_UPDATE_CFG2_SEL_REG rc=%d\n", dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n", rc); return rc; } } rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK, (chip->dt.auto_recharge_soc != -EINVAL) ? SOC_BASED_RECHG_BIT : VBAT_BASED_RECHG_BIT); if (rc < 0) { dev_err(chg->dev, "Couldn't configure SOC-rechg CHG_CFG2_REG rc=%d\n", rc); return rc; } /* program the auto-recharge threshold */ if (chip->dt.auto_recharge_soc != -EINVAL) { rc = smblib_write(chg, CHARGE_RCHG_SOC_THRESHOLD_CFG_REG, (chip->dt.auto_recharge_soc * 255) / 100); if (rc < 0) { dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n", rc); return rc; } /* Program the sample count for SOC based recharge to 1 */ rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG, NO_OF_SAMPLE_FOR_RCHG, 0); if (rc < 0) { dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n", rc); return rc; } } if (chg->sw_jeita_enabled) { rc = smblib_disable_hw_jeita(chg, true); Loading
drivers/power/supply/qcom/smb5-lib.c +6 −2 Original line number Diff line number Diff line Loading @@ -62,11 +62,15 @@ int smblib_write(struct smb_charger *chg, u16 addr, u8 val) return regmap_write(chg->regmap, addr, val); } int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val) int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val, int count) { return regmap_bulk_write(chg->regmap, addr, val, count); } int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val) { return regmap_update_bits(chg->regmap, addr, mask, val); } int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua) Loading
drivers/power/supply/qcom/smb5-lib.h +5 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ enum print_reason { #define BOOST_BACK_STORM_COUNT 3 #define WEAK_CHG_STORM_COUNT 8 #define VBAT_TO_VRAW_ADC(v) div_u64((u64)v * 1000000UL, 194637UL) enum smb_mode { PARALLEL_MASTER = 0, PARALLEL_SLAVE, Loading Loading @@ -344,6 +346,7 @@ struct smb_charger { bool use_extcon; bool otg_present; int hw_max_icl_ua; int auto_recharge_soc; /* workaround flag */ u32 wa_flags; Loading Loading @@ -372,6 +375,8 @@ struct smb_charger { int smblib_read(struct smb_charger *chg, u16 addr, u8 *val); int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val); int smblib_write(struct smb_charger *chg, u16 addr, u8 val); int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val, int count); int smblib_batch_read(struct smb_charger *chg, u16 addr, u8 *val, int count); int smblib_get_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int *val_u); Loading
drivers/power/supply/qcom/smb5-reg.h +13 −1 Original line number Diff line number Diff line Loading @@ -66,11 +66,17 @@ enum { #define CHARGING_ENABLE_CMD_BIT BIT(0) #define CHGR_CFG2_REG (CHGR_BASE + 0x51) #define SOC_BASED_RECHG_BIT BIT(1) #define RECHG_MASK GENMASK(2, 1) #define VBAT_BASED_RECHG_BIT BIT(2) #define SOC_BASED_RECHG_BIT GENMASK(2, 1) #define CHARGER_INHIBIT_BIT BIT(0) #define CHGR_FAST_CHARGE_CURRENT_CFG_REG (CHGR_BASE + 0x61) #define CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG (CHGR_BASE + 0x6B) #define NO_OF_SAMPLE_FOR_RCHG_SHIFT 2 #define NO_OF_SAMPLE_FOR_RCHG GENMASK(3, 2) #define CHGR_FLOAT_VOLTAGE_CFG_REG (CHGR_BASE + 0x70) #define CHARGE_INHIBIT_THRESHOLD_CFG_REG (CHGR_BASE + 0x72) Loading @@ -80,6 +86,12 @@ enum { #define INHIBIT_ANALOG_VFLT_MINUS_200MV 2 #define INHIBIT_ANALOG_VFLT_MINUS_300MV 3 #define CHARGE_RCHG_SOC_THRESHOLD_CFG_REG (CHGR_BASE + 0x7D) #define CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG (CHGR_BASE + 0x7E) #define CHGR_ADC_RECHARGE_THRESHOLD_LSB_REG (CHGR_BASE + 0x7F) #define JEITA_EN_CFG_REG (CHGR_BASE + 0x90) #define JEITA_EN_HOT_SL_FCV_BIT BIT(3) #define JEITA_EN_COLD_SL_FCV_BIT BIT(2) Loading