From 88fc3718dbad120668311f790c83a90b21f46e49 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Thu, 4 Jun 2020 15:12:37 +0800 Subject: [PATCH 1/2] input: qcom-hv-haptics: Deglitch fifo-empty interrupt Check INT_RT_STS in FIFO empty IRQ handler and ignore the interrupt if FIFO_EMPTY real time status bit is not set. Change-Id: I7a276fa1d8c79d530fc26f74263e0608096a99f8 Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index 03e5c926f690..b7b8fa9be419 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -46,6 +46,9 @@ #define AUTO_RES_ERROR_BIT BIT(1) #define HPRW_RDY_FAULT_BIT BIT(0) +#define HAP_CFG_INT_RT_STS_REG 0x10 +#define FIFO_EMPTY_BIT BIT(1) + /* config register definitions in HAPTICS_CFG module */ #define HAP_CFG_DRV_CTRL_REG 0x47 #define PSTG_DLY_MASK GENMASK(7, 6) @@ -1919,9 +1922,20 @@ static irqreturn_t fifo_empty_irq_handler(int irq, void *data) struct fifo_cfg *fifo = chip->play.effect->fifo; struct fifo_play_status *status = &chip->play.fifo_status; u32 samples_left; - u8 *samples; + u8 *samples, val; int rc, num; + rc = haptics_read(chip, chip->cfg_addr_base, + HAP_CFG_INT_RT_STS_REG, &val, 1); + if (rc < 0) + return IRQ_HANDLED; + + if (!(val & FIFO_EMPTY_BIT)) { + dev_dbg(chip->dev, "Ignore spurious/falling IRQ, INT_RT_STS = %#x\n", + val); + return IRQ_HANDLED; + } + if (atomic_read(&chip->play.fifo_status.written_done) == 1) { /* * Check the FIFO real time fill status before stopping From 7f9efca481a78bf9e5ef58bcd70f9f9c8875e837 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Thu, 4 Jun 2020 15:57:39 +0800 Subject: [PATCH 2/2] input: qcom-hv-haptics: restore RC calibration mode after FIFO playing Auto RC clock calibration is used as default configuration. When playing FIFO streaming data, manual RC clock calibration is used for adjusting the FIFO pattern based on the detected LRA frequency. Restore back to use auto RC clock calibration after FIFO pattern is played. Change-Id: I335552cfeafe559aa35a76bf6aa218a92b62d3db Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index b7b8fa9be419..6693f927a4ab 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -1687,6 +1687,7 @@ static void haptics_fifo_empty_irq_config(struct haptics_chip *chip, static int haptics_stop_fifo_play(struct haptics_chip *chip) { int rc; + u8 val; if (atomic_read(&chip->play.fifo_status.is_busy) == 0) { dev_dbg(chip->dev, "FIFO playing is not in progress\n"); @@ -1707,6 +1708,18 @@ static int haptics_stop_fifo_play(struct haptics_chip *chip) chip->custom_effect->fifo->samples = NULL; atomic_set(&chip->play.fifo_status.is_busy, 0); + + /* + * All other playing modes would use AUTO mode RC + * calibration except FIFO streaming mode, so restore + * back to AUTO RC calibration after FIFO playing. + */ + val = CAL_RC_CLK_AUTO_VAL << CAL_RC_CLK_SHIFT; + rc = haptics_masked_write(chip, chip->cfg_addr_base, + HAP_CFG_CAL_EN_REG, CAL_RC_CLK_MASK, val); + if (rc < 0) + return rc; + dev_dbg(chip->dev, "stopped FIFO playing successfully\n"); return 0; }