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

Commit 9b4d0765 authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: qpnp-qg: Add ESR estimation



Add support for online ESR (equivalent series resistance)
estimation for the battery. It is currently enabled during
charge.

The QG driver periodically (configurable) fires ESR
pulses and calculates the ESR. The ESR is qualified and
filtered before passing it to the userspace for further
processing. The processed values from userspace are
stored back into SDAM for subsequent reboots.

While at it, also add a few DT properties for ESR and update
the capacity learning default values.

Change-Id: Ic343f0d8a0109020fe384089355cfbe9a92f9a78
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 8fc190af
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -262,6 +262,39 @@ First Level Node - QGAUGE device
		    capacity learning cycle. If this is not specified, then
		    the default value is 0. Unit is in decipercentage.

- qcom,esr-disable
	Usage:      optional
	Value type: <bool>
	Definition: Boolean property to disable ESR estimation. If not defined
		    ESR estimation stays enabled for charge-cycles.

- qcom,esr-discharge-enable
	Usage:      optional
	Value type: <bool>
	Definition: Boolean property to enable ESR estimation during discharge.
		    Only valid if 'qcom,esr-disable' is not defined.

- qcom,esr-qual-current-ua
	Usage:      optional
	Value type: <u32>
	Definition: Minimum current differential in uA to qualify an ESR
		    reading as valid. If not defined the value defaults
		    to 130mA.

- qcom,esr-qual-vbatt-uv
	Usage:      optional
	Value type: <u32>
	Definition: Minimum vbatt differential in uV to qualify an ESR
		    reading as valid. If not defined the value defaults
		    to 7mV.

- qcom,esr-disable-soc
	Usage:      optional
	Value type: <u32>
	Definition: Minimum battery SOC below which ESR will not be
		    attempted by QG. If not defined the value defaults
		    to 10%.

==========================================================
Second Level Nodes - Peripherals managed by QGAUGE driver
==========================================================
+20 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@

#include <linux/kernel.h>
#include "fg-alg.h"
#include "qg-defs.h"

