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

Commit 900b378a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: qpnp-charger: avoid ARB during JEITA"

parents bf54a4d9 54e1b2c9
Loading
Loading
Loading
Loading
+71 −25
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@
#define BOOST_ILIM				0x78
#define USB_SPARE				0xDF
#define DC_COMP_OVR1				0xE9
#define CHGR_COMP_OVR1				0xEE

#define REG_OFFSET_PERP_SUBTYPE			0x05

@@ -390,6 +391,8 @@ struct qpnp_chg_chip {
	bool				power_stage_workaround_enable;
};

static void
qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip);

static struct of_device_id qpnp_charger_match_table[] = {
	{ .compatible = QPNP_CHARGER_DEV_NAME, },
@@ -1857,6 +1860,29 @@ static int qpnp_chg_is_fastchg_on(struct qpnp_chg_chip *chip)
	return (chgr_sts & FAST_CHG_ON_IRQ) ? 1 : 0;
}

#define VBATDET_BYPASS	0x01
static int
bypass_vbatdet_comp(struct qpnp_chg_chip *chip, bool bypass)
{
	int rc;

	pr_debug("bypass %d\n", bypass);
		rc = qpnp_chg_masked_write(chip,
			chip->chgr_base + SEC_ACCESS,
			0xA5,
			0xA5, 1);
	rc |= qpnp_chg_masked_write(chip,
			chip->chgr_base + CHGR_COMP_OVR1,
			0xFF,
			bypass ? VBATDET_BYPASS : 0, 1);
	if (rc) {
		pr_err("Failed to bypass vbatdet comp rc = %d\n", rc);
		return rc;
	}

	return rc;
}

static irqreturn_t
qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
{
@@ -1885,6 +1911,11 @@ qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)

		if (fastchg_on) {
			chip->chg_done = false;
			bypass_vbatdet_comp(chip, 1);
			if (chip->bat_is_warm || chip->bat_is_cool) {
				qpnp_chg_set_appropriate_vddmax(chip);
				qpnp_chg_set_appropriate_battery_current(chip);
			}

			if (chip->resuming_charging) {
				chip->resuming_charging = false;
@@ -1901,6 +1932,8 @@ qpnp_chg_chgr_chg_fastchg_irq_handler(int irq, void *_chip)
		} else {
			if (chip->parallel_ovp_mode)
				switch_parallel_ovp_mode(chip, 0);
			if (!chip->bat_is_warm && !chip->bat_is_cool)
				bypass_vbatdet_comp(chip, 0);
		}
	}

@@ -2771,6 +2804,25 @@ static int qpnp_chg_tchg_max_set(struct qpnp_chg_chip *chip, int minutes)
	return 0;
}

static void
qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
{
	unsigned int chg_current = chip->max_bat_chg_current;

	if (chip->bat_is_cool)
		chg_current = min(chg_current, chip->cool_bat_chg_ma);

	if (chip->bat_is_warm)
		chg_current = min(chg_current, chip->warm_bat_chg_ma);

	if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
		chg_current = min(chg_current,
			chip->thermal_mitigation[chip->therm_lvl_sel]);

	pr_debug("setting %d mA\n", chg_current);
	qpnp_chg_ibatmax_set(chip, chg_current);
}

static int
qpnp_chg_vddsafe_set(struct qpnp_chg_chip *chip, int voltage)
{
@@ -2978,25 +3030,6 @@ qpnp_boost_vget_uv(struct qpnp_chg_chip *chip)
	return BOOST_MIN_UV + ((boost_reg - BOOST_MIN) * BOOST_STEP_UV);
}

static void
qpnp_chg_set_appropriate_battery_current(struct qpnp_chg_chip *chip)
{
	unsigned int chg_current = chip->max_bat_chg_current;

	if (chip->bat_is_cool)
		chg_current = min(chg_current, chip->cool_bat_chg_ma);

	if (chip->bat_is_warm)
		chg_current = min(chg_current, chip->warm_bat_chg_ma);

	if (chip->therm_lvl_sel != 0 && chip->thermal_mitigation)
		chg_current = min(chg_current,
			chip->thermal_mitigation[chip->therm_lvl_sel]);

	pr_debug("setting %d mA\n", chg_current);
	qpnp_chg_ibatmax_set(chip, chg_current);
}

static void
qpnp_batt_system_temp_level_set(struct qpnp_chg_chip *chip, int lvl_sel)
{
@@ -3571,9 +3604,6 @@ qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
		chip->bat_is_cool = bat_cool;
		chip->bat_is_warm = bat_warm;

		if (bat_cool || bat_warm)
			chip->resuming_charging = false;

		/**
		 * set appropriate voltages and currents.
		 *
@@ -3581,9 +3611,25 @@ qpnp_chg_adc_notification(enum qpnp_tm_state state, void *ctx)
		 * driver will not resume with SoC. Only vbatdet is used to
		 * determine resume of charging.
		 */
		if (bat_cool || bat_warm) {
			chip->resuming_charging = false;
			qpnp_chg_set_appropriate_vbatdet(chip);

			/* To avoid ARB, only vbatdet is configured in
			 * warm/cold zones. Once vbat < vbatdet the
			 * appropriate vddmax/ibatmax adjustments will
			 * be made in the fast charge interrupt. */
			bypass_vbatdet_comp(chip, 1);
			qpnp_chg_charge_en(chip, !chip->charging_disabled);
			qpnp_chg_charge_en(chip, chip->charging_disabled);
			qpnp_chg_charge_en(chip, !chip->charging_disabled);
		} else {
			bypass_vbatdet_comp(chip, 0);
			/* restore normal parameters */
			qpnp_chg_set_appropriate_vbatdet(chip);
			qpnp_chg_set_appropriate_vddmax(chip);
			qpnp_chg_set_appropriate_battery_current(chip);
		qpnp_chg_set_appropriate_vbatdet(chip);
		}
	}

	pr_debug("warm %d, cool %d, low = %d deciDegC, high = %d deciDegC\n",