From 0c7591e6b9d221e6edbbee35008ffabbc02590de Mon Sep 17 00:00:00 2001 From: Jeff LaBundy Date: Fri, 26 Jan 2018 11:58:10 -0600 Subject: [PATCH] misc: cs40l20: Handle diagnostics interruption * Preserved device state correctly if new work is scheduled before diagnostics is cancelled. * Removed hard coding of diagnostics trigger index. * Updated minimum supported firmware revision to 0x000202. Change-Id: I5b667cf32a588e329eb03face69ad8e7e0a13e71 Signed-off-by: Jeff LaBundy Signed-off-by: Ravi Vembu --- drivers/misc/cs40l20.c | 16 ++++++++++++---- drivers/misc/cs40l20.h | 5 ++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/misc/cs40l20.c b/drivers/misc/cs40l20.c index e010d8ff0d30..d7a93d53f242 100644 --- a/drivers/misc/cs40l20.c +++ b/drivers/misc/cs40l20.c @@ -104,7 +104,8 @@ static ssize_t cs40l20_cp_trigger_index_store(struct device *dev, if (ret) return -EINVAL; - if ((index & 0x7FFF) > (cs40l20->num_waves - 1) && index != 0xFFFF) + if ((index & CS40L20_INDEX_MASK) >= cs40l20->num_waves + && index != CS40L20_INDEX_DIAG) return -EINVAL; cs40l20->cp_trigger_index = index; @@ -379,6 +380,12 @@ static void cs40l20_vibe_start_worker(struct work_struct *work) mutex_lock(&cs40l20->lock); + /* gracefully exit if diagnostics stimulus is interrupted */ + if (cs40l20->cp_trailer_index == CS40L20_INDEX_DIAG) { + cs40l20->diag_state = CS40L20_DIAG_STATE_INIT; + goto err_mutex; + } + cs40l20->cp_trailer_index = cs40l20->cp_trigger_index; switch (cs40l20->cp_trailer_index) { @@ -387,7 +394,8 @@ static void cs40l20_vibe_start_worker(struct work_struct *work) ret = regmap_write(regmap, cs40l20_dsp_reg(cs40l20, "TRIGGER_MS", CS40L20_XM_UNPACKED_TYPE), - cs40l20->cp_trailer_index & 0x7FFF); + cs40l20->cp_trailer_index + & CS40L20_INDEX_MASK); if (ret) dev_err(dev, "Failed to start playback\n"); break; @@ -401,7 +409,7 @@ static void cs40l20_vibe_start_worker(struct work_struct *work) dev_err(dev, "Failed to start playback\n"); break; - case 0xFFFF: + case CS40L20_INDEX_DIAG: cs40l20->diag_state = CS40L20_DIAG_STATE_INIT; ret = regmap_write(regmap, @@ -452,7 +460,7 @@ static void cs40l20_vibe_stop_worker(struct work_struct *work) mutex_lock(&cs40l20->lock); switch (cs40l20->cp_trailer_index) { - case 0xFFFF: + case CS40L20_INDEX_DIAG: ret = cs40l20_diag_capture(cs40l20); if (ret) dev_err(dev, "Failed to capture f0 and ReDC\n"); diff --git a/drivers/misc/cs40l20.h b/drivers/misc/cs40l20.h index 7292c095ef89..bfffa00c6fa7 100644 --- a/drivers/misc/cs40l20.h +++ b/drivers/misc/cs40l20.h @@ -703,7 +703,7 @@ #define CS40L20_XM_LIST_TERM 0xBEDEAD #define CS40L20_NUM_ALGOS_MAX 16 -#define CS40L20_FW_REV_MIN 0x000201 +#define CS40L20_FW_REV_MIN 0x000202 #define CS40L20_ALGO_ID_SIZE 4 #define CS40L20_COEFF_COUNT_SIZE 4 @@ -714,6 +714,9 @@ #define CS40L20_TIMEOUT_MS_MAX 0x02AAAA /* ~174 sec */ #define CS40L20_HALO_STATE_RUNNING 0x2 +#define CS40L20_INDEX_MASK 0x7FFF +#define CS40L20_INDEX_DIAG 0xFFFF + #define CS40L20_DIAG_STATE_INIT 0x00 #define CS40L20_DIAG_STATE_RUN 0x01 #define CS40L20_DIAG_STATE_DONE 0x02