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

Commit 9fa3567d authored by Abinaya P's avatar Abinaya P Committed by Ankit Sharma
Browse files

msm: qpnp-haptic: add DT property for back-emf generation delay



For auto resonance detection to work properly, sufficient
back-emf has to be generated. In general, back-emf takes
some time to build up. When the auto resonance mode is chosen
as QWD, high-z will be applied for every LRA cycle and hence
there won't be enough back-emf at the start-up. Hence, the
motor needs to vibrate for few LRA cycles after the PLAY bit
is asserted. So disable the auto resonance and enable it back
after some delay. Add DT property to configure this delay value.

CRs-Fixed: 833062
Change-Id: I688329f642ca9d506e203f448da5d874b91b77ff
Signed-off-by: default avatarAbinaya P <abinayap@codeaurora.org>
parent a66dbe84
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -67,6 +67,18 @@ Optional properties when qcom,actuator-type is "lra"
 - qcom,lra-res-cal-period : Auto resonance calibration period. The values range from
			4 to 32(default)

Optional properties when qcom,lra-auto-res-mode is "qwd"
 - qcom,time-required-to-generate-back-emf-us: Time period required to generate sufficient
			back-emf (in case of QWD mode only) in us. For auto resonance
			detection to work properly,sufficient back-emf has to be
			generated. In general, back-emf takes some time to build up.
			When the auto resonance  mode is chosen as QWD, high-z will
			be applied for every LRA cycle and hence there won't be
			enough back-emf at the start-up. So we need to drive the
			motor for a few LRA cycles. Hence, auto resonance detection
			is enabled after this delay period after the PLAY bit is
			asserted. The default value is 20000us.

Example:
		qcom,haptic@c000 {
			status = "disabled";
@@ -94,4 +106,5 @@ Example:
			qcom,lra-high-z = "opt1";
			qcom,lra-auto-res-mode = "qwd";
			qcom,lra-res-cal-period = <4>;
			qcom,time-required-to-generate-back-emf-us = <20000>;
		};
+37 −7
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@
#define QPNP_HAP_CYCLS			5
#define QPNP_TEST_TIMER_MS		5

#define AUTO_RES_ENABLE_TIMEOUT		20000
#define QPNP_HAP_TIME_REQ_FOR_BACK_EMF_GEN	20000
#define AUTO_RES_ERR_CAPTURE_RES	5
#define AUTO_RES_ERR_MAX		15

@@ -250,6 +250,8 @@ struct qpnp_pwm_info {
 *  @ auto_res_mode - auto resonace mode
 *  @ lra_high_z - high z option line
 *  @ timeout_ms - max timeout in ms
 *  @ time_required_to_generate_back_emf_us - the time required for sufficient
      back-emf to be generated for auto resonance to be successful
 *  @ vmax_mv - max voltage in mv
 *  @ ilim_ma - limiting current in ma
 *  @ sc_deb_cycles - short circuit debounce cycles
@@ -301,6 +303,7 @@ struct qpnp_hap {
	enum qpnp_hap_auto_res_mode	auto_res_mode;
	enum qpnp_hap_high_z		lra_high_z;
	u32				timeout_ms;
	u32				time_required_to_generate_back_emf_us;
	u32				vmax_mv;
	u32				ilim_ma;
	u32				sc_deb_cycles;
@@ -1455,6 +1458,7 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)
	int rc = 0;
	u8 val = 0;
	unsigned long timeout_ns = POLL_TIME_AUTO_RES_ERR_NS;
	u32 back_emf_delay_us = hap->time_required_to_generate_back_emf_us;

	if (hap->play_mode == QPNP_HAP_PWM) {
		if (on)
@@ -1464,6 +1468,18 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)
	} else if (hap->play_mode == QPNP_HAP_BUFFER ||
			hap->play_mode == QPNP_HAP_DIRECT) {
		if (on) {
			/*
			 * For auto resonance detection to work properly,
			 * sufficient back-emf has to be generated. In general,
			 * back-emf takes some time to build up. When the auto
			 * resonance mode is chosen as QWD, high-z will be
			 * applied for every LRA cycle and hence there won't be
			 * enough back-emf at the start-up. Hence, the motor
			 * needs to vibrate for few LRA cycles after the PLAY
			 * bit is asserted. So disable the auto resonance here
			 * and enable it after the sleep of
			 * 'time_required_to_generate_back_emf_us' is completed.
			 */
			if (hap->correct_lra_drive_freq ||
				hap->auto_res_mode == QPNP_HAP_AUTO_RES_QWD)
				qpnp_hap_auto_res_enable(hap, 0);
@@ -1474,17 +1490,18 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)

			rc = qpnp_hap_play(hap, on);

			if ((hap->act_type == QPNP_HAP_LRA &&
				hap->correct_lra_drive_freq) ||
				hap->auto_res_mode == QPNP_HAP_AUTO_RES_QWD) {
				usleep_range(AUTO_RES_ENABLE_TIMEOUT,
					(AUTO_RES_ENABLE_TIMEOUT + 1));
			if (hap->act_type == QPNP_HAP_LRA &&
				(hap->correct_lra_drive_freq ||
				hap->auto_res_mode == QPNP_HAP_AUTO_RES_QWD)) {
				usleep_range(back_emf_delay_us,
						(back_emf_delay_us + 1));

				rc = qpnp_hap_auto_res_enable(hap, 1);
				if (rc < 0)
					return rc;
			}
			if (hap->correct_lra_drive_freq) {
			if (hap->act_type == QPNP_HAP_LRA &&
					hap->correct_lra_drive_freq) {
				/*
				 * Start timer to poll Auto Resonance error bit
				 */
@@ -2038,6 +2055,19 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
		hap->misc_trim_error_rc19p2_clk_reg_present =
				of_property_read_bool(pdev->dev.of_node,
				"qcom,misc-trim-error-rc19p2-clk-reg-present");

		if (hap->auto_res_mode == QPNP_HAP_AUTO_RES_QWD) {
			hap->time_required_to_generate_back_emf_us =
					QPNP_HAP_TIME_REQ_FOR_BACK_EMF_GEN;
			rc = of_property_read_u32(pdev->dev.of_node,
				"qcom,time-required-to-generate-back-emf-us",
				&temp);
			if (!rc)
				hap->time_required_to_generate_back_emf_us =
									temp;
		} else {
			hap->time_required_to_generate_back_emf_us = 0;
		}
	}

	rc = of_property_read_string(pdev->dev.of_node,