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

Commit f0ca633c authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: qpnp-fg-gen4: Support configuring ESR calibration during discharging



Add support to configure ESR calibration or measurements done
only during discharging. This configuration works mutually
exclusive to ESR fast calibration with the required parameters
specified by the user.

Change-Id: Id9f65e373b988af6dc60b12c932d1efaa81af42c
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent a1829f0c
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -154,6 +154,14 @@ First Level Node - FG Gen4 device
		    This factor will be used when ESR correction delta is
		    applied after the calculation. Default value is 2.

- qcom,fg-esr-calib-dischg:
	Usage:      optional
	Value type: <empty>
	Definition: Enables ESR calibration only during discharging. This
		    should be specified only when ESR fast calibration is not
		    required. Also, ESR discharging timers should be specified
		    for the proper functionality.

- qcom,fg-esr-pulse-thresh-ma
	Usage:      optional
	Value type: <u32>
+111 −59
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@
#define VBATT_LOW_OFFSET		1
#define SYS_CONFIG_WORD			60
#define SYS_CONFIG_OFFSET		0
#define SYS_CONFIG2_OFFSET		1
#define PROFILE_LOAD_WORD		65
#define PROFILE_LOAD_OFFSET		0
#define RSLOW_COEFF_DISCHG_WORD		78
@@ -193,6 +194,7 @@ struct fg_dt_props {
	bool	rapid_soc_dec_en;
	bool	five_pin_battery;
	bool	multi_profile_load;
	bool	esr_calib_dischg;
	int	cutoff_volt_mv;
	int	empty_volt_mv;
	int	cutoff_curr_ma;
@@ -3989,6 +3991,104 @@ static int fg_alg_init(struct fg_gen4_chip *chip)
	return 0;
}

static int fg_gen4_esr_calib_config(struct fg_gen4_chip *chip)
{
	struct fg_dev *fg = &chip->fg;
	u8 buf[2], val, mask;
	int rc;

	if (chip->esr_fast_calib) {
		rc = fg_gen4_esr_fast_calib_config(chip, true);
		if (rc < 0)
			return rc;
	} else {
		if (chip->dt.esr_timer_chg_slow[TIMER_RETRY] >= 0 &&
			chip->dt.esr_timer_chg_slow[TIMER_MAX] >= 0) {
			rc = fg_set_esr_timer(fg,
				chip->dt.esr_timer_chg_slow[TIMER_RETRY],
				chip->dt.esr_timer_chg_slow[TIMER_MAX], true,
				FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in setting ESR charge timer, rc=%d\n",
					rc);
				return rc;
			}
		}

		if (chip->dt.esr_timer_dischg_slow[TIMER_RETRY] >= 0 &&
			chip->dt.esr_timer_dischg_slow[TIMER_MAX] >= 0) {
			rc = fg_set_esr_timer(fg,
				chip->dt.esr_timer_dischg_slow[TIMER_RETRY],
				chip->dt.esr_timer_dischg_slow[TIMER_MAX],
				false, FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in setting ESR discharge timer, rc=%d\n",
					rc);
				return rc;
			}
		}

		if (chip->dt.esr_calib_dischg) {
			/* Allow ESR calibration only during discharging */
			val = BIT(6) | BIT(7);
			mask = BIT(1) | BIT(6) | BIT(7);
			rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD,
					SYS_CONFIG_OFFSET, mask, val,
					FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in writing SYS_CONFIG_WORD, rc=%d\n",
					rc);
				return rc;
			}

			/* Disable ESR charging timer */
			val = 0;
			mask = BIT(0);
			rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD,
					SYS_CONFIG2_OFFSET, mask, val,
					FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in writing SYS_CONFIG2_OFFSET, rc=%d\n",
					rc);
				return rc;
			}
		} else {
			/*
			 * Disable ESR discharging timer and ESR pulsing during
			 * discharging when ESR fast calibration is disabled.
			 */
			val = 0;
			mask = BIT(6) | BIT(7);
			rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD,
					SYS_CONFIG_OFFSET, mask, val,
					FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in writing SYS_CONFIG_WORD, rc=%d\n",
					rc);
				return rc;
			}
		}
	}

	/*
	 * Delta ESR interrupt threshold should be configured as specified if
	 * ESR fast calibration is disabled. Else, set it to max (4000 mOhms).
	 */
	fg_encode(fg->sp, FG_SRAM_DELTA_ESR_THR,
		chip->esr_fast_calib ? 4000000 : chip->dt.delta_esr_thr_uohms,
		buf);
	rc = fg_sram_write(fg,
			fg->sp[FG_SRAM_DELTA_ESR_THR].addr_word,
			fg->sp[FG_SRAM_DELTA_ESR_THR].addr_byte, buf,
			fg->sp[FG_SRAM_DELTA_ESR_THR].len, FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("Error in writing DELTA_ESR_THR, rc=%d\n", rc);
		return rc;
	}

	return rc;
}

