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

Commit b2ccc8bb 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-gen3: Improve the accuracy of charge_counter"

parents b99fa91f ef69cf22
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -426,6 +426,7 @@ struct fg_chip {
	int			batt_id_ohms;
	int			ki_coeff_full_soc;
	int			charge_status;
	int			prev_charge_status;
	int			charge_done;
	int			charge_type;
	int			online_status;
+68 −11
Original line number Diff line number Diff line
@@ -562,6 +562,21 @@ static int fg_get_charge_raw(struct fg_chip *chip, int *val)
	return 0;
}

#define BATT_SOC_32BIT	GENMASK(31, 0)
static int fg_get_charge_counter_shadow(struct fg_chip *chip, int *val)
{
	int rc, batt_soc;

	rc = fg_get_sram_prop(chip, FG_SRAM_BATT_SOC, &batt_soc);
	if (rc < 0) {
		pr_err("Error in getting BATT_SOC, rc=%d\n", rc);
		return rc;
	}

	*val = div_u64((u32)batt_soc * chip->cl.learned_cc_uah, BATT_SOC_32BIT);
	return 0;
}

static int fg_get_charge_counter(struct fg_chip *chip, int *val)
{
	int rc, cc_soc;
@@ -1249,6 +1264,21 @@ static bool is_parallel_charger_available(struct fg_chip *chip)
	return true;
}

static int fg_prime_cc_soc_sw(struct fg_chip *chip, int cc_soc_sw)
{
	int rc;

	rc = fg_sram_write(chip, chip->sp[FG_SRAM_CC_SOC_SW].addr_word,
		chip->sp[FG_SRAM_CC_SOC_SW].addr_byte, (u8 *)&cc_soc_sw,
		chip->sp[FG_SRAM_CC_SOC_SW].len, FG_IMA_ATOMIC);
	if (rc < 0)
		pr_err("Error in writing cc_soc_sw, rc=%d\n", rc);
	else
		fg_dbg(chip, FG_STATUS, "cc_soc_sw: %x\n", cc_soc_sw);

	return rc;
}

static int fg_save_learned_cap_to_sram(struct fg_chip *chip)
{
	int16_t cc_mah;
@@ -1434,7 +1464,6 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip)
	return 0;
}

#define BATT_SOC_32BIT	GENMASK(31, 0)
static int fg_cap_learning_begin(struct fg_chip *chip, u32 batt_soc)
{
	int rc, cc_soc_sw, batt_soc_msb;
@@ -1453,16 +1482,13 @@ static int fg_cap_learning_begin(struct fg_chip *chip, u32 batt_soc)
	/* Prime cc_soc_sw with battery SOC when capacity learning begins */
	cc_soc_sw = div64_s64((int64_t)batt_soc * CC_SOC_30BIT,
				BATT_SOC_32BIT);
	rc = fg_sram_write(chip, chip->sp[FG_SRAM_CC_SOC_SW].addr_word,
		chip->sp[FG_SRAM_CC_SOC_SW].addr_byte, (u8 *)&cc_soc_sw,
		chip->sp[FG_SRAM_CC_SOC_SW].len, FG_IMA_ATOMIC);
	rc = fg_prime_cc_soc_sw(chip, cc_soc_sw);
	if (rc < 0) {
		pr_err("Error in writing cc_soc_sw, rc=%d\n", rc);
		goto out;
	}

	chip->cl.init_cc_soc_sw = cc_soc_sw;
	chip->cl.active = true;
	fg_dbg(chip, FG_CAP_LEARN, "Capacity learning started @ battery SOC %d init_cc_soc_sw:%d\n",
		batt_soc_msb, chip->cl.init_cc_soc_sw);
out:
@@ -1482,9 +1508,7 @@ static int fg_cap_learning_done(struct fg_chip *chip)

	/* Write a FULL value to cc_soc_sw */
	cc_soc_sw = CC_SOC_30BIT;
	rc = fg_sram_write(chip, chip->sp[FG_SRAM_CC_SOC_SW].addr_word,
		chip->sp[FG_SRAM_CC_SOC_SW].addr_byte, (u8 *)&cc_soc_sw,
		chip->sp[FG_SRAM_CC_SOC_SW].len, FG_IMA_ATOMIC);
	rc = fg_prime_cc_soc_sw(chip, cc_soc_sw);
	if (rc < 0) {
		pr_err("Error in writing cc_soc_sw, rc=%d\n", rc);
		goto out;
@@ -1497,8 +1521,9 @@ static int fg_cap_learning_done(struct fg_chip *chip)

static void fg_cap_learning_update(struct fg_chip *chip)
{
	int rc, batt_soc, batt_soc_msb;
	int rc, batt_soc, batt_soc_msb, cc_soc_sw;
	bool input_present = is_input_present(chip);
	bool prime_cc = false;

	mutex_lock(&chip->cl.lock);

@@ -1511,6 +1536,9 @@ static void fg_cap_learning_update(struct fg_chip *chip)
		goto out;
	}

	if (chip->charge_status == chip->prev_charge_status)
		goto out;

	rc = fg_get_sram_prop(chip, FG_SRAM_BATT_SOC, &batt_soc);
	if (rc < 0) {
		pr_err("Error in getting ACT_BATT_CAP, rc=%d\n", rc);
@@ -1526,8 +1554,12 @@ static void fg_cap_learning_update(struct fg_chip *chip)
		if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING) {
			rc = fg_cap_learning_begin(chip, batt_soc);
			chip->cl.active = (rc == 0);
		} else {
			if ((chip->charge_status ==
					POWER_SUPPLY_STATUS_DISCHARGING) ||
					chip->charge_done)
				prime_cc = true;
		}

	} else {
		if (chip->charge_done) {
			rc = fg_cap_learning_done(chip);
@@ -1545,6 +1577,7 @@ static void fg_cap_learning_update(struct fg_chip *chip)
					 batt_soc_msb);
				chip->cl.active = false;
				chip->cl.init_cc_uah = 0;
				prime_cc = true;
			}
		}

