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

Commit 22260a8a authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: qpnp-fg-gen4: Calculate Rbatt for 5-pin battery to support TTF



Currently, battery resistance (Rbatt) is provided based on ESR
and Rslow measured by FG. However 5-pin battery can be used on
some SM8150 platforms where Rprot from protective circuit should
be taken into account when Rbatt is used in TTF (Time to Full)
algorithm.

Add support for it through "qcom,five-pin-battery" property.

Change-Id: I3c7dc190c72beff5d4a687891d8e4d72cae047d5
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent afb9e688
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -368,6 +368,13 @@ First Level Node - FG Gen4 device
		    decrease when the battery SOC is low but not converging to
		    zero with battery voltage dropping rapidly below Vcutoff.

- qcom,five-pin-battery
	Usage:      optional
	Value type: <empty>
	Definition: A boolean property that when specified indicates that a
		    five pin battery is used. Based on this, time to full
		    calculations would use the Rbatt calculated properly.

==========================================================
Second Level Nodes - Peripherals managed by FG Gen4 driver
==========================================================
+4 −0
Original line number Diff line number Diff line
@@ -174,6 +174,8 @@ enum fg_sram_param_id {
	FG_SRAM_MONOTONIC_SOC,
	FG_SRAM_VOLTAGE_PRED,
	FG_SRAM_OCV,
	FG_SRAM_VBAT_FINAL,
	FG_SRAM_IBAT_FINAL,
	FG_SRAM_ESR,
	FG_SRAM_ESR_MDL,
	FG_SRAM_ESR_ACT,
@@ -491,6 +493,8 @@ struct fg_dbgfs {

extern int fg_decode_voltage_15b(struct fg_sram_param *sp,
	enum fg_sram_param_id id, int val);
extern int fg_decode_current_16b(struct fg_sram_param *sp,
	enum fg_sram_param_id id, int val);
extern int fg_decode_cc_soc(struct fg_sram_param *sp,
	enum fg_sram_param_id id, int value);
extern int fg_decode_value_16b(struct fg_sram_param *sp,
+10 −0
Original line number Diff line number Diff line
@@ -38,6 +38,16 @@ int fg_decode_voltage_15b(struct fg_sram_param *sp,
	return sp[id].value;
}

int fg_decode_current_16b(struct fg_sram_param *sp,
				enum fg_sram_param_id id, int value)
{
	value = sign_extend32(value, 15);
	sp[id].value = div_s64((s64)value * sp[id].denmtr, sp[id].numrtr);
	pr_debug("id: %d raw value: %x decoded value: %d\n", id, value,
		sp[id].value);
	return sp[id].value;
}

int fg_decode_cc_soc(struct fg_sram_param *sp,
				enum fg_sram_param_id id, int value)
{
+65 −4
Original line number Diff line number Diff line
@@ -119,6 +119,10 @@
#define CYCLE_COUNT_OFFSET		0
#define PROFILE_INTEGRITY_WORD		299
#define PROFILE_INTEGRITY_OFFSET	0
#define IBAT_FINAL_WORD			320
#define IBAT_FINAL_OFFSET		0
#define VBAT_FINAL_WORD			321
#define VBAT_FINAL_OFFSET		0
#define ESR_WORD			331
#define ESR_OFFSET			0
#define ESR_MDL_WORD			335
@@ -180,6 +184,7 @@ struct fg_dt_props {
	bool	hold_soc_while_full;
	bool	linearize_soc;
	bool	rapid_soc_dec_en;
	bool	five_pin_battery;
	int	cutoff_volt_mv;
	int	empty_volt_mv;
	int	cutoff_curr_ma;
@@ -286,6 +291,10 @@ static struct fg_sram_param pm8150b_v1_sram_params[] = {
		244141, 0, NULL, fg_decode_voltage_15b),
	PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 1000, 244141, 0, NULL,
		fg_decode_voltage_15b),
	PARAM(VBAT_FINAL, VBAT_FINAL_WORD, VBAT_FINAL_OFFSET, 2, 1000, 244141,
		0, NULL, fg_decode_voltage_15b),
	PARAM(IBAT_FINAL, IBAT_FINAL_WORD, IBAT_FINAL_OFFSET, 2, 1000, 488282,
		0, NULL, fg_decode_current_16b),
	PARAM(ESR, ESR_WORD, ESR_OFFSET, 2, 1000, 244141, 0, fg_encode_default,
		fg_decode_value_16b),
	PARAM(ESR_MDL, ESR_MDL_WORD, ESR_MDL_OFFSET, 2, 1000, 244141, 0,
@@ -374,6 +383,10 @@ static struct fg_sram_param pm8150b_v2_sram_params[] = {
		1000, 244141, 0, NULL, fg_decode_voltage_15b),
	PARAM(OCV, OCV_v2_WORD, OCV_v2_OFFSET, 2, 1000, 244141, 0, NULL,
		fg_decode_voltage_15b),
	PARAM(VBAT_FINAL, VBAT_FINAL_WORD, VBAT_FINAL_OFFSET, 2, 1000, 244141,
		0, NULL, fg_decode_voltage_15b),
	PARAM(IBAT_FINAL, IBAT_FINAL_WORD, IBAT_FINAL_OFFSET, 2, 1000, 488282,
		0, NULL, fg_decode_current_16b),
	PARAM(ESR, ESR_WORD, ESR_OFFSET, 2, 1000, 244141, 0, fg_encode_default,
		fg_decode_value_16b),
	PARAM(ESR_MDL, ESR_MDL_WORD, ESR_MDL_OFFSET, 2, 1000, 244141, 0,
@@ -693,6 +706,51 @@ static bool is_debug_batt_id(struct fg_dev *fg)
	return false;
}

static int fg_gen4_get_cell_impedance(struct fg_gen4_chip *chip, int *val)
{
	struct fg_dev *fg = &chip->fg;
	int rc, esr_uohms, temp, vbat_term_mv, v_delta, rprot_uohms = 0;

	rc = fg_get_battery_resistance(fg, &esr_uohms);
	if (rc < 0)
		return rc;

	if (!chip->dt.five_pin_battery)
		goto out;

	if (fg->charge_type != POWER_SUPPLY_CHARGE_TYPE_TAPER ||
		fg->bp.float_volt_uv <= 0)
		goto out;

	rc = fg_get_battery_voltage(fg, &vbat_term_mv);
	if (rc < 0)
		goto out;

	rc = fg_get_sram_prop(fg, FG_SRAM_VBAT_FINAL, &temp);
	if (rc < 0) {
		pr_err("Error in getting VBAT_FINAL rc:%d\n", rc);
		goto out;
	}

	v_delta = abs(temp - fg->bp.float_volt_uv);

	rc = fg_get_sram_prop(fg, FG_SRAM_IBAT_FINAL, &temp);
	if (rc < 0) {
		pr_err("Error in getting IBAT_FINAL rc:%d\n", rc);
		goto out;
	}

	if (!temp)
		goto out;

	rprot_uohms = div64_u64((u64)v_delta * 1000000, abs(temp));
	pr_debug("v_delta: %d ibat_final: %d rprot_uohms: %d\n", v_delta, temp,
		rprot_uohms);
out:
	*val = esr_uohms - rprot_uohms;
	return rc;
}

static int fg_gen4_get_prop_capacity(struct fg_dev *fg, int *val)
{
	struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg);
@@ -812,7 +870,7 @@ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val)
		*val = chip->dt.sys_term_curr_ma;
		break;
	case TTF_RBATT:
		rc = fg_get_battery_resistance(fg, val);
		rc = fg_gen4_get_cell_impedance(chip, val);
		break;
	case TTF_VFLOAT:
		*val = fg->bp.float_volt_uv;
@@ -2454,13 +2512,13 @@ static irqreturn_t fg_delta_esr_irq_handler(int irq, void *data)
{
	struct fg_dev *fg = data;
	struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg);
	int esr_mohms, rc;
	int esr_uohms, rc;

	rc = fg_get_battery_resistance(fg, &esr_mohms);
	rc = fg_get_battery_resistance(fg, &esr_uohms);
	if (rc < 0)
		return IRQ_HANDLED;

	fg_dbg(fg, FG_IRQ, "irq %d triggered esr_mohms: %d\n", irq, esr_mohms);
	fg_dbg(fg, FG_IRQ, "irq %d triggered esr_uohms: %d\n", irq, esr_uohms);

	if (chip->esr_fast_calib) {
		vote(fg->awake_votable, ESR_CALIB, true, 0);
@@ -4544,6 +4602,9 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip)

	chip->dt.rapid_soc_dec_en = of_property_read_bool(node,
					"qcom,rapid-soc-dec-en");

	chip->dt.five_pin_battery = of_property_read_bool(node,
					"qcom,five-pin-battery");
	return 0;
}