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

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

qpnp-fg-gen3: Read debug battery id thresholds from RR_ADC registers



Currently, GEN3 FG driver uses a debug battery id threshold of
7 KOhms. However, depending on the battery id chosen by the user
this threshold can be modified in the bootloader. Hence, add
support to read the debug battery id thresholds directly from
RR_ADC peripheral registers. This can be used to decide whether
a fake battery SOC (67) can be displayed to the user.

Change-Id: I22ab702e10c310e4f847c6c81a48a8f0f3188429
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent c297f6de
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ First Level Node - FG Gen3 device
	Definition: For details about IIO bindings see:
		    Documentation/devicetree/bindings/iio/iio-bindings.txt

- qcom,rradc-base
	Usage:      required
	Value type: <u32>
	Definition: Should specify the base address of RR_ADC peripheral. This
		    is used for reading certain peripheral registers under it.

- qcom,fg-cutoff-voltage
	Usage:      optional
	Value type: <u32>
@@ -297,6 +303,7 @@ pmi8998_fg: qpnp,fg {
	qcom,pmic-revid = <&pmi8998_revid>;
	io-channels = <&pmi8998_rradc 3>;
	io-channel-names = "rradc_batt_id";
	qcom,rradc-base = <0x4500>;
	qcom,ki-coeff-soc-dischg = <30 60 90>;
	qcom,ki-coeff-med-dischg = <800 1000 1400>;
	qcom,ki-coeff-hi-dischg = <1200 1500 2100>;
+8 −1
Original line number Diff line number Diff line
@@ -39,6 +39,12 @@
			pr_debug(fmt, ##__VA_ARGS__);	\
	} while (0)

#define is_between(left, right, value) \
		(((left) >= (right) && (left) >= (value) \
			&& (value) >= (right)) \
		|| ((left) <= (right) && (left) <= (value) \
			&& (value) <= (right)))

/* Awake votable reasons */
#define SRAM_READ	"fg_sram_read"
#define SRAM_WRITE	"fg_sram_write"
@@ -311,8 +317,9 @@ struct fg_chip {
	u32			batt_soc_base;
	u32			batt_info_base;
	u32			mem_if_base;
	u32			rradc_base;
	u32			wa_flags;
	int			batt_id_kohms;
	int			batt_id_ohms;
	int			charge_status;
	int			prev_charge_status;
	int			charge_done;
+4 −0
Original line number Diff line number Diff line
@@ -13,6 +13,10 @@
#ifndef __FG_REG_H__
#define __FG_REG_H__

/* FG_ADC_RR register definitions used only for READ */
#define ADC_RR_FAKE_BATT_LOW_LSB(chip)		(chip->rradc_base + 0x58)
#define ADC_RR_FAKE_BATT_HIGH_LSB(chip)		(chip->rradc_base + 0x5A)

/* FG_BATT_SOC register definitions */
#define BATT_SOC_FG_ALG_STS(chip)		(chip->batt_soc_base + 0x06)
#define BATT_SOC_FG_ALG_AUX_STS0(chip)		(chip->batt_soc_base + 0x07)
+56 −10
Original line number Diff line number Diff line
@@ -698,18 +698,57 @@ static bool is_batt_empty(struct fg_chip *chip)
	return ((vbatt_uv < chip->dt.cutoff_volt_mv * 1000) ? true : false);
}

#define DEBUG_BATT_ID_KOHMS	7
static int fg_get_debug_batt_id(struct fg_chip *chip, int *batt_id)
{
	int rc;
	u64 temp;
	u8 buf[2];

	rc = fg_read(chip, ADC_RR_FAKE_BATT_LOW_LSB(chip), buf, 2);
	if (rc < 0) {
		pr_err("failed to read addr=0x%04x, rc=%d\n",
			ADC_RR_FAKE_BATT_LOW_LSB(chip), rc);
		return rc;
	}

	/*
	 * Fake battery threshold is encoded in the following format.
	 * Threshold (code) = (battery_id in Ohms) * 0.00015 * 2^10 / 2.5
	 */
	temp = (buf[1] << 8 | buf[0]) * 2500000;
	do_div(temp, 150 * 1024);
	batt_id[0] = temp;
	rc = fg_read(chip, ADC_RR_FAKE_BATT_HIGH_LSB(chip), buf, 2);
	if (rc < 0) {
		pr_err("failed to read addr=0x%04x, rc=%d\n",
			ADC_RR_FAKE_BATT_HIGH_LSB(chip), rc);
		return rc;
	}

	temp = (buf[1] << 8 | buf[0]) * 2500000;
	do_div(temp, 150 * 1024);
	batt_id[1] = temp;
	pr_debug("debug batt_id range: [%d %d]\n", batt_id[0], batt_id[1]);
	return 0;
}

static bool is_debug_batt_id(struct fg_chip *chip)
{
	int batt_id_delta = 0;
	int debug_batt_id[2], rc;

	if (!chip->batt_id_kohms)
	if (!chip->batt_id_ohms)
		return false;

	batt_id_delta = abs(chip->batt_id_kohms - DEBUG_BATT_ID_KOHMS);
	if (batt_id_delta <= 1) {
		fg_dbg(chip, FG_POWER_SUPPLY, "Debug battery id: %dKohms\n",
			chip->batt_id_kohms);
	rc = fg_get_debug_batt_id(chip, debug_batt_id);
	if (rc < 0) {
		pr_err("Failed to get debug batt_id, rc=%d\n", rc);
		return false;
	}

	if (is_between(debug_batt_id[0], debug_batt_id[1],
		chip->batt_id_ohms)) {
		fg_dbg(chip, FG_POWER_SUPPLY, "Debug battery id: %dohms\n",
			chip->batt_id_ohms);
		return true;
	}

@@ -797,8 +836,8 @@ static int fg_get_batt_profile(struct fg_chip *chip)
		return rc;
	}

	chip->batt_id_ohms = batt_id;
	batt_id /= 1000;
	chip->batt_id_kohms = batt_id;
	batt_node = of_find_node_by_name(node, "qcom,battery-data");
	if (!batt_node) {
		pr_err("Batterydata not available\n");
@@ -3163,10 +3202,17 @@ static int fg_parse_dt(struct fg_chip *chip)
		}
	}

	rc = of_property_read_u32(node, "qcom,rradc-base", &base);
	if (rc < 0) {
		dev_err(chip->dev, "rradc-base not specified, rc=%d\n", rc);
		return rc;
	}
	chip->rradc_base = base;

	rc = fg_get_batt_profile(chip);
	if (rc < 0)
		pr_warn("profile for batt_id=%dKOhms not found..using OTP, rc:%d\n",
			chip->batt_id_kohms, rc);
			chip->batt_id_ohms / 1000, rc);

	/* Read all the optional properties below */
	rc = of_property_read_u32(node, "qcom,fg-cutoff-voltage", &temp);
@@ -3455,7 +3501,7 @@ static int fg_gen3_probe(struct platform_device *pdev)

	if (!rc)
		pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
			msoc, volt_uv, batt_temp, chip->batt_id_kohms);
			msoc, volt_uv, batt_temp, chip->batt_id_ohms / 1000);

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