summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/qpnp-haptic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc/qcom/qpnp-haptic.c')
-rw-r--r--drivers/soc/qcom/qpnp-haptic.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/drivers/soc/qcom/qpnp-haptic.c b/drivers/soc/qcom/qpnp-haptic.c
index 38cc86963181..4ca0edf24eed 100644
--- a/drivers/soc/qcom/qpnp-haptic.c
+++ b/drivers/soc/qcom/qpnp-haptic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, 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
@@ -2231,6 +2231,8 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int time_ms)
{
struct qpnp_hap *hap = container_of(dev, struct qpnp_hap,
timed_dev);
+ bool state = !!time_ms;
+ ktime_t rem;
int rc;
if (time_ms < 0)
@@ -2238,38 +2240,49 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int time_ms)
mutex_lock(&hap->lock);
- if (time_ms == 0) {
- /* disable haptics */
- hrtimer_cancel(&hap->hap_timer);
- hap->state = 0;
- schedule_work(&hap->work);
+ if (hap->state == state) {
+ if (state) {
+ rem = hrtimer_get_remaining(&hap->hap_timer);
+ if (time_ms > ktime_to_ms(rem)) {
+ time_ms = (time_ms > hap->timeout_ms ?
+ hap->timeout_ms : time_ms);
+ hrtimer_cancel(&hap->hap_timer);
+ hap->play_time_ms = time_ms;
+ hrtimer_start(&hap->hap_timer,
+ ktime_set(time_ms / 1000,
+ (time_ms % 1000) * 1000000),
+ HRTIMER_MODE_REL);
+ }
+ }
mutex_unlock(&hap->lock);
return;
}
- if (time_ms < 10)
- time_ms = 10;
-
- if (is_sw_lra_auto_resonance_control(hap))
- hrtimer_cancel(&hap->auto_res_err_poll_timer);
-
- hrtimer_cancel(&hap->hap_timer);
+ hap->state = state;
+ if (!hap->state) {
+ hrtimer_cancel(&hap->hap_timer);
+ } else {
+ if (time_ms < 10)
+ time_ms = 10;
- if (hap->auto_mode) {
- rc = qpnp_hap_auto_mode_config(hap, time_ms);
- if (rc < 0) {
- pr_err("Unable to do auto mode config\n");
- mutex_unlock(&hap->lock);
- return;
+ if (hap->auto_mode) {
+ rc = qpnp_hap_auto_mode_config(hap, time_ms);
+ if (rc < 0) {
+ pr_err("Unable to do auto mode config\n");
+ mutex_unlock(&hap->lock);
+ return;
+ }
}
+
+ time_ms = (time_ms > hap->timeout_ms ?
+ hap->timeout_ms : time_ms);
+ hap->play_time_ms = time_ms;
+ hrtimer_start(&hap->hap_timer,
+ ktime_set(time_ms / 1000,
+ (time_ms % 1000) * 1000000),
+ HRTIMER_MODE_REL);
}
- time_ms = (time_ms > hap->timeout_ms ? hap->timeout_ms : time_ms);
- hap->play_time_ms = time_ms;
- hap->state = 1;
- hrtimer_start(&hap->hap_timer,
- ktime_set(time_ms / 1000, (time_ms % 1000) * 1000000),
- HRTIMER_MODE_REL);
mutex_unlock(&hap->lock);
schedule_work(&hap->work);
}