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

Commit ec635a0b authored by Abinaya P's avatar Abinaya P
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 b2b64139
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>;
		};
+38 −9
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -139,7 +139,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

@@ -248,6 +248,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
@@ -298,6 +300,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;
@@ -1479,6 +1482,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)
@@ -1488,6 +1492,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);
@@ -1498,17 +1514,17 @@ 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
				 */
@@ -2054,6 +2070,19 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
		hap->misc_trim_error_rc19p2_clk_reg_present =
				of_property_read_bool(spmi->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(spmi->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(spmi->dev.of_node,