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

Commit b99ea4cb authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy Committed by Harry Yang
Browse files

qpnp-fg-gen3: add support for configuring ESR filter coefficients



As per the hardware documentation, add support for configuring
ESR tight and broad filters for normal and low temperature. This
is needed as the low temperature ESR filter coefficients are not
functional in the hardware.

All the filter values (in terms of percentage) can be configured
through the device tree. When the battery temperature goes below
10 C or user configured temperature threshold, ESR filter values
of room temperature will be applied to ESR low temperature
filters. Once the battery temperature goes above 10 C, original
values will be applied back to ESR low temperature filters.

Change-Id: I347f194f96ace3036a3c49efe0306d9f909cef36
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 34af21cb
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -273,6 +273,45 @@ First Level Node - FG Gen3 device
		    is specified, then ESR to Rslow scaling factors will be
		    updated to account it for an accurate ESR.

- qcom,fg-esr-filter-switch-temp
	Usage:      optional
	Value type: <u32>
	Definition: Battery temperature threshold below which low temperature
		    ESR filter coefficients will be switched to normal
		    temperature ESR filter coefficients. If this is not
		    specified, then the default value used will be 100. Unit is
		    in decidegC.

- qcom,fg-esr-tight-filter-micro-pct
	Usage:      optional
	Value type: <u32>
	Definition: Value in micro percentage for ESR tight filter. If this is
		    not specified, then a default value of 3907 (0.39 %) will
		    be used. Lowest possible value is 1954 (0.19 %).

- qcom,fg-esr-broad-filter-micro-pct
	Usage:      optional
	Value type: <u32>
	Definition: Value in micro percentage for ESR broad filter. If this is
		    not specified, then a default value of 99610 (9.96 %) will
		    be used. Lowest possible value is 1954 (0.19 %).

- qcom,fg-esr-tight-lt-filter-micro-pct
	Usage:      optional
	Value type: <u32>
	Definition: Value in micro percentage for low temperature ESR tight
		    filter. If this is not specified, then a default value of
		    48829 (4.88 %) will be used. Lowest possible value is 1954
		    (0.19 %).

- qcom,fg-esr-broad-lt-filter-micro-pct
	Usage:      optional
	Value type: <u32>
	Definition: Value in micro percentage for low temperature ESR broad
		    filter. If this is not specified, then a default value of
		    148438 (14.84 %) will be used. Lowest possible value is
		    1954 (0.19 %).

==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
+8 −0
Original line number Diff line number Diff line
@@ -161,6 +161,8 @@ enum fg_sram_param_id {
	FG_SRAM_RECHARGE_VBATT_THR,
	FG_SRAM_KI_COEFF_MED_DISCHG,
	FG_SRAM_KI_COEFF_HI_DISCHG,
	FG_SRAM_ESR_TIGHT_FILTER,
	FG_SRAM_ESR_BROAD_FILTER,
	FG_SRAM_MAX,
};

@@ -225,6 +227,11 @@ struct fg_dt_props {
	int	cl_min_cap_limit;
	int	jeita_hyst_temp;
	int	batt_temp_delta;
	int	esr_flt_switch_temp;
	int	esr_tight_flt_upct;
	int	esr_broad_flt_upct;
	int	esr_tight_lt_flt_upct;
	int	esr_broad_lt_flt_upct;
	int	jeita_thresholds[NUM_JEITA_LEVELS];
	int	ki_coeff_soc[KI_COEFF_SOC_LEVELS];
	int	ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
@@ -337,6 +344,7 @@ struct fg_chip {
	bool			ki_coeff_dischg_en;
	bool			esr_fcc_ctrl_en;
	bool			soc_reporting_ready;
	bool			esr_flt_cold_temp_en;
	struct completion	soc_update;
	struct completion	soc_ready;
	struct delayed_work	profile_load_work;
+140 −1
Original line number Diff line number Diff line
@@ -37,6 +37,11 @@
#define SYS_TERM_CURR_OFFSET		0
#define VBATT_FULL_WORD			7
#define VBATT_FULL_OFFSET		0
#define ESR_FILTER_WORD			8
#define ESR_UPD_TIGHT_OFFSET		0
#define ESR_UPD_BROAD_OFFSET		1
#define ESR_UPD_TIGHT_LOW_TEMP_OFFSET	2
#define ESR_UPD_BROAD_LOW_TEMP_OFFSET	3
#define KI_COEFF_MED_DISCHG_WORD	9
#define KI_COEFF_MED_DISCHG_OFFSET	3
#define KI_COEFF_HI_DISCHG_WORD		10
@@ -203,6 +208,10 @@ static struct fg_sram_param pmi8998_v1_sram_params[] = {
	PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_WORD,
		KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 244141, 0,
		fg_encode_default, NULL),
	PARAM(ESR_TIGHT_FILTER, ESR_FILTER_WORD, ESR_UPD_TIGHT_OFFSET,
		1, 512, 1000000, 0, fg_encode_default, NULL),
	PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
		1, 512, 1000000, 0, fg_encode_default, NULL),
};

