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

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

Merge "power: qpnp-fg: Reconfigure SW_CC_SOC to reduce error"

parents 6c3ef9a9 b52b689a
Loading
Loading
Loading
Loading
+61 −10
Original line number Diff line number Diff line
@@ -3435,13 +3435,11 @@ fail:

#define CC_SOC_BASE_REG		0x5BC
#define CC_SOC_OFFSET		3
#define CC_SOC_MAGNITUDE_MASK	0x1FFFFFFF
#define CC_SOC_NEGATIVE_BIT	BIT(29)
static int fg_get_cc_soc(struct fg_chip *chip, int *cc_soc)
{
	int rc;
	u8 reg[4];
	unsigned int temp, magnitude;
	int temp;

	rc = fg_mem_read(chip, reg, CC_SOC_BASE_REG, 4, CC_SOC_OFFSET, 0);
	if (rc) {
@@ -3450,15 +3448,32 @@ static int fg_get_cc_soc(struct fg_chip *chip, int *cc_soc)
	}

	temp = reg[3] << 24 | reg[2] << 16 | reg[1] << 8 | reg[0];
	magnitude = temp & CC_SOC_MAGNITUDE_MASK;
	if (temp & CC_SOC_NEGATIVE_BIT)
		*cc_soc = -1 * (~magnitude + 1);
	else
		*cc_soc = magnitude;

	*cc_soc = sign_extend32(temp, 29);
	return 0;
}

static int fg_get_current_cc(struct fg_chip *chip)
{
	int cc_soc, rc;
	int64_t current_capacity;

	if (!(chip->wa_flag & USE_CC_SOC_REG))
		return chip->learning_data.cc_uah;

	if (!chip->learning_data.learned_cc_uah)
		return -EINVAL;

	rc = fg_get_cc_soc(chip, &cc_soc);
	if (rc < 0) {
		pr_err("Failed to get cc_soc, rc=%d\n", rc);
		return rc;
	}

	current_capacity = cc_soc * chip->learning_data.learned_cc_uah;
	do_div(current_capacity, FULL_PERCENT_28BIT);
	return current_capacity;
}

#define BATT_MISSING_STS BIT(6)
static bool is_battery_missing(struct fg_chip *chip)
{
@@ -3832,6 +3847,17 @@ static int fg_cap_learning_check(struct fg_chip *chip)
		}

		fg_cap_learning_stop(chip);
	} else if (chip->status == POWER_SUPPLY_STATUS_FULL) {
		if (chip->wa_flag & USE_CC_SOC_REG) {
			/* reset SW_CC_SOC register to 100% upon charge_full */
			rc = fg_mem_write(chip, (u8 *)&cc_pc_100,
				CC_SOC_BASE_REG, 4, CC_SOC_OFFSET, 0);
			if (rc)
				pr_err("Failed to reset CC_SOC_REG rc=%d\n",
								rc);
			else if (fg_debug_mask & FG_STATUS)
				pr_info("Reset SW_CC_SOC to full value\n");
		}
	}

fail:
@@ -3927,7 +3953,7 @@ static void status_change_work(struct work_struct *work)
				struct fg_chip,
				status_change_work);
	unsigned long current_time = 0;
	int cc_soc, rc, capacity = get_prop_capacity(chip);
	int cc_soc, batt_soc, rc, capacity = get_prop_capacity(chip);
	bool batt_missing = is_battery_missing(chip);

	if (batt_missing) {
@@ -3994,6 +4020,26 @@ static void status_change_work(struct work_struct *work)
	}

	if (chip->prev_status != chip->status && chip->last_sram_update_time) {
		/*
		 * Reset SW_CC_SOC to a value based off battery SOC when
		 * the device is discharging.
		 */
		if (chip->status == POWER_SUPPLY_STATUS_DISCHARGING) {
			batt_soc = get_battery_soc_raw(chip);
			if (!batt_soc)
				return;

			batt_soc = div64_s64((int64_t)batt_soc *
					FULL_PERCENT_28BIT, FULL_PERCENT_3B);
			rc = fg_mem_write(chip, (u8 *)&batt_soc,
				CC_SOC_BASE_REG, 4, CC_SOC_OFFSET, 0);
			if (rc)
				pr_err("Failed to reset CC_SOC_REG rc=%d\n",
									rc);
			else if (fg_debug_mask & FG_STATUS)
				pr_info("Reset SW_CC_SOC to %x\n", batt_soc);
		}

		/*
		 * Schedule the update_temp_work whenever there is a status
		 * change. This is essential for applying the slope limiter
@@ -4035,6 +4081,7 @@ static void status_change_work(struct work_struct *work)
					chip->sw_cc_soc_data.init_cc_soc);
		}
	}

	if ((chip->wa_flag & USE_CC_SOC_REG) && chip->bad_batt_detection_en
			&& chip->safety_timer_expired) {
		chip->sw_cc_soc_data.delta_soc =
@@ -4434,6 +4481,7 @@ static enum power_supply_property fg_power_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
	POWER_SUPPLY_PROP_VOLTAGE_OCV,
	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
	POWER_SUPPLY_PROP_CHARGE_COUNTER,
	POWER_SUPPLY_PROP_CHARGE_NOW,
	POWER_SUPPLY_PROP_CHARGE_NOW_RAW,
	POWER_SUPPLY_PROP_CHARGE_NOW_ERROR,
@@ -4540,6 +4588,9 @@ static int fg_power_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CHARGE_NOW_RAW:
		val->intval = get_sram_prop_now(chip, FG_DATA_CC_CHARGE);
		break;
	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
		val->intval = fg_get_current_cc(chip);
		break;
	case POWER_SUPPLY_PROP_HI_POWER:
		val->intval = !!chip->bcl_lpm_disabled;
		break;