Loading Documentation/devicetree/bindings/power/qpnp-linear-charger.txt +7 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,13 @@ Parent node optional properties: If not specified charger driver depends on BMSfor end-of-charge detection. - qcom,disable-vbatdet-based-recharge If specified disable VBATDET irq and charging can only be resumed if charger is re-inserted or SOC falls below resume SOC. This property should always be used along with the BMS property: "qcom,disable-suspend-on-usb". - qcom,use-external-charger If specifed the LBC module will be disabled and the driver will not register. It also enables BID for Loading Documentation/devicetree/bindings/power/qpnp-vm-bms.txt +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ Parent node Optional properties the fifo_update_done interrupt. Possible values- 0 to 8 - qcom,force-s3-on-suspend : Bool property to force the BMS into S3 (sleep) state while entering into system suspend. - qcom,force-bms-active-on-charger: Bool property to keep BMS FSM active if charger is present. - qcom,report-charger-eoc : Bool property to indicate if BMS needs to indicate EOC to charger. - qcom,ignore-shutdown-soc: A boolean that controls whether BMS will Loading drivers/power/qpnp-linear-charger.c +26 −11 Original line number Diff line number Diff line Loading @@ -266,6 +266,8 @@ struct vddtrim_map vddtrim_map[] = { * @cfg_float_charge: enable float charging * @charger_disabled: maintain USB path state. * @cfg_charger_detect_eoc: charger can detect end of charging * @cfg_disable_vbatdet_based_recharge: keep VBATDET comparator overriden to * low and VBATDET irq disabled. * @cfg_safe_current: battery safety current setting * @cfg_hot_batt_p: hot battery threshold setting * @cfg_cold_batt_p: eold battery threshold setting Loading Loading @@ -323,6 +325,7 @@ struct qpnp_lbc_chip { unsigned int cfg_max_voltage_mv; unsigned int cfg_min_voltage_mv; unsigned int cfg_charger_detect_eoc; unsigned int cfg_disable_vbatdet_based_recharge; unsigned int cfg_batt_weak_voltage_uv; unsigned int cfg_warm_bat_mv; unsigned int cfg_cool_bat_mv; Loading Loading @@ -1145,6 +1148,7 @@ static int get_prop_capacity(struct qpnp_lbc_chip *chip) && ret.intval <= chip->cfg_soc_resume_limit) { pr_debug("resuming charging at %d%% soc\n", ret.intval); if (!chip->cfg_disable_vbatdet_based_recharge) qpnp_lbc_vbatdet_override(chip, OVERRIDE_0); qpnp_lbc_charger_enable(chip, SOC, 1); } Loading Loading @@ -1419,11 +1423,7 @@ static int qpnp_batt_power_set_property(struct power_supply *psy, if (val->intval == POWER_SUPPLY_STATUS_FULL && !chip->cfg_float_charge) { mutex_lock(&chip->chg_enable_lock); /* No override for VBAT_DET_LO comp */ rc = qpnp_lbc_vbatdet_override(chip, OVERRIDE_NONE); if (rc) pr_err("Failed to override VBAT_DET rc=%d\n", rc); /* Disable charging */ rc = qpnp_lbc_charger_enable(chip, SOC, 0); if (rc) Loading @@ -1437,8 +1437,17 @@ static int qpnp_batt_power_set_property(struct power_supply *psy, * To enable charging when VBAT falls below VBAT_DET * and device stays suspended after EOC. */ if (!chip->cfg_disable_vbatdet_based_recharge) { /* No override for VBAT_DET_LO comp */ rc = qpnp_lbc_vbatdet_override(chip, OVERRIDE_NONE); if (rc) pr_err("Failed to override VBAT_DET rc=%d\n", rc); else qpnp_lbc_enable_irq(chip, &chip->irqs[CHG_VBAT_DET_LO]); } mutex_unlock(&chip->chg_enable_lock); } Loading Loading @@ -1916,6 +1925,10 @@ static int qpnp_charger_read_dt_props(struct qpnp_lbc_chip *chip) of_property_read_bool(chip->spmi->dev.of_node, "qcom,charger-detect-eoc"); /* Get the vbatdet disable property */ chip->cfg_disable_vbatdet_based_recharge = of_property_read_bool(chip->spmi->dev.of_node, "qcom,disable-vbatdet-based-recharge"); /* Disable charging when faking battery values */ if (chip->cfg_use_fake_battery) chip->cfg_charging_disabled = true; Loading Loading @@ -1972,6 +1985,7 @@ static irqreturn_t qpnp_lbc_usbin_valid_irq_handler(int irq, void *_chip) * Override VBAT_DET comparator to start charging * even if VBAT > VBAT_DET. */ if (!chip->cfg_disable_vbatdet_based_recharge) qpnp_lbc_vbatdet_override(chip, OVERRIDE_0); /* Loading Loading @@ -2294,10 +2308,11 @@ static int qpnp_lbc_get_irqs(struct qpnp_lbc_chip *chip, u8 subtype, case LBC_CHGR_SUBTYPE: SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_FAST_CHG, fast-chg-on); SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_VBAT_DET_LO, vbat-det-lo); SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_FAILED, chg-failed); if (!chip->cfg_disable_vbatdet_based_recharge) SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_VBAT_DET_LO, vbat-det-lo); if (chip->cfg_charger_detect_eoc) SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_DONE, chg-done); Loading drivers/power/qpnp-vm-bms.c +37 −6 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ struct bms_wakeup_source { struct bms_dt_cfg { bool cfg_report_charger_eoc; bool cfg_force_bms_active_on_charger; bool cfg_force_s3_on_suspend; bool cfg_ignore_shutdown_soc; bool cfg_use_voltage_soc; Loading Loading @@ -233,6 +234,7 @@ struct qpnp_bms_chip { struct bms_irq fsm_state_change_irq; struct power_supply bms_psy; struct power_supply *batt_psy; struct power_supply *usb_psy; }; static struct qpnp_bms_chip *the_chip; Loading Loading @@ -417,6 +419,21 @@ static int calculate_delta_time(unsigned long *time_stamp, int *delta_time_s) return 0; } static bool is_charger_present(struct qpnp_bms_chip *chip) { union power_supply_propval ret = {0,}; if (chip->usb_psy == NULL) chip->usb_psy = power_supply_get_by_name("usb"); if (chip->usb_psy) { chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_PRESENT, &ret); return ret.intval; } return false; } static bool is_battery_charging(struct qpnp_bms_chip *chip) { union power_supply_propval ret = {0,}; Loading Loading @@ -2971,7 +2988,9 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip) chip->spmi->dev.of_node, "qcom,report-charger-eoc"); chip->dt.cfg_disable_bms = of_property_read_bool( chip->spmi->dev.of_node, "qcom,disable-bms"); chip->dt.cfg_force_bms_active_on_charger = of_property_read_bool( chip->spmi->dev.of_node, "qcom,force-bms-active-on-charger"); pr_debug("v_cutoff_uv=%d, max_v=%d\n", chip->dt.cfg_v_cutoff_uv, chip->dt.cfg_max_voltage_uv); pr_debug("r_conn=%d shutdown_soc_valid_limit=%d\n", Loading @@ -2981,10 +3000,11 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip) chip->dt.cfg_ignore_shutdown_soc, chip->dt.cfg_use_voltage_soc, chip->dt.cfg_low_soc_fifo_length); pr_debug("force-s3-on-suspend=%d report-charger-eoc=%d disable-bms=%d\n", pr_debug("force-s3-on-suspend=%d report-charger-eoc=%d disable-bms=%d disable-suspend-on-usb=%d\n", chip->dt.cfg_force_s3_on_suspend, chip->dt.cfg_report_charger_eoc, chip->dt.cfg_disable_bms); chip->dt.cfg_disable_bms, chip->dt.cfg_force_bms_active_on_charger); return 0; } Loading Loading @@ -3378,15 +3398,26 @@ static int bms_suspend(struct device *dev) struct qpnp_bms_chip *chip = dev_get_drvdata(dev); bool battery_charging = is_battery_charging(chip); bool hi_power_state = is_hi_power_state_requested(chip); bool charger_present = is_charger_present(chip); bool bms_suspend_config; /* * Keep BMS FSM active if 'cfg_force_bms_active_on_charger' property * is present and charger inserted. This ensures that recharge * starts once battery SOC falls below resume_soc. */ bms_suspend_config = chip->dt.cfg_force_bms_active_on_charger && charger_present; chip->apply_suspend_config = false; if (!battery_charging && !hi_power_state) if (!battery_charging && !hi_power_state && !bms_suspend_config) chip->apply_suspend_config = true; pr_debug("battery_charging=%d power_state=%s hi_power_state=0x%x apply_suspend_config=%d\n", pr_debug("battery_charging=%d power_state=%s hi_power_state=0x%x apply_suspend_config=%d bms_suspend_config=%d usb_present=%d\n", battery_charging, hi_power_state ? "hi" : "low", chip->hi_power_state, chip->apply_suspend_config); chip->apply_suspend_config, bms_suspend_config, charger_present); if (chip->apply_suspend_config) { if (chip->dt.cfg_force_s3_on_suspend) { Loading Loading
Documentation/devicetree/bindings/power/qpnp-linear-charger.txt +7 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,13 @@ Parent node optional properties: If not specified charger driver depends on BMSfor end-of-charge detection. - qcom,disable-vbatdet-based-recharge If specified disable VBATDET irq and charging can only be resumed if charger is re-inserted or SOC falls below resume SOC. This property should always be used along with the BMS property: "qcom,disable-suspend-on-usb". - qcom,use-external-charger If specifed the LBC module will be disabled and the driver will not register. It also enables BID for Loading
Documentation/devicetree/bindings/power/qpnp-vm-bms.txt +2 −0 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ Parent node Optional properties the fifo_update_done interrupt. Possible values- 0 to 8 - qcom,force-s3-on-suspend : Bool property to force the BMS into S3 (sleep) state while entering into system suspend. - qcom,force-bms-active-on-charger: Bool property to keep BMS FSM active if charger is present. - qcom,report-charger-eoc : Bool property to indicate if BMS needs to indicate EOC to charger. - qcom,ignore-shutdown-soc: A boolean that controls whether BMS will Loading
drivers/power/qpnp-linear-charger.c +26 −11 Original line number Diff line number Diff line Loading @@ -266,6 +266,8 @@ struct vddtrim_map vddtrim_map[] = { * @cfg_float_charge: enable float charging * @charger_disabled: maintain USB path state. * @cfg_charger_detect_eoc: charger can detect end of charging * @cfg_disable_vbatdet_based_recharge: keep VBATDET comparator overriden to * low and VBATDET irq disabled. * @cfg_safe_current: battery safety current setting * @cfg_hot_batt_p: hot battery threshold setting * @cfg_cold_batt_p: eold battery threshold setting Loading Loading @@ -323,6 +325,7 @@ struct qpnp_lbc_chip { unsigned int cfg_max_voltage_mv; unsigned int cfg_min_voltage_mv; unsigned int cfg_charger_detect_eoc; unsigned int cfg_disable_vbatdet_based_recharge; unsigned int cfg_batt_weak_voltage_uv; unsigned int cfg_warm_bat_mv; unsigned int cfg_cool_bat_mv; Loading Loading @@ -1145,6 +1148,7 @@ static int get_prop_capacity(struct qpnp_lbc_chip *chip) && ret.intval <= chip->cfg_soc_resume_limit) { pr_debug("resuming charging at %d%% soc\n", ret.intval); if (!chip->cfg_disable_vbatdet_based_recharge) qpnp_lbc_vbatdet_override(chip, OVERRIDE_0); qpnp_lbc_charger_enable(chip, SOC, 1); } Loading Loading @@ -1419,11 +1423,7 @@ static int qpnp_batt_power_set_property(struct power_supply *psy, if (val->intval == POWER_SUPPLY_STATUS_FULL && !chip->cfg_float_charge) { mutex_lock(&chip->chg_enable_lock); /* No override for VBAT_DET_LO comp */ rc = qpnp_lbc_vbatdet_override(chip, OVERRIDE_NONE); if (rc) pr_err("Failed to override VBAT_DET rc=%d\n", rc); /* Disable charging */ rc = qpnp_lbc_charger_enable(chip, SOC, 0); if (rc) Loading @@ -1437,8 +1437,17 @@ static int qpnp_batt_power_set_property(struct power_supply *psy, * To enable charging when VBAT falls below VBAT_DET * and device stays suspended after EOC. */ if (!chip->cfg_disable_vbatdet_based_recharge) { /* No override for VBAT_DET_LO comp */ rc = qpnp_lbc_vbatdet_override(chip, OVERRIDE_NONE); if (rc) pr_err("Failed to override VBAT_DET rc=%d\n", rc); else qpnp_lbc_enable_irq(chip, &chip->irqs[CHG_VBAT_DET_LO]); } mutex_unlock(&chip->chg_enable_lock); } Loading Loading @@ -1916,6 +1925,10 @@ static int qpnp_charger_read_dt_props(struct qpnp_lbc_chip *chip) of_property_read_bool(chip->spmi->dev.of_node, "qcom,charger-detect-eoc"); /* Get the vbatdet disable property */ chip->cfg_disable_vbatdet_based_recharge = of_property_read_bool(chip->spmi->dev.of_node, "qcom,disable-vbatdet-based-recharge"); /* Disable charging when faking battery values */ if (chip->cfg_use_fake_battery) chip->cfg_charging_disabled = true; Loading Loading @@ -1972,6 +1985,7 @@ static irqreturn_t qpnp_lbc_usbin_valid_irq_handler(int irq, void *_chip) * Override VBAT_DET comparator to start charging * even if VBAT > VBAT_DET. */ if (!chip->cfg_disable_vbatdet_based_recharge) qpnp_lbc_vbatdet_override(chip, OVERRIDE_0); /* Loading Loading @@ -2294,10 +2308,11 @@ static int qpnp_lbc_get_irqs(struct qpnp_lbc_chip *chip, u8 subtype, case LBC_CHGR_SUBTYPE: SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_FAST_CHG, fast-chg-on); SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_VBAT_DET_LO, vbat-det-lo); SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_FAILED, chg-failed); if (!chip->cfg_disable_vbatdet_based_recharge) SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_VBAT_DET_LO, vbat-det-lo); if (chip->cfg_charger_detect_eoc) SPMI_GET_IRQ_RESOURCE(chip, rc, spmi_resource, CHG_DONE, chg-done); Loading
drivers/power/qpnp-vm-bms.c +37 −6 Original line number Diff line number Diff line Loading @@ -137,6 +137,7 @@ struct bms_wakeup_source { struct bms_dt_cfg { bool cfg_report_charger_eoc; bool cfg_force_bms_active_on_charger; bool cfg_force_s3_on_suspend; bool cfg_ignore_shutdown_soc; bool cfg_use_voltage_soc; Loading Loading @@ -233,6 +234,7 @@ struct qpnp_bms_chip { struct bms_irq fsm_state_change_irq; struct power_supply bms_psy; struct power_supply *batt_psy; struct power_supply *usb_psy; }; static struct qpnp_bms_chip *the_chip; Loading Loading @@ -417,6 +419,21 @@ static int calculate_delta_time(unsigned long *time_stamp, int *delta_time_s) return 0; } static bool is_charger_present(struct qpnp_bms_chip *chip) { union power_supply_propval ret = {0,}; if (chip->usb_psy == NULL) chip->usb_psy = power_supply_get_by_name("usb"); if (chip->usb_psy) { chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_PRESENT, &ret); return ret.intval; } return false; } static bool is_battery_charging(struct qpnp_bms_chip *chip) { union power_supply_propval ret = {0,}; Loading Loading @@ -2971,7 +2988,9 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip) chip->spmi->dev.of_node, "qcom,report-charger-eoc"); chip->dt.cfg_disable_bms = of_property_read_bool( chip->spmi->dev.of_node, "qcom,disable-bms"); chip->dt.cfg_force_bms_active_on_charger = of_property_read_bool( chip->spmi->dev.of_node, "qcom,force-bms-active-on-charger"); pr_debug("v_cutoff_uv=%d, max_v=%d\n", chip->dt.cfg_v_cutoff_uv, chip->dt.cfg_max_voltage_uv); pr_debug("r_conn=%d shutdown_soc_valid_limit=%d\n", Loading @@ -2981,10 +3000,11 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip) chip->dt.cfg_ignore_shutdown_soc, chip->dt.cfg_use_voltage_soc, chip->dt.cfg_low_soc_fifo_length); pr_debug("force-s3-on-suspend=%d report-charger-eoc=%d disable-bms=%d\n", pr_debug("force-s3-on-suspend=%d report-charger-eoc=%d disable-bms=%d disable-suspend-on-usb=%d\n", chip->dt.cfg_force_s3_on_suspend, chip->dt.cfg_report_charger_eoc, chip->dt.cfg_disable_bms); chip->dt.cfg_disable_bms, chip->dt.cfg_force_bms_active_on_charger); return 0; } Loading Loading @@ -3378,15 +3398,26 @@ static int bms_suspend(struct device *dev) struct qpnp_bms_chip *chip = dev_get_drvdata(dev); bool battery_charging = is_battery_charging(chip); bool hi_power_state = is_hi_power_state_requested(chip); bool charger_present = is_charger_present(chip); bool bms_suspend_config; /* * Keep BMS FSM active if 'cfg_force_bms_active_on_charger' property * is present and charger inserted. This ensures that recharge * starts once battery SOC falls below resume_soc. */ bms_suspend_config = chip->dt.cfg_force_bms_active_on_charger && charger_present; chip->apply_suspend_config = false; if (!battery_charging && !hi_power_state) if (!battery_charging && !hi_power_state && !bms_suspend_config) chip->apply_suspend_config = true; pr_debug("battery_charging=%d power_state=%s hi_power_state=0x%x apply_suspend_config=%d\n", pr_debug("battery_charging=%d power_state=%s hi_power_state=0x%x apply_suspend_config=%d bms_suspend_config=%d usb_present=%d\n", battery_charging, hi_power_state ? "hi" : "low", chip->hi_power_state, chip->apply_suspend_config); chip->apply_suspend_config, bms_suspend_config, charger_present); if (chip->apply_suspend_config) { if (chip->dt.cfg_force_s3_on_suspend) { Loading