@@ -1561,8 +1594,27 @@ static void fg_cap_learning_update(struct fg_chip *chip)
					batt_soc_msb);
				chip->cl.active = false;
				chip->cl.init_cc_uah = 0;
				prime_cc = true;
			}
		}
	}

	/*
	 * Prime CC_SOC_SW when the device is not charging or during charge
	 * termination when the capacity learning is not active.
	 */

	if (prime_cc) {
		if (chip->charge_done)
			cc_soc_sw = CC_SOC_30BIT;
		else
			cc_soc_sw = div_u64((u32)batt_soc *
					CC_SOC_30BIT, BATT_SOC_32BIT);

		rc = fg_prime_cc_soc_sw(chip, cc_soc_sw);
		if (rc < 0)
			pr_err("Error in writing cc_soc_sw, rc=%d\n",
				rc);
	}

out:
@@ -2564,7 +2616,7 @@ static void status_change_work(struct work_struct *work)
	}

	fg_ttf_update(chip);

	chip->prev_charge_status = chip->charge_status;
out:
	fg_dbg(chip, FG_POWER_SUPPLY, "charge_status:%d charge_type:%d charge_done:%d\n",
		chip->charge_status, chip->charge_type, chip->charge_done);
@@ -3556,6 +3608,9 @@ static int fg_psy_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
		rc = fg_get_charge_counter(chip, &pval->intval);
		break;
	case POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW:
		rc = fg_get_charge_counter_shadow(chip, &pval->intval);
		break;
	case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
		rc = fg_get_time_to_full(chip, &pval->intval);
		break;
@@ -3766,6 +3821,7 @@ static enum power_supply_property fg_psy_props[] = {
	POWER_SUPPLY_PROP_CHARGE_NOW,
	POWER_SUPPLY_PROP_CHARGE_FULL,
	POWER_SUPPLY_PROP_CHARGE_COUNTER,
	POWER_SUPPLY_PROP_CHARGE_COUNTER_SHADOW,
	POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
	POWER_SUPPLY_PROP_SOC_REPORTING_READY,
@@ -5001,6 +5057,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
	chip->debug_mask = &fg_gen3_debug_mask;
	chip->irqs = fg_irqs;
	chip->charge_status = -EINVAL;
	chip->prev_charge_status = -EINVAL;
	chip->ki_coeff_full_soc = -EINVAL;
	chip->online_status = -EINVAL;
	chip->regmap = dev_get_regmap(chip->dev->parent, NULL);