diff options
author | Tai Kuo <taikuo@google.com> | 2022-06-24 16:03:34 +0800 |
---|---|---|
committer | Tai Kuo <taikuo@google.com> | 2022-06-24 16:14:03 +0800 |
commit | 1a86adc6047bbf84cfb4fa2e6e2bcc5733f24dd2 (patch) | |
tree | 6e25751fbac21376c8b977e2ce5a1f89a0a97281 | |
parent | 5c6168be601719c507ad4602e23170e55bd64c21 (diff) | |
download | amplifiers-1a86adc6047bbf84cfb4fa2e6e2bcc5733f24dd2.tar.gz |
cs40l26: merge cs40l26 v5.3.0android-t-qpr1-beta-1_r0.3android-gs-raviole-5.10-android13-qpr1-beta
Branch: v5.10-cs40l26
Tag: cs40l26-v5.3.0_5.10
Files:
drivers/input/misc/cs40l26-i2c.c (No changes)
drivers/input/misc/cs40l26-spi.c (No changes)
drivers/input/misc/cs40l26-sysfs.c (No changes)
drivers/input/misc/cs40l26-tables.c (No changes)
drivers/input/misc/cs40l26.c
include/linux/mfd/cs40l26.h
sound/soc/codecs/cs40l26.c -> cs40l26-codec.c (No changes)
Features:
- Support for maintenance firmware revisions dating back to Rev. 39.2.22
Bug fixes:
- Disallow erase call if a haptic effect is in-flight. This allows the driver
maintain correct number of loaded effects when firmware fails to delete waveform
if the delete is attempted when haptics playback is active.
- Minor code update to handle potential failure of memchunk read from CL DSP FW driver.
Commits:
6e36db4 input: cs40l26: Rollback minimum fw revision for maintenance fw
77a5ce5 input: cs40l26: Handle memchunk read failure
20efcc3 input: cs40l26: Ensure effect to be erased is not in-flight
Bug: 237047104
Test: Copy texts and adjust alarm
Test: NFC, dumpstate, keyboard vibration
Test: idlcli commands
Test: Switch firmware continuous
Test: Switch firmware and check the first tick effect
Test: atest VtsHalVibratorManagerTargetTest \
VtsHalVibratorTargetTest \
android.os.cts.VibratorTest \
android.os.cts.VibratorManagerTest \
android.os.cts.VibrationEffectTest \
android.os.cts.VibrationAttributesTest \
android.os.cts.CombinedVibrationTest
Signed-off-by: Tai Kuo <taikuo@google.com>
Change-Id: Iad33742ad694ea9ed5987dc617e64fca0044f7c7
-rw-r--r-- | cs40l26/cs40l26.c | 29 | ||||
-rw-r--r-- | cs40l26/cs40l26.h | 8 |
2 files changed, 34 insertions, 3 deletions
diff --git a/cs40l26/cs40l26.c b/cs40l26/cs40l26.c index 93fe669..39f5253 100644 --- a/cs40l26/cs40l26.c +++ b/cs40l26/cs40l26.c @@ -708,6 +708,7 @@ static int cs40l26_handle_mbox_buffer(struct cs40l26_private *cs40l26) switch (val) { case CS40L26_DSP_MBOX_COMPLETE_MBOX: dev_dbg(dev, "Mailbox: COMPLETE_MBOX\n"); + complete_all(&cs40l26->erase_cont); cs40l26_vibe_state_update(cs40l26, CS40L26_VIBE_STATE_EVENT_MBOX_COMPLETE); break; @@ -1943,6 +1944,8 @@ static void cs40l26_vibe_start_worker(struct work_struct *work) if (!cs40l26->vibe_state_reporting) cs40l26_vibe_state_update(cs40l26, CS40L26_VIBE_STATE_EVENT_MBOX_PLAYBACK); + + reinit_completion(&cs40l26->erase_cont); err_mutex: mutex_unlock(&cs40l26->lock); pm_runtime_mark_last_busy(dev); @@ -2428,7 +2431,12 @@ static int cs40l26_refactor_owt(struct cs40l26_private *cs40l26, s16 *in_data, ch = cl_dsp_memchunk_create((void *) in_data, in_data_bytes); cl_dsp_memchunk_read(&ch, 8); /* Skip padding */ - nsections = cl_dsp_memchunk_read(&ch, 8); + ret = cl_dsp_memchunk_read(&ch, 8); + if (ret < 0) + return ret; + + nsections = ret; + global_rep = cl_dsp_memchunk_read(&ch, 8); sections = kcalloc(nsections, sizeof(struct cs40l26_owt_section), @@ -2957,6 +2965,7 @@ static void cs40l26_erase_worker(struct work_struct *work) struct cs40l26_private, erase_work); int ret = 0; int effect_id; + u16 duration; u32 index; ret = pm_runtime_get_sync(cs40l26->dev); @@ -2967,6 +2976,22 @@ static void cs40l26_erase_worker(struct work_struct *work) effect_id = cs40l26->erase_effect->id; index = cs40l26->trigger_indices[effect_id]; + duration = (cs40l26->erase_effect->replay.length == 0) ? + CS40L26_MAX_WAIT_VIBE_COMPLETE_MS : + cs40l26->erase_effect->replay.length + CS40L26_ERASE_BUFFER_MS; + + /* Check for ongoing effect playback. */ + if (cs40l26->vibe_state == CS40L26_VIBE_STATE_HAPTIC) { + /* Wait for effect to complete. */ + mutex_unlock(&cs40l26->lock); + if (!wait_for_completion_timeout(&cs40l26->erase_cont, + msecs_to_jiffies(duration))) { + ret = -ETIME; + dev_err(cs40l26->dev, "Failed to erase effect: %d", ret); + goto pm_err; + } + mutex_lock(&cs40l26->lock); + } dev_dbg(cs40l26->dev, "%s: effect ID = %d\n", __func__, effect_id); @@ -2992,6 +3017,7 @@ static void cs40l26_erase_worker(struct work_struct *work) out_mutex: mutex_unlock(&cs40l26->lock); +pm_err: pm_runtime_mark_last_busy(cs40l26->dev); pm_runtime_put_autosuspend(cs40l26->dev); @@ -4798,6 +4824,7 @@ int cs40l26_probe(struct cs40l26_private *cs40l26, cs40l26->pm_ready = false; init_completion(&cs40l26->i2s_cont); + init_completion(&cs40l26->erase_cont); if (!cs40l26->fw_defer) { ret = cs40l26_fw_upload(cs40l26); diff --git a/cs40l26/cs40l26.h b/cs40l26/cs40l26.h index 639c309..d7be94f 100644 --- a/cs40l26/cs40l26.h +++ b/cs40l26/cs40l26.h @@ -858,9 +858,9 @@ #define CS40L26_FW_CALIB_ID 0x1800DA #define CS40L26_FW_CALIB_MIN_REV 0x010014 #define CS40L26_FW_CALIB_BRANCH 0x01 -#define CS40L26_FW_MAINT_MIN_REV 0x27021A +#define CS40L26_FW_MAINT_MIN_REV 0x270216 #define CS40L26_FW_MAINT_BRANCH 0x27 -#define CS40L26_FW_MAINT_CALIB_MIN_REV 0x210112 +#define CS40L26_FW_MAINT_CALIB_MIN_REV 0x21010D #define CS40L26_FW_MAINT_CALIB_BRANCH 0x21 #define CS40L26_FW_BRANCH_MASK GENMASK(23, 21) @@ -927,6 +927,9 @@ #define CS40L26_AMP_VOL_PCM_MAX 0x07FF +#define CS40L26_ERASE_BUFFER_MS 500 +#define CS40L26_MAX_WAIT_VIBE_COMPLETE_MS 10000 + /* GPI Triggering */ #define CS40L26_GPIO1 1 #define CS40L26_EVENT_MAP_INDEX_MASK GENMASK(8, 0) @@ -1513,6 +1516,7 @@ struct cs40l26_private { bool comp_enable_redc; bool comp_enable_f0; struct completion i2s_cont; + struct completion erase_cont; u8 vpbr_thld; }; |