static struct fg_sram_param pmi8998_v2_sram_params[] = {
@@ -263,6 +272,10 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
	PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_v2_WORD,
		KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
		fg_encode_default, NULL),
	PARAM(ESR_TIGHT_FILTER, ESR_FILTER_WORD, ESR_UPD_TIGHT_OFFSET,
		1, 512, 1000000, 0, fg_encode_default, NULL),
	PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
		1, 512, 1000000, 0, fg_encode_default, NULL),
};

static struct fg_alg_flag pmi8998_v1_alg_flags[] = {
@@ -1550,6 +1563,65 @@ static int fg_adjust_recharge_soc(struct fg_chip *chip)
	return 0;
}

static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp)
{
	u8 esr_tight_lt_flt, esr_broad_lt_flt;
	bool cold_temp = false;
	int rc;

	/*
	 * If the battery temperature is lower than -20 C, then skip modifying
	 * ESR filter.
	 */
	if (batt_temp < -210)
		return 0;

	/*
	 * If battery temperature is lesser than 10 C (default), then apply the
	 * normal ESR tight and broad filter values to ESR low temperature tight
	 * and broad filters. If battery temperature is higher than 10 C, then
	 * apply back the low temperature ESR filter coefficients to ESR low
	 * temperature tight and broad filters.
	 */
	if (batt_temp > chip->dt.esr_flt_switch_temp
		&& chip->esr_flt_cold_temp_en) {
		fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
			chip->dt.esr_tight_lt_flt_upct, &esr_tight_lt_flt);
		fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
			chip->dt.esr_broad_lt_flt_upct, &esr_broad_lt_flt);
	} else if (batt_temp <= chip->dt.esr_flt_switch_temp
			&& !chip->esr_flt_cold_temp_en) {
		fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
			chip->dt.esr_tight_flt_upct, &esr_tight_lt_flt);
		fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
			chip->dt.esr_broad_flt_upct, &esr_broad_lt_flt);
		cold_temp = true;
	} else {
		return 0;
	}

	rc = fg_sram_write(chip, ESR_FILTER_WORD,
			ESR_UPD_TIGHT_LOW_TEMP_OFFSET, &esr_tight_lt_flt, 1,
			FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("Error in writing ESR LT tight filter, rc=%d\n", rc);
		return rc;
	}

	rc = fg_sram_write(chip, ESR_FILTER_WORD,
			ESR_UPD_BROAD_LOW_TEMP_OFFSET, &esr_broad_lt_flt, 1,
			FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("Error in writing ESR LT broad filter, rc=%d\n", rc);
		return rc;
	}

	chip->esr_flt_cold_temp_en = cold_temp;
	fg_dbg(chip, FG_STATUS, "applied %s ESR filter values\n",
		cold_temp ? "cold" : "normal");
	return 0;
}