#define BATT_TEMP_HYST_MASK	GENMASK(3, 0)
#define BATT_TEMP_DELTA_MASK	GENMASK(7, 4)
#define BATT_TEMP_DELTA_SHIFT	4
@@ -4234,66 +4334,9 @@ static int fg_gen4_hw_init(struct fg_gen4_chip *chip)
		}
	}

	if (chip->esr_fast_calib) {
		rc = fg_gen4_esr_fast_calib_config(chip, true);
	rc = fg_gen4_esr_calib_config(chip);
	if (rc < 0)
		return rc;
	} else {
		if (chip->dt.esr_timer_chg_slow[TIMER_RETRY] >= 0 &&
			chip->dt.esr_timer_chg_slow[TIMER_MAX] >= 0) {
			rc = fg_set_esr_timer(fg,
				chip->dt.esr_timer_chg_slow[TIMER_RETRY],
				chip->dt.esr_timer_chg_slow[TIMER_MAX], true,
				FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in setting ESR charge timer, rc=%d\n",
					rc);
				return rc;
			}
		}

		if (chip->dt.esr_timer_dischg_slow[TIMER_RETRY] >= 0 &&
			chip->dt.esr_timer_dischg_slow[TIMER_MAX] >= 0) {
			rc = fg_set_esr_timer(fg,
				chip->dt.esr_timer_dischg_slow[TIMER_RETRY],
				chip->dt.esr_timer_dischg_slow[TIMER_MAX],
				false, FG_IMA_DEFAULT);
			if (rc < 0) {
				pr_err("Error in setting ESR discharge timer, rc=%d\n",
					rc);
				return rc;
			}
		}

		/*
		 * Disable ESR discharging timer and ESR pulsing during
		 * discharging when ESR fast calibration is disabled.
		 */
		val = 0;
		mask = BIT(6) | BIT(7);
		rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD,
				SYS_CONFIG_OFFSET, mask, val, FG_IMA_DEFAULT);
		if (rc < 0) {
			pr_err("Error in writing SYS_CONFIG_WORD, rc=%d\n", rc);
			return rc;
		}
	}

	/*
	 * Delta ESR interrupt threshold should be configured as specified if
	 * ESR fast calibration is disabled. Else, set it to max (4000 mOhms).
	 */
	fg_encode(fg->sp, FG_SRAM_DELTA_ESR_THR,
		chip->esr_fast_calib ? 4000000 : chip->dt.delta_esr_thr_uohms,
		buf);
	rc = fg_sram_write(fg,
			fg->sp[FG_SRAM_DELTA_ESR_THR].addr_word,
			fg->sp[FG_SRAM_DELTA_ESR_THR].addr_byte, buf,
			fg->sp[FG_SRAM_DELTA_ESR_THR].len, FG_IMA_DEFAULT);
	if (rc < 0) {
		pr_err("Error in writing DELTA_ESR_THR, rc=%d\n", rc);
		return rc;
	}

	rc = restore_cycle_count(chip->counter);
	if (rc < 0) {
@@ -4440,6 +4483,15 @@ static int fg_parse_esr_cal_params(struct fg_dev *fg)
	struct device_node *node = fg->dev->of_node;
	int rc, i, temp;

	if (chip->dt.esr_timer_dischg_slow[TIMER_RETRY] >= 0 &&
			chip->dt.esr_timer_dischg_slow[TIMER_MAX] >= 0) {
		/* ESR calibration only during discharging */
		chip->dt.esr_calib_dischg = of_property_read_bool(node,
						"qcom,fg-esr-calib-dischg");
		if (chip->dt.esr_calib_dischg)
			return 0;
	}

	if (!of_find_property(node, "qcom,fg-esr-cal-soc-thresh", NULL) ||
		!of_find_property(node, "qcom,fg-esr-cal-temp-thresh", NULL))
		return 0;