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

Commit fbe34611 authored by Fenglin Wu's avatar Fenglin Wu
Browse files

input: qcom-hv-haptics: reset haptics module if it's stuck in SWR mode



The haptics module would get stuck in SWR mode if SWR port is
disconnected during SWR play, and this can happen if ADSP SSR
(subsystem reset) is triggered when playing in SWR mode. This
stuck condition can be detected by checking if haptics module
has already been in SWR mode when swr-haptics driver requests
to enable SWR haptics. When it's detected, ignore SWR mode
temporarily and toggle HAPTICS_EN for a HW reset. When SWR play
is attempted again i.e. when swr_haptics driver request to turn
on SWR slave device, SWR mode would get re-enabled.

Change-Id: Ie55d331e3c689972b42dd9688f0d2b182b3fd282
Signed-off-by: default avatarFenglin Wu <fenglinw@codeaurora.org>
parent bbb2705d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -79,7 +79,9 @@
#define DRV_WF_SEL_MASK				GENMASK(1, 0)

#define HAP_CFG_AUTO_SHUTDOWN_CFG_REG		0x4A

#define HAP_CFG_TRIG_PRIORITY_REG		0x4B
#define SWR_IGNORE_BIT				BIT(4)

#define HAP_CFG_SPMI_PLAY_REG			0x4C
#define PLAY_EN_BIT				BIT(7)
@@ -3902,6 +3904,34 @@ static int swr_slave_reg_enable(struct regulator_dev *rdev)
		return rc;
	}

	/*
	 * If haptics has already been in SWR mode when enabling the SWR
	 * slave, it means that the haptics module was stuck in prevous
	 * SWR play. Then toggle HAPTICS_EN to reset haptics module and
	 * ignore SWR mode until next SWR slave enable request is coming.
	 */
	if (is_swr_play_enabled(chip)) {
		rc = haptics_masked_write(chip, chip->cfg_addr_base,
				HAP_CFG_TRIG_PRIORITY_REG,
				SWR_IGNORE_BIT, SWR_IGNORE_BIT);
		if (rc < 0) {
			dev_err(chip->dev, "Failed to enable SWR_IGNORE, rc=%d\n", rc);
			return rc;
		}

		rc = haptics_toggle_module_enable(chip);
		if (rc < 0)
			return rc;
	} else {
		rc = haptics_masked_write(chip, chip->cfg_addr_base,
				HAP_CFG_TRIG_PRIORITY_REG,
				SWR_IGNORE_BIT, 0);
		if (rc < 0) {
			dev_err(chip->dev, "Failed to disable SWR_IGNORE, rc=%d\n", rc);
			return rc;
		}
	}

	chip->swr_slave_enabled = true;
	return 0;
}