static int fg_esr_fcc_config(struct fg_chip *chip)
{
	union power_supply_propval prop = {0, };
@@ -2790,6 +2862,26 @@ static int fg_hw_init(struct fg_chip *chip)
		}
	}

	fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
		chip->dt.esr_tight_flt_upct, buf);
	rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
			chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_byte, buf,
			chip->sp[FG_SRAM_ESR_TIGHT_FILTER].len, FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("Error in writing ESR tight filter, rc=%d\n", rc);
		return rc;
	}

	fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
		chip->dt.esr_broad_flt_upct, buf);
	rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_word,
			chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_byte, buf,
			chip->sp[FG_SRAM_ESR_BROAD_FILTER].len, FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("Error in writing ESR broad filter, rc=%d\n", rc);
		return rc;
	}

	return 0;
}

@@ -2901,6 +2993,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
		return IRQ_HANDLED;
	}

	rc = fg_esr_filter_config(chip, batt_temp);
	if (rc < 0)
		pr_err("Error in configuring ESR filter rc:%d\n", rc);

	if (!is_charger_available(chip)) {
		chip->last_batt_temp = batt_temp;
		return IRQ_HANDLED;
@@ -3207,6 +3303,11 @@ static int fg_parse_ki_coefficients(struct fg_chip *chip)
#define DEFAULT_CL_MAX_LIM_DECIPERC	0
#define BTEMP_DELTA_LOW			2
#define BTEMP_DELTA_HIGH		10
#define DEFAULT_ESR_FLT_TEMP_DECIDEGC	100
#define DEFAULT_ESR_TIGHT_FLT_UPCT	3907
#define DEFAULT_ESR_BROAD_FLT_UPCT	99610
#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT	48829
#define DEFAULT_ESR_BROAD_LT_FLT_UPCT	148438
static int fg_parse_dt(struct fg_chip *chip)
{
	struct device_node *child, *revid_node, *node = chip->dev->of_node;
@@ -3483,6 +3584,40 @@ static int fg_parse_dt(struct fg_chip *chip)
	else
		chip->dt.rconn_mohms = temp;

	rc = of_property_read_u32(node, "qcom,fg-esr-filter-switch-temp",
			&temp);
	if (rc < 0)
		chip->dt.esr_flt_switch_temp = DEFAULT_ESR_FLT_TEMP_DECIDEGC;
	else
		chip->dt.esr_flt_switch_temp = temp;

	rc = of_property_read_u32(node, "qcom,fg-esr-tight-filter-micro-pct",
			&temp);
	if (rc < 0)
		chip->dt.esr_tight_flt_upct = DEFAULT_ESR_TIGHT_FLT_UPCT;
	else
		chip->dt.esr_tight_flt_upct = temp;

	rc = of_property_read_u32(node, "qcom,fg-esr-broad-filter-micro-pct",
			&temp);
	if (rc < 0)
		chip->dt.esr_broad_flt_upct = DEFAULT_ESR_BROAD_FLT_UPCT;
	else
		chip->dt.esr_broad_flt_upct = temp;

	rc = of_property_read_u32(node, "qcom,fg-esr-tight-lt-filter-micro-pct",
			&temp);
	if (rc < 0)
		chip->dt.esr_tight_lt_flt_upct = DEFAULT_ESR_TIGHT_LT_FLT_UPCT;
	else
		chip->dt.esr_tight_lt_flt_upct = temp;

	rc = of_property_read_u32(node, "qcom,fg-esr-broad-lt-filter-micro-pct",
			&temp);
	if (rc < 0)
		chip->dt.esr_broad_lt_flt_upct = DEFAULT_ESR_BROAD_LT_FLT_UPCT;
	else
		chip->dt.esr_broad_lt_flt_upct = temp;
	return 0;
}

@@ -3608,9 +3743,13 @@ static int fg_gen3_probe(struct platform_device *pdev)
	if (!rc)
		rc = fg_get_battery_temp(chip, &batt_temp);

	if (!rc)
	if (!rc) {
		pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
			msoc, volt_uv, batt_temp, chip->batt_id_ohms / 1000);
		rc = fg_esr_filter_config(chip, batt_temp);
		if (rc < 0)
			pr_err("Error in configuring ESR filter rc:%d\n", rc);
	}

	device_init_wakeup(chip->dev, true);
	if (chip->profile_available)