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

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

power: qpnp-bms: detect battery removal in offmode



Use the smbb battery interface driver's bat_pres_status battery
removal circuit to detect whether a battery has been removed when
the device is powered off.

Change-Id: Ifb219455d2f563c6052ec9e8e8c690dd12070c2f
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent 86155e46
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -13,7 +13,11 @@ device is to enabled:
		to determine whether the BMS is using an internal or external
		rsense to accumulate the Coulomb Counter and read current.

Additionally, an optional subnode may be included:
Additionally, optional subnodes may be included:
- qcom,batt-pres-status : A subnode with a register address for the SMBB
		battery interface's BATT_PRES_STATUS register. If this node is
		added, then the BMS will try to detect offmode battery removal
		via the battery interface's offmode battery removal circuit.
- qcom,battery-data : A phandle to a node containing the available batterydata
		profiles. See the batterydata bindings documentation for more
		details.
@@ -75,8 +79,8 @@ Parent node required properties:
- qcom,min-fcc-learning-soc: An interger value which defines the minimum SOC
			to start FCC learning. This is applicable only if
			FCC learning is enabled.
- qcom,min-fcc-ocv-pc:	An interger value which defines the minimum PC-lookup(OCV)
			to start FCC learning. This is applicable only if
- qcom,min-fcc-ocv-pc:	An interger value which defines the minimum PC-lookup
			(OCV) to start FCC learning. This is applicable only if
			FCC learning is enabled.
- qcom,min-fcc-learning-samples: An interger value which defines the minimum
			number of the FCC measurement cycles required to
@@ -103,14 +107,19 @@ Parent node optional properties:
- qcom,use-ocv-thresholds : A boolean that controls whether BMS will take
			new OCVs only between the defined thresholds.
- qcom,enable-fcc-learning: A boolean that defines if FCC learning is enabled.
- qcom,bms-adc_tm: Corresponding ADC_TM device's phandle to set recurring measurements
		and receive notifications for die_temperature, vbatt.
- qcom,bms-adc_tm: Corresponding ADC_TM device's phandle to set recurring
			measurements and receive notifications for
			die_temperature and vbatt.

qcom,batt-pres-status node required properties:
- reg : offset and length of the PMIC SMBB battery interface BATT_PRES_STATUS
		register.

All sub node required properties:
qcom,bms-iadc node required properties:
- reg : offset and length of the PMIC peripheral register map.

qcom,bms-bms node required properties:
- reg : offset and length of the PMIC peripheral register map.
- interrupts : the interrupt mappings.
		The format should be
		<slave-id peripheral-id interrupt-number>.
@@ -156,6 +165,10 @@ pm8941_bms: qcom,bms {
	qcom,bms-iadc = <&pm8941_iadc>;
	qcom,bms-adc_tm = <&pm8941_adc_tm>;

	qcom,batt-pres-status@1208 {
		reg = <0x1208 0x1>;
	}

	qcom,bms-iadc@3800 {
		reg = <0x3800 0x100>;
	};
+22 −2
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ struct qpnp_bms_chip {
	wait_queue_head_t		bms_wait_queue;
	u16				base;
	u16				iadc_base;
	u16				batt_pres_addr;

	u8				revision1;
	u8				revision2;
@@ -3233,6 +3234,7 @@ static int set_ocv_voltage_thresholds(struct qpnp_bms_chip *chip,
	return 0;
}

#define BAT_REMOVED_OFFMODE_BIT		BIT(6)
static void read_shutdown_soc_and_iavg(struct qpnp_bms_chip *chip)
{
	int rc;
@@ -3265,6 +3267,7 @@ static void read_shutdown_soc_and_iavg(struct qpnp_bms_chip *chip)

		rc = qpnp_read_wrapper(chip, &temp,
				chip->base + SOC_STORAGE_REG, 1);
		pr_debug("stored soc = %d\n", temp);
		if (rc) {
			pr_err("failed to read addr = %d %d\n",
					chip->base + SOC_STORAGE_REG, rc);
@@ -3282,10 +3285,19 @@ static void read_shutdown_soc_and_iavg(struct qpnp_bms_chip *chip)
	/* read the SOC storage to determine if there was a battery removal */
	rc = qpnp_read_wrapper(chip, &temp, chip->base + SOC_STORAGE_REG, 1);
	if (!rc) {
		if (temp == SOC_INVALID)
		if (temp == SOC_INVALID) {
			chip->battery_removed = true;
			chip->shutdown_soc_invalid = true;
		}
	}
	if (chip->batt_pres_addr) {
		rc = qpnp_read_wrapper(chip, &temp, chip->batt_pres_addr, 1);
		pr_debug("offmode removed: %02x\n", temp);
		if (!rc && (temp & BAT_REMOVED_OFFMODE_BIT)) {
			chip->battery_removed = true;
			chip->shutdown_soc_invalid = true;
		}
	}


	pr_debug("shutdown_soc = %d shutdown_iavg = %d shutdown_soc_invalid = %d, battery_removed = %d\n",
			chip->shutdown_soc,
@@ -3644,6 +3656,14 @@ static int register_spmi(struct qpnp_bms_chip *chip, struct spmi_device *spmi)
			return -ENXIO;
		}

		pr_debug("Node name = %s\n", spmi_resource->of_node->name);

		if (strcmp("qcom,batt-pres-status",
					spmi_resource->of_node->name) == 0) {
			chip->batt_pres_addr = resource->start;
			continue;
		}

		rc = qpnp_read_wrapper(chip, &type,
				resource->start + REG_OFFSET_PERP_TYPE, 1);
		if (rc) {