From 4fd0b8d16704a48a5bf3737f8b8332cc9df55fee Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Wed, 16 May 2018 13:37:59 -0500 Subject: [PATCH] misc: cs40l2x: Add suspend blocker support Added wakeup calls in order to prevent the system from suspending while continuous vibration is in progress. Change-Id: I295fbe3098ebda4710bcd90653609c284d8c69a3 Signed-off-by: Jeff LaBundy Signed-off-by: Ravi Vembu --- drivers/misc/cs40l2x.c | 52 ++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/drivers/misc/cs40l2x.c b/drivers/misc/cs40l2x.c index 6b0958a40b71..e4b618c77cbc 100644 --- a/drivers/misc/cs40l2x.c +++ b/drivers/misc/cs40l2x.c @@ -1413,19 +1413,19 @@ static void cs40l2x_vibe_start_worker(struct work_struct *work) cs40l2x->cp_trailer_index = cs40l2x->cp_trigger_index; -#ifdef CONFIG_ANDROID_TIMED_OUTPUT - /* launch timer in the event of continuous playback */ switch (cs40l2x->cp_trailer_index) { case CS40L2X_INDEX_VIBE: case CS40L2X_INDEX_CONT_MIN ... CS40L2X_INDEX_CONT_MAX: case CS40L2X_INDEX_DIAG: + pm_stay_awake(dev); +#ifdef CONFIG_ANDROID_TIMED_OUTPUT hrtimer_start(&cs40l2x->vibe_timer, ktime_set(cs40l2x->vibe_timeout / 1000, (cs40l2x->vibe_timeout % 1000) * 1000000), HRTIMER_MODE_REL); - } #endif /* CONFIG_ANDROID_TIMED_OUTPUT */ + } switch (cs40l2x->cp_trailer_index) { case CS40L2X_INDEX_VIBE: @@ -1527,6 +1527,30 @@ static void cs40l2x_vibe_stop_worker(struct work_struct *work) mutex_lock(&cs40l2x->lock); switch (cs40l2x->cp_trailer_index) { + case CS40L2X_INDEX_VIBE: + case CS40L2X_INDEX_CONT_MIN ... CS40L2X_INDEX_CONT_MAX: + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, "ENDPLAYBACK", + CS40L2X_XM_UNPACKED_TYPE), 1); + if (ret) + dev_err(dev, "Failed to stop playback\n"); + pm_relax(dev); + break; + + case CS40L2X_INDEX_CLICK_MIN ... CS40L2X_INDEX_CLICK_MAX: + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, "ENDPLAYBACK", + CS40L2X_XM_UNPACKED_TYPE), 1); + if (ret) + dev_err(dev, "Failed to stop playback\n"); + break; + + case CS40L2X_INDEX_PBQ: + ret = cs40l2x_pbq_cancel(cs40l2x); + if (ret) + dev_err(dev, "Failed to cancel playback queue\n"); + break; + case CS40L2X_INDEX_DIAG: ret = cs40l2x_diag_capture(cs40l2x); if (ret) @@ -1539,20 +1563,11 @@ static void cs40l2x_vibe_stop_worker(struct work_struct *work) ret = cs40l2x_dig_scale_set(cs40l2x, cs40l2x->diag_dig_scale); if (ret) dev_err(dev, "Failed to restore digital scale\n"); - break; - - case CS40L2X_INDEX_PBQ: - ret = cs40l2x_pbq_cancel(cs40l2x); - if (ret) - dev_err(dev, "Failed to cancel playback queue\n"); + pm_relax(dev); break; default: - ret = regmap_write(regmap, - cs40l2x_dsp_reg(cs40l2x, "ENDPLAYBACK", - CS40L2X_XM_UNPACKED_TYPE), 1); - if (ret) - dev_err(dev, "Failed to stop playback\n"); + dev_err(dev, "Invalid wavetable index\n"); } cs40l2x->cp_trailer_index = 0; @@ -1671,6 +1686,7 @@ static void cs40l2x_create_led(struct cs40l2x_private *cs40l2x) static void cs40l2x_vibe_init(struct cs40l2x_private *cs40l2x) { struct hrtimer *pbq_timer = &cs40l2x->pbq_timer; + int ret; #ifdef CONFIG_ANDROID_TIMED_OUTPUT cs40l2x_create_timed_output(cs40l2x); @@ -1692,6 +1708,12 @@ static void cs40l2x_vibe_init(struct cs40l2x_private *cs40l2x) hrtimer_init(pbq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); pbq_timer->function = cs40l2x_pbq_timer; + ret = device_init_wakeup(cs40l2x->dev, true); + if (ret) { + dev_err(cs40l2x->dev, "Failed to initialize wakeup source\n"); + return; + } + cs40l2x->vibe_init_success = true; } @@ -2992,6 +3014,8 @@ static int cs40l2x_i2c_remove(struct i2c_client *i2c_client) cancel_work_sync(&cs40l2x->vibe_stop_work); destroy_workqueue(cs40l2x->vibe_workqueue); + + device_init_wakeup(cs40l2x->dev, false); } gpiod_set_value_cansleep(cs40l2x->reset_gpio, 0);