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

Commit fe0ccc46 authored by Xiaozhe Shi's avatar Xiaozhe Shi
Browse files

power: qpnp-fg: configure charger termination current



If the charger is using the fuel gauge ADC current to determine end of
charge, the termination current should be configured in the fuel gauge
SRAM register (0x4F8, 2) to make it work properly. Allow this register
to be configured via the devicetree property qcom,fg-chg-iterm-ma.

CRs-Fixed: 804096
Change-Id: Idc04c4d6e7cbd70c8e6d3d56789337667cfdb6d7
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent 7eeceb01
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -54,6 +54,10 @@ Parent node optional properties:
					software. If this is not set, it will
					be controlled by hardware (default).
- qcom,fg-iterm-ma:			Battery current at which the fuel gauge
					will try to scale 100% towards. When
					the charge current goes above this, the
					SoC should be at 100%.
- qcom,fg-chg-iterm-ma:			Battery current at which the fuel gauge
					will issue end of charge if the charger
					is configured to use the fuel gauge
					ADCs for end of charge detection. This
+24 −4
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ enum fg_mem_setting_index {
	FG_MEM_BCL_LM_THRESHOLD,
	FG_MEM_BCL_MH_THRESHOLD,
	FG_MEM_TERM_CURRENT,
	FG_MEM_CHG_TERM_CURRENT,
	FG_MEM_IRQ_VOLT_EMPTY,
	FG_MEM_CUTOFF_VOLTAGE,
	FG_MEM_VBAT_EST_DIFF,
@@ -178,6 +179,7 @@ static struct fg_mem_setting settings[FG_MEM_SETTING_MAX] = {
	SETTING(BCL_LM_THRESHOLD, 0x47C,   2,      50),
	SETTING(BCL_MH_THRESHOLD, 0x47C,   3,      752),
	SETTING(TERM_CURRENT,	 0x40C,   2,      250),
	SETTING(CHG_TERM_CURRENT, 0x4F8,   2,      250),
	SETTING(IRQ_VOLT_EMPTY,	 0x458,   3,      3100),
	SETTING(CUTOFF_VOLTAGE,	 0x40C,   0,      3200),
	SETTING(VBAT_EST_DIFF,	 0x000,   0,      30),
@@ -2567,10 +2569,28 @@ done:
	return rc;
}

#define V_PREDICTED_ADDR		0x540
#define V_CURRENT_PREDICTED_OFFSET	0
#define MICROUNITS_TO_ADC_RAW(units)	\
			div64_s64(units * LSB_16B_DENMTR, LSB_16B_NUMRTR)
static int update_chg_iterm(struct fg_chip *chip)
{
	u8 data[2];
	u16 converted_current_raw;
	s64 current_ma = -settings[FG_MEM_CHG_TERM_CURRENT].value;

	converted_current_raw = (s16)MICROUNITS_TO_ADC_RAW(current_ma * 1000);
	data[0] = cpu_to_le16(converted_current_raw) & 0xFF;
	data[1] = cpu_to_le16(converted_current_raw) >> 8;

	if (fg_debug_mask & FG_STATUS)
		pr_info("current = %lld, converted_raw = %04x, data = %02x %02x\n",
			current_ma, converted_current_raw, data[0], data[1]);
	return fg_mem_write(chip, data,
			settings[FG_MEM_CHG_TERM_CURRENT].address,
			2, settings[FG_MEM_CHG_TERM_CURRENT].offset, 0);
}

#define V_PREDICTED_ADDR		0x540
#define V_CURRENT_PREDICTED_OFFSET	0
#define LOW_LATENCY	BIT(6)
#define PROFILE_LOAD_TIMEOUT_MS		5000
#define BATT_PROFILE_OFFSET		0x4C0
@@ -2839,6 +2859,7 @@ done:
	chip->first_profile_loaded = true;
	chip->profile_loaded = true;
	chip->battery_missing = is_battery_missing(chip);
	update_chg_iterm(chip);
	rc = populate_learning_data(chip);
	if (rc) {
		pr_err("failed to read ocv properties=%d\n", rc);
@@ -2919,8 +2940,6 @@ static int update_irq_volt_empty(struct fg_chip *chip)
			settings[FG_MEM_IRQ_VOLT_EMPTY].offset, 0);
}

#define MICROUNITS_TO_ADC_RAW(units)	\
			div64_s64(units * LSB_16B_DENMTR, LSB_16B_NUMRTR)
static int update_cutoff_voltage(struct fg_chip *chip)
{
	u8 data[2];
@@ -3005,6 +3024,7 @@ static int fg_of_init(struct fg_chip *chip)
	OF_READ_SETTING(FG_MEM_BCL_MH_THRESHOLD, "bcl-mh-threshold-ma",
		rc, 1);
	OF_READ_SETTING(FG_MEM_TERM_CURRENT, "fg-iterm-ma", rc, 1);
	OF_READ_SETTING(FG_MEM_CHG_TERM_CURRENT, "fg-chg-iterm-ma", rc, 1);
	OF_READ_SETTING(FG_MEM_CUTOFF_VOLTAGE, "fg-cutoff-voltage-mv", rc, 1);
	data = of_get_property(chip->spmi->dev.of_node,
			"qcom,thermal-coefficients", &len);