struct qg_batt_props {
	const char		*batt_type_str;
@@ -50,10 +51,24 @@ struct qg_dt {
	int			rbat_conn_mohm;
	int			ignore_shutdown_soc_secs;
	int			cold_temp_threshold;
	int			esr_qual_i_ua;
	int			esr_qual_v_uv;
	int			esr_disable_soc;
	bool			hold_soc_while_full;
	bool			linearize_soc;
	bool			cl_disable;
	bool			cl_feedback_on;
	bool			esr_disable;
	bool			esr_discharge_enable;
};

struct qg_esr_data {
	u32			pre_esr_v;
	u32			pre_esr_i;
	u32			post_esr_v;
	u32			post_esr_i;
	u32			esr;
	bool			valid;
};

struct qpnp_qg {
@@ -87,6 +102,7 @@ struct qpnp_qg {
	struct power_supply	*batt_psy;
	struct power_supply	*usb_psy;
	struct power_supply	*parallel_psy;
	struct qg_esr_data	esr_data[QG_MAX_ESR_COUNT];

	/* status variable */
	u32			*debug_mask;
@@ -103,9 +119,12 @@ struct qpnp_qg {
	int			charge_status;
	int			charge_type;
	int			next_wakeup_ms;
	u32			fifo_done_count;
	u32			wa_flags;
	u32			seq_no;
	u32			charge_counter_uah;
	u32			esr_avg;
	u32			esr_last;
	ktime_t			last_user_update_time;
	ktime_t			last_fifo_update_time;

@@ -147,6 +166,7 @@ enum debug_mask {
	QG_DEBUG_BUS_READ	= BIT(8),
	QG_DEBUG_BUS_WRITE	= BIT(9),
	QG_DEBUG_ALG_CL		= BIT(10),
	QG_DEBUG_ESR		= BIT(11),
};

enum qg_irq {
+3 −0
Original line number Diff line number Diff line
@@ -44,6 +44,9 @@
#define UV_TO_DECIUV(a)			(a / 100)
#define DECIUV_TO_UV(a)			(a * 100)

#define QG_MAX_ESR_COUNT		10
#define QG_MIN_ESR_COUNT		2

#define CAP(min, max, value)			\
		((min > value) ? min : ((value > max) ? max : value))

+26 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#define QG_STATUS1_REG				0x08
#define BATTERY_PRESENT_BIT			BIT(0)
#define ESR_MEAS_DONE_BIT			BIT(4)

#define QG_STATUS2_REG				0x09
#define GOOD_OCV_BIT				BIT(1)
@@ -25,6 +26,9 @@
#define QG_STATUS3_REG				0x0A
#define COUNT_FIFO_RT_MASK			GENMASK(3, 0)

#define QG_STATUS4_REG				0x0B
#define ESR_MEAS_IN_PROGRESS_BIT		BIT(4)

#define QG_INT_RT_STS_REG			0x10
#define FIFO_UPDATE_DONE_RT_STS_BIT		BIT(3)
#define VBAT_LOW_INT_RT_STS_BIT			BIT(1)
@@ -60,11 +64,19 @@
#define QG_S3_ENTRY_IBAT_THRESHOLD_REG		0x5E
#define QG_S3_EXIT_IBAT_THRESHOLD_REG		0x5F

#define QG_ESR_MEAS_TRIG_REG			0x68
#define HW_ESR_MEAS_START_BIT			BIT(0)

#define QG_S7_PON_OCV_V_DATA0_REG		0x70
#define QG_S7_PON_OCV_I_DATA0_REG		0x72
#define QG_S3_GOOD_OCV_V_DATA0_REG		0x74
#define QG_S3_GOOD_OCV_I_DATA0_REG		0x76

#define QG_PRE_ESR_V_DATA0_REG			0x78
#define QG_PRE_ESR_I_DATA0_REG			0x7A
#define QG_POST_ESR_V_DATA0_REG			0x7C
#define QG_POST_ESR_I_DATA0_REG			0x7E

#define QG_V_ACCUM_DATA0_RT_REG			0x88
#define QG_I_ACCUM_DATA0_RT_REG			0x8B
#define QG_ACCUM_CNT_RT_REG			0x8E
@@ -80,15 +92,19 @@
#define QG_LAST_S3_SLEEP_V_DATA0_REG		0xCC

/* SDAM offsets */
#define QG_SDAM_VALID_OFFSET			0x46
#define QG_SDAM_SOC_OFFSET			0x47
#define QG_SDAM_TEMP_OFFSET			0x48
#define QG_SDAM_RBAT_OFFSET			0x4A
#define QG_SDAM_OCV_OFFSET			0x4C
#define QG_SDAM_IBAT_OFFSET			0x50
#define QG_SDAM_TIME_OFFSET			0x54
#define QG_SDAM_CYCLE_COUNT_OFFSET		0x58
#define QG_SDAM_LEARNED_CAPACITY_OFFSET		0x68
#define QG_SDAM_PON_OCV_OFFSET			0x7C
#define QG_SDAM_VALID_OFFSET			0x46 /* 1-byte 0x46 */
#define QG_SDAM_SOC_OFFSET			0x47 /* 1-byte 0x47 */
#define QG_SDAM_TEMP_OFFSET			0x48 /* 2-byte 0x48-0x49 */
#define QG_SDAM_RBAT_OFFSET			0x4A /* 2-byte 0x4A-0x4B */
#define QG_SDAM_OCV_OFFSET			0x4C /* 4-byte 0x4C-0x4F */
#define QG_SDAM_IBAT_OFFSET			0x50 /* 4-byte 0x50-0x53 */
#define QG_SDAM_TIME_OFFSET			0x54 /* 4-byte 0x54-0x57 */
#define QG_SDAM_CYCLE_COUNT_OFFSET		0x58 /* 16-byte 0x58-0x67 */
#define QG_SDAM_LEARNED_CAPACITY_OFFSET		0x68 /* 2-byte 0x68-0x69 */
#define QG_SDAM_ESR_CHARGE_DELTA_OFFSET		0x6A /* 4-byte 0x6A-0x6D */
#define QG_SDAM_ESR_DISCHARGE_DELTA_OFFSET	0x6E /* 4-byte 0x6E-0x71 */
#define QG_SDAM_ESR_CHARGE_SF_OFFSET		0x72 /* 2-byte 0x72-0x73 */
#define QG_SDAM_ESR_DISCHARGE_SF_OFFSET		0x74 /* 2-byte 0x74-0x75 */
#define QG_SDAM_PON_OCV_OFFSET			0x7C /* 2-byte 0x7C-0x7D */

#endif
+20 −0
Original line number Diff line number Diff line
@@ -68,6 +68,26 @@ static struct qg_sdam_info sdam_info[] = {
		.offset = QG_SDAM_PON_OCV_OFFSET,
		.length = 2,
	},
	[SDAM_ESR_CHARGE_DELTA] = {
		.name	= "SDAM_ESR_CHARGE_DELTA",
		.offset = QG_SDAM_ESR_CHARGE_DELTA_OFFSET,
		.length = 4,
	},
	[SDAM_ESR_DISCHARGE_DELTA] = {
		.name	= "SDAM_ESR_DISCHARGE_DELTA",
		.offset = QG_SDAM_ESR_DISCHARGE_DELTA_OFFSET,
		.length = 4,
	},
	[SDAM_ESR_CHARGE_SF] = {
		.name	= "SDAM_ESR_CHARGE_SF_OFFSET",
		.offset = QG_SDAM_ESR_CHARGE_SF_OFFSET,
		.length = 2,
	},
	[SDAM_ESR_DISCHARGE_SF] = {
		.name	= "SDAM_ESR_DISCHARGE_SF_OFFSET",
		.offset = QG_SDAM_ESR_DISCHARGE_SF_OFFSET,
		.length = 2,
	},
};

int qg_sdam_write(u8 param, u32 data)
Loading