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

Commit aab2ad6e authored by Abinaya P's avatar Abinaya P
Browse files

msm: qpnp-haptic: cancel poll timer before enqueuing new timer request



When multiple requests come for enabling haptics and the actutator type
is LRA and auto resonance error detection is enabled, then apart from
cancelling the haptics timer, also cancel the previous instance of the
auto resonance timer if it exists to avoid enqueuing the same timer again.

Also, re-organise the code to access the timers only when the actuator
type is LRA.

Change-Id: I1cd384152b2ce691c1882356dd5e74fd2bfdd9ee
Signed-off-by: default avatarAbinaya P <abinayap@codeaurora.org>
parent 90c540cd
Loading
Loading
Loading
Loading
+32 −23
Original line number Diff line number Diff line
@@ -1420,14 +1420,12 @@ static enum hrtimer_restart detect_auto_res_error(struct hrtimer *timer)
		return HRTIMER_NORESTART;
	} else {
		update_lra_frequency(hap);
	}

		currtime  = ktime_get();
		hrtimer_forward(&hap->auto_res_err_poll_timer, currtime,
				ktime_set(0, POLL_TIME_AUTO_RES_ERR_NS));

		return HRTIMER_RESTART;
	}
}

static void correct_auto_res_error(struct work_struct *auto_res_err_work)
{
@@ -1497,7 +1495,8 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)

			rc = qpnp_hap_play(hap, on);

			if (hap->correct_lra_drive_freq ||
			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));
@@ -1529,7 +1528,8 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)
			}

			rc = qpnp_hap_mod_enable(hap, on);
			if (hap->correct_lra_drive_freq) {
			if (hap->act_type == QPNP_HAP_LRA &&
					hap->correct_lra_drive_freq) {
				hrtimer_cancel(&hap->auto_res_err_poll_timer);
				calculate_lra_code(hap);
			}
@@ -1546,6 +1546,11 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value)
					 timed_dev);

	mutex_lock(&hap->lock);

	if (hap->act_type == QPNP_HAP_LRA &&
				hap->correct_lra_drive_freq)
		hrtimer_cancel(&hap->auto_res_err_poll_timer);

	hrtimer_cancel(&hap->hap_timer);

	if (value == 0) {
@@ -1686,7 +1691,6 @@ static enum hrtimer_restart qpnp_hap_test_timer(struct hrtimer *timer)
static int qpnp_haptic_suspend(struct device *dev)
{
	struct qpnp_hap *hap = dev_get_drvdata(dev);

	hrtimer_cancel(&hap->hap_timer);
	cancel_work_sync(&hap->work);
	/* turn-off haptic */
@@ -2024,6 +2028,14 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
			dev_err(&spmi->dev, "Unable to read cal period\n");
			return rc;
		}

		hap->correct_lra_drive_freq =
				of_property_read_bool(spmi->dev.of_node,
						"qcom,correct-lra-drive-freq");

		hap->misc_trim_error_rc19p2_clk_reg_present =
				of_property_read_bool(spmi->dev.of_node,
				"qcom,misc-trim-error-rc19p2-clk-reg-present");
	}

	rc = of_property_read_string(spmi->dev.of_node,
@@ -2150,13 +2162,6 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
		}
	}

	hap->correct_lra_drive_freq = of_property_read_bool(spmi->dev.of_node,
						 "qcom,correct-lra-drive-freq");

	hap->misc_trim_error_rc19p2_clk_reg_present =
				of_property_read_bool(spmi->dev.of_node,
				"qcom,misc-trim-error-rc19p2-clk-reg-present");

	return 0;
}

@@ -2209,19 +2214,19 @@ static int qpnp_haptic_probe(struct spmi_device *spmi)
	hap->timed_dev.get_time = qpnp_hap_get_time;
	hap->timed_dev.enable = qpnp_hap_td_enable;

	rc = timed_output_dev_register(&hap->timed_dev);
	if (rc < 0) {
		dev_err(&spmi->dev, "timed_output registration failed\n");
		goto timed_output_fail;
	}

	if (hap->correct_lra_drive_freq) {
	if (hap->act_type == QPNP_HAP_LRA && hap->correct_lra_drive_freq) {
		INIT_WORK(&hap->auto_res_err_work, correct_auto_res_error);
		hrtimer_init(&hap->auto_res_err_poll_timer, CLOCK_MONOTONIC,
						HRTIMER_MODE_REL);
		hap->auto_res_err_poll_timer.function = detect_auto_res_error;
	}

	rc = timed_output_dev_register(&hap->timed_dev);
	if (rc < 0) {
		dev_err(&spmi->dev, "timed_output registration failed\n");
		goto timed_output_fail;
	}

	for (i = 0; i < ARRAY_SIZE(qpnp_hap_attrs); i++) {
		rc = sysfs_create_file(&hap->timed_dev.dev->kobj,
				&qpnp_hap_attrs[i].attr);
@@ -2242,6 +2247,8 @@ sysfs_fail:
	timed_output_dev_unregister(&hap->timed_dev);
timed_output_fail:
	cancel_work_sync(&hap->work);
	if (hap->act_type == QPNP_HAP_LRA && hap->correct_lra_drive_freq)
		hrtimer_cancel(&hap->auto_res_err_poll_timer);
	hrtimer_cancel(&hap->hap_timer);
	mutex_destroy(&hap->lock);
	mutex_destroy(&hap->wf_lock);
@@ -2259,6 +2266,8 @@ static int qpnp_haptic_remove(struct spmi_device *spmi)
				&qpnp_hap_attrs[i].attr);

	cancel_work_sync(&hap->work);
	if (hap->act_type == QPNP_HAP_LRA && hap->correct_lra_drive_freq)
		hrtimer_cancel(&hap->auto_res_err_poll_timer);
	hrtimer_cancel(&hap->hap_timer);
	timed_output_dev_unregister(&hap->timed_dev);
	mutex_destroy(&hap->lock);