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

Commit 697c2775 authored by David Keitel's avatar David Keitel
Browse files

power: qpnp-charger: use iadc for ibat trim logic



The CURRENT_NOW property provided through BMS
only provides averaged ibat values. This is not
ideal for the ibat trim logic which requires
instantenous current readings.

Fix this by using the iadc peripheral to read
the INTERNAL_RSENSE or EXTERNAL_RSENSE channel.

Change-Id: I654f8b0d17e081bd7bc572165ac619a7d412bdaf
Signed-off-by: default avatarDavid Keitel <dkeitel@codeaurora.org>
parent 745417f2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -100,6 +100,9 @@ Parent node optional properties:
					around reduces the power stage segments while charging
					under high load during low battery voltages. It's for
					improving IADC accuracy while board has a bad layout.
- qcom,use-external-rsense		A boolean that controls whether BMS will use
					an external sensor resistor instead of the default
					RDS of the batfet.

Sub node required structure:
- A qcom,chg node must be a child of an SPMI node that has specified
+1 −0
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@
		qcom,resume-soc = <99>;
		qcom,tchg-mins = <150>;
		qcom,chg-vadc = <&pm8941_vadc>;
		qcom,chg-iadc = <&pm8941_iadc>;
		qcom,chg-adc_tm = <&pm8941_adc_tm>;
		qcom,ibat-calibration-enabled;

+41 −2
Original line number Diff line number Diff line
@@ -315,6 +315,7 @@ struct qpnp_chg_chip {
	bool				duty_cycle_100p;
	bool				ibat_calibration_enabled;
	bool				aicl_settled;
	bool				use_external_rsense;
	unsigned int			bpd_detection;
	unsigned int			max_bat_chg_current;
	unsigned int			warm_bat_chg_ma;
@@ -367,6 +368,7 @@ struct qpnp_chg_chip {
	bool				batfet_ext_en;
	struct work_struct		batfet_lcl_work;
	struct qpnp_vadc_chip		*vadc_dev;
	struct qpnp_iadc_chip		*iadc_dev;
	struct qpnp_adc_tm_chip		*adc_tm_dev;
	struct mutex			jeita_configure_lock;
	struct mutex			batfet_vreg_lock;
@@ -2449,11 +2451,20 @@ static void
qpnp_chg_trim_ibat(struct qpnp_chg_chip *chip, u8 ibat_trim)
{
	int ibat_now_ma, ibat_diff_ma, rc;
	struct qpnp_iadc_result i_result;
	enum qpnp_iadc_channels iadc_channel;

	ibat_now_ma = get_prop_current_now(chip) / 1000;
	iadc_channel = chip->use_external_rsense ?
				EXTERNAL_RSENSE : INTERNAL_RSENSE;
	rc = qpnp_iadc_read(chip->iadc_dev, iadc_channel, &i_result);
	if (rc) {
		pr_err("Unable to read bat rc=%d\n", rc);
		return;
	}

	ibat_now_ma = i_result.result_ua / 1000;

	if (qpnp_chg_is_ibat_loop_active(chip)) {
		ibat_now_ma *= -1;
		ibat_diff_ma = ibat_now_ma - IBAT_TRIM_TGT_MA;

		if (abs(ibat_diff_ma) > 50) {
@@ -2494,6 +2505,9 @@ qpnp_chg_input_current_settled(struct qpnp_chg_chip *chip)
	if (!chip->ibat_calibration_enabled)
		return 0;

	if (chip->type != SMBB)
		return 0;

	rc = qpnp_chg_read(chip, &reg,
			chip->buck_base + BUCK_CTRL_TRIM3, 1);
	if (rc) {
@@ -2556,7 +2570,16 @@ qpnp_chg_input_current_settled(struct qpnp_chg_chip *chip)
			qpnp_chg_trim_ibat(chip, ibat_trim);
		else
			pr_debug("ibat loop not active\n");

		/* read the adjusted ibat_trim for further adjustments */
		rc = qpnp_chg_read(chip, &ibat_trim,
			chip->buck_base + BUCK_CTRL_TRIM3, 1);
		if (rc) {
			pr_err("failed to read BUCK_CTRL_TRIM3 rc=%d\n", rc);
			break;
		}
	}

	/* restore IBATMAX */
	rc = qpnp_chg_ibatmax_set(chip, ibat_max_ma);
	if (rc)
@@ -4295,6 +4318,11 @@ qpnp_charger_read_dt_props(struct qpnp_chg_chip *chip)
			return rc;
	}

	/* Get the use-external-rsense property */
	chip->use_external_rsense = of_property_read_bool(
			chip->spmi->dev.of_node,
			"qcom,use-external-rsense");

	/* Get the btc-disabled property */
	chip->btc_disabled = of_property_read_bool(chip->spmi->dev.of_node,
					"qcom,btc-disabled");
@@ -4439,6 +4467,17 @@ qpnp_charger_probe(struct spmi_device *spmi)
				goto fail_chg_enable;
			}

			if (subtype == SMBB_BAT_IF_SUBTYPE) {
				chip->iadc_dev = qpnp_get_iadc(chip->dev,
						"chg");
				if (IS_ERR(chip->iadc_dev)) {
					rc = PTR_ERR(chip->iadc_dev);
					if (rc != -EPROBE_DEFER)
						pr_err("iadc property missing\n");
					goto fail_chg_enable;
				}
			}

			rc = qpnp_chg_load_battery_data(chip);
			if (rc)
				goto fail_chg_enable;