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

Commit b4709eef authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: vm-bms: Add snapshot of the qpnp-vm-bms driver



Add the latest driver snapshot of qpnp-vm-bms from msm-3.10 kernel.
(msm-3.10 commit - 7704c94d47f8ed7cc81e487ab9d576ef52e0f1e5)

Change-Id: Ib459f8fdfbf9d903a6b6a2655ea7414343639ccd
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 6a6deeda
Loading
Loading
Loading
Loading
+59 −23
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
#include <linux/qpnp/qpnp-adc.h>
#include <linux/of_batterydata.h>
#include <linux/batterydata-interface.h>
#include <linux/qpnp-revid.h>
#include <linux/qpnp/qpnp-revid.h>
#include <uapi/linux/vm_bms.h>

#define _BMS_MASK(BITS, POS) \
@@ -244,6 +244,7 @@ struct qpnp_bms_chip {
	u16				charge_cycles;
	unsigned int			start_soc;
	unsigned int			end_soc;
	unsigned int			chg_start_soc;

	struct bms_battery_data		*batt_data;
	struct bms_dt_cfg		dt;
@@ -962,7 +963,7 @@ static int lookup_soc_ocv(struct qpnp_bms_chip *chip, int ocv_uv, int batt_temp)

	if (chip->batt_data->ibat_acc_lut) {
		/* Apply  ACC logic only if we discharging */
		if (!is_battery_charging(chip) && chip->current_now > 0) {
		if (chip->current_now > 0) {

			/*
			 * IBAT averaging is disabled at low temp.
@@ -1607,7 +1608,9 @@ static int report_vm_bms_soc(struct qpnp_bms_chip *chip)
	 * avoid overflows when charging continues for extended periods
	 */
	if (charging && chip->last_soc != -EINVAL) {
		if (chip->charge_start_tm_sec == 0) {
		if (chip->charge_start_tm_sec == 0 ||
			(chip->catch_up_time_sec == 0 &&
				(abs(soc - chip->last_soc) >= MIN_SOC_UUC))) {
			/*
			 * calculating soc for the first time
			 * after start of chg. Initialize catchup time
@@ -1619,17 +1622,25 @@ static int report_vm_bms_soc(struct qpnp_bms_chip *chip)
			else
				chip->catch_up_time_sec = SOC_CATCHUP_SEC_MAX;

			chip->chg_start_soc = chip->last_soc;

			if (chip->catch_up_time_sec < 0)
				chip->catch_up_time_sec = 0;
			chip->charge_start_tm_sec = last_change_sec;

			pr_debug("chg_start_soc=%d charge_start_tm_sec=%d catch_up_time_sec=%d\n",
				chip->chg_start_soc, chip->charge_start_tm_sec,
						chip->catch_up_time_sec);
		}

		charge_time_sec = min(SOC_CATCHUP_SEC_MAX, (int)last_change_sec
				- chip->charge_start_tm_sec);

		/* end catchup if calculated soc and last soc are same */
		if (chip->last_soc == soc)
		if (chip->last_soc == soc) {
			chip->catch_up_time_sec = 0;
			chip->chg_start_soc = chip->last_soc;
		}
	}

	if (chip->last_soc != -EINVAL) {
@@ -1647,7 +1658,7 @@ static int report_vm_bms_soc(struct qpnp_bms_chip *chip)
		else if (chip->last_soc < soc && soc != 100)
			soc = scale_soc_while_chg(chip, charge_time_sec,
					chip->catch_up_time_sec,
					soc, chip->last_soc);
					soc, chip->chg_start_soc);

		/*
		 * if the battery is close to cutoff or if the batt_temp
@@ -1963,6 +1974,11 @@ static void calculate_reported_soc(struct qpnp_bms_chip *chip)
{
	union power_supply_propval ret = {0,};

	if (chip->last_soc < 0) {
		pr_debug("last_soc is not ready, return\n");
		return;
	}

	if (chip->reported_soc > chip->last_soc) {
		/*send DISCHARGING status if the reported_soc drops from 100 */
		if (chip->reported_soc == 100) {
@@ -2022,13 +2038,26 @@ static int clamp_soc_based_on_voltage(struct qpnp_bms_chip *chip, int soc)
	}
}

static void battery_voltage_check(struct qpnp_bms_chip *chip)
{
	int rc, vbat_uv = 0;

	rc = get_battery_voltage(chip, &vbat_uv);
	if (rc < 0) {
		pr_err("Failed to read battery-voltage rc=%d\n", rc);
	} else {
		very_low_voltage_check(chip, vbat_uv);
		cv_voltage_check(chip, vbat_uv);
	}
}

#define UI_SOC_CATCHUP_TIME	(60)
static void monitor_soc_work(struct work_struct *work)
{
	struct qpnp_bms_chip *chip = container_of(work,
				struct qpnp_bms_chip,
				monitor_soc_work.work);
	int rc, vbat_uv = 0, new_soc = 0, batt_temp;
	int rc, new_soc = 0, batt_temp;

	bms_stay_awake(&chip->vbms_soc_wake_source);

@@ -2044,13 +2073,7 @@ static void monitor_soc_work(struct work_struct *work)
		chip->last_soc = -EINVAL;
		new_soc = 100;
	} else {
		rc = get_battery_voltage(chip, &vbat_uv);
		if (rc < 0) {
			pr_err("Failed to read battery-voltage rc=%d\n", rc);
		} else {
			very_low_voltage_check(chip, vbat_uv);
			cv_voltage_check(chip, vbat_uv);
		}
		battery_voltage_check(chip);

		if (chip->dt.cfg_use_voltage_soc) {
			calculate_soc_from_voltage(chip);
@@ -2075,6 +2098,11 @@ static void monitor_soc_work(struct work_struct *work)
				pr_debug("SOC changed! new_soc=%d prev_soc=%d\n",
						new_soc, chip->calculated_soc);
				chip->calculated_soc = new_soc;
				/*
				 * To recalculate the catch-up time, clear it
				 * when SOC changes.
				 */
				chip->catch_up_time_sec = 0;

				if (chip->calculated_soc == 100)
					/* update last_soc immediately */
@@ -2180,6 +2208,7 @@ static enum power_supply_property bms_power_props[] = {
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_RESISTANCE,
	POWER_SUPPLY_PROP_RESISTANCE_CAPACITIVE,
	POWER_SUPPLY_PROP_RESISTANCE_NOW,
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_VOLTAGE_OCV,
	POWER_SUPPLY_PROP_HI_POWER,
@@ -2232,6 +2261,12 @@ static int qpnp_vm_bms_power_get_property(struct power_supply *psy,
		if (chip->dt.cfg_r_conn_mohm > 0)
			val->intval += chip->dt.cfg_r_conn_mohm;
		break;
	case POWER_SUPPLY_PROP_RESISTANCE_NOW:
		rc = get_batt_therm(chip, &value);
		if (rc < 0)
			value = BMS_DEFAULT_TEMP;
		val->intval = get_rbatt(chip, chip->calculated_soc, value);
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = get_prop_bms_current_now(chip);
		break;
@@ -2442,6 +2477,10 @@ static void qpnp_vm_bms_ext_power_changed(struct power_supply *psy)
	battery_status_check(chip);
	battery_insertion_check(chip);

	mutex_lock(&chip->last_soc_mutex);
	battery_voltage_check(chip);
	mutex_unlock(&chip->last_soc_mutex);

	if (chip->reported_soc_in_use)
		reported_soc_check_status(chip);
}
@@ -2931,7 +2970,7 @@ static int calculate_initial_aging_comp(struct qpnp_bms_chip *chip)

static int bms_load_hw_defaults(struct qpnp_bms_chip *chip)
{
	u8 val, state, bms_en = 0;
	u8 val, bms_en = 0;
	u32 interval[2], count[2], fifo[2];
	int rc;

@@ -3029,14 +3068,10 @@ static int bms_load_hw_defaults(struct qpnp_bms_chip *chip)
	get_fifo_length(chip, S2_STATE, &fifo[1]);

	/* Force the BMS state to S2 at boot-up */
	rc = get_fsm_state(chip, &state);
	if (rc)
		pr_err("Unable to get FSM state rc=%d\n", rc);
	if (rc || (state != S2_STATE)) {
		pr_debug("Forcing S2 state\n");
	rc = force_fsm_state(chip, S2_STATE);
		if (rc)
			pr_err("Unable to set FSM state rc=%d\n", rc);
	if (rc) {
		pr_err("Unable to force S2 state rc=%d\n", rc);
		return rc;
	}

	rc = qpnp_read_wrapper(chip, &bms_en, chip->base + EN_CTL_REG, 1);
@@ -3453,7 +3488,8 @@ static int set_battery_data(struct qpnp_bms_chip *chip)
	rc = of_batterydata_read_data(node, batt_data, battery_id);
	if (rc || !batt_data->pc_temp_ocv_lut
		|| !batt_data->fcc_temp_lut
		|| !batt_data->rbatt_sf_lut) {
		|| !batt_data->rbatt_sf_lut
		|| !batt_data->ibat_acc_lut) {
		pr_err("battery data load failed\n");
		devm_kfree(chip->dev, batt_data->fcc_temp_lut);
		devm_kfree(chip->dev, batt_data->pc_temp_ocv_lut);
+1 −0
Original line number Diff line number Diff line
@@ -487,6 +487,7 @@ header-y += virtio_net.h
header-y += virtio_pci.h
header-y += virtio_ring.h
header-y += virtio_rng.h
header-y += vm_bms.h
header-y += vm_sockets.h
header-y += vt.h
header-y += wait.h