Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17c7bc96 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: vm_bms: add notification to restart charging"

parents 909c6d22 0c52e010
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -105,6 +105,8 @@ Parent node Optional properties
- qcom,low-soc-fifo-length : The fifo length (of S2 STATE) to be used at lower
			SOCs. If this value is not specified the system uses
			default lenght.
- qcom,resume-soc:	Capacity in percent at which charging should resume
			when a fully charged battery drops below this level.

qcom,batt-pres-status node required properties:
- reg : offset and length of the PMIC LBC battery interface BATT_PRES_STATUS
+77 −6
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ struct bms_dt_cfg {
	int				cfg_s2_fifo_length;
	int				cfg_disable_bms;
	int				cfg_s3_ocv_tol_uv;
	int				cfg_soc_resume_limit;
};

struct qpnp_bms_chip {
@@ -230,6 +231,7 @@ struct qpnp_bms_chip {
	int				iavg_samples_ma[IAVG_SAMPLES];
	int				iavg_ma;
	int				prev_soc_uuc;
	int				eoc_reported;

	struct bms_battery_data		*batt_data;
	struct bms_dt_cfg		dt;
@@ -515,6 +517,22 @@ static bool is_battery_present(struct qpnp_bms_chip *chip)
	return false;
}

static bool is_battery_taper_charging(struct qpnp_bms_chip *chip)
{
	union power_supply_propval ret = {0,};

	if (chip->batt_psy == NULL)
		chip->batt_psy = power_supply_get_by_name("battery");

	if (chip->batt_psy) {
		chip->batt_psy->get_property(chip->batt_psy,
				POWER_SUPPLY_PROP_CHARGE_TYPE, &ret);
		return ret.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER;
	}

	return false;
}

static int master_hold_control(struct qpnp_bms_chip *chip, bool enable)
{
	u8 reg = 0;
@@ -1274,8 +1292,11 @@ static int report_eoc(struct qpnp_bms_chip *chip)
			ret.intval = POWER_SUPPLY_STATUS_FULL;
			rc = chip->batt_psy->set_property(chip->batt_psy,
					POWER_SUPPLY_PROP_STATUS, &ret);
			if (rc)
			if (rc) {
				pr_err("Unable to set 'STATUS' rc=%d\n", rc);
				return rc;
			}
			chip->eoc_reported = true;
		}
	} else {
		pr_err("battery psy not registered\n");
@@ -1284,10 +1305,46 @@ static int report_eoc(struct qpnp_bms_chip *chip)
	return rc;
}

static void check_recharge_condition(struct qpnp_bms_chip *chip)
{
	int rc;
	union power_supply_propval ret = {0,};
	int status = get_battery_status(chip);

	if (chip->last_soc > chip->dt.cfg_soc_resume_limit)
		return;

	if (status == POWER_SUPPLY_STATUS_UNKNOWN) {
		pr_debug("Unable to read battery status\n");
		return;
	}

	/* Report recharge to charger for SOC based resume of charging */
	if ((status != POWER_SUPPLY_STATUS_CHARGING) && chip->eoc_reported) {
		ret.intval = POWER_SUPPLY_STATUS_CHARGING;
		rc = chip->batt_psy->set_property(chip->batt_psy,
				POWER_SUPPLY_PROP_STATUS, &ret);
		if (rc < 0) {
			pr_err("Unable to set battery property rc=%d\n", rc);
		} else {
			pr_info("soc dropped below resume_soc soc=%d resume_soc=%d, restart charging\n",
					chip->last_soc,
					chip->dt.cfg_soc_resume_limit);
			chip->eoc_reported = false;
		}
	}
}

static void check_eoc_condition(struct qpnp_bms_chip *chip)
{
	int rc;
	int status = get_battery_status(chip);
	union power_supply_propval ret = {0,};

	if (status == POWER_SUPPLY_STATUS_UNKNOWN) {
		pr_err("Unable to read battery status\n");
		return;
	}

	/*
	 * Check battery status:
@@ -1328,8 +1385,17 @@ static void check_eoc_condition(struct qpnp_bms_chip *chip)
			chip->ocv_at_100 = chip->last_ocv_uv;
			chip->last_soc = 100;
		} else if (chip->last_soc != 100) {
			/*
			 * Report that the battery is discharging.
			 * This gets called once when the SOC falls
			 * below 100.
			 */
			ret.intval = POWER_SUPPLY_STATUS_DISCHARGING;
			chip->batt_psy->set_property(chip->batt_psy,
						POWER_SUPPLY_PROP_STATUS, &ret);

			pr_debug("SOC dropped (%d) discarding ocv_at_100\n",
							chip->calculated_soc);
							chip->last_soc);
			chip->ocv_at_100 = -EINVAL;
		}
	}
@@ -1443,6 +1509,8 @@ static int report_vm_bms_soc(struct qpnp_bms_chip *chip)
	if ((soc != chip->last_soc) || (soc == 100)) {
		chip->last_soc = soc;
		check_eoc_condition(chip);
		if ((chip->dt.cfg_soc_resume_limit > 0) && !charging)
			check_recharge_condition(chip);
	}

	pr_debug("last_soc=%d calculated_soc=%d soc=%d time_since_last_change=%d\n",
@@ -1596,8 +1664,9 @@ static void very_low_voltage_check(struct qpnp_bms_chip *chip, int vbat_uv)
static void cv_voltage_check(struct qpnp_bms_chip *chip, int vbat_uv)
{
	if (bms_wake_active(&chip->vbms_cv_wake_source)) {
		if (vbat_uv < (chip->dt.cfg_max_voltage_uv -
			VBATT_ERROR_MARGIN + CV_DROP_MARGIN)) {
		if ((vbat_uv < (chip->dt.cfg_max_voltage_uv -
				VBATT_ERROR_MARGIN + CV_DROP_MARGIN))
			&& !is_battery_taper_charging(chip)) {
			pr_debug("Fell below CV, releasing cv ws\n");
			chip->in_cv_state = false;
			bms_relax(&chip->vbms_cv_wake_source);
@@ -1608,8 +1677,9 @@ static void cv_voltage_check(struct qpnp_bms_chip *chip, int vbat_uv)
		}
	} else if (!bms_wake_active(&chip->vbms_cv_wake_source)
			&& is_battery_charging(chip)
			&& (vbat_uv > (chip->dt.cfg_max_voltage_uv -
					VBATT_ERROR_MARGIN))) {
			&& ((vbat_uv > (chip->dt.cfg_max_voltage_uv -
					VBATT_ERROR_MARGIN))
				|| is_battery_taper_charging(chip))) {
		pr_debug("CC_TO_CV voltage=%d holding cv ws\n", vbat_uv);
		chip->in_cv_state = true;
		bms_stay_awake(&chip->vbms_cv_wake_source);
@@ -3181,6 +3251,7 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip)
	SPMI_PROP_READ_OPTIONAL(cfg_s3_ocv_tol_uv, "s3-ocv-tolerence-uv", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_low_soc_fifo_length,
						"low-soc-fifo-length", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_soc_resume_limit, "resume-soc", rc);

	chip->dt.cfg_ignore_shutdown_soc = of_property_read_bool(
			chip->spmi->dev.of_node, "qcom,ignore-shutdown-soc");