mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
input: qcom-hv-haptics: reset FIFO play logic when hBoost is busy
Currently, when waiting for hBoost ready times out, error code -EBUSY is returned. In addition to that, reset the FIFO play logic so that the following FIFO requests can still be served. Meanwhile, add 100us before updating HAPTICS_EN for hBoost to have enough time to handle its power transition as per the hardware recommendation. Change-Id: Iebfc98b589bda747e4c2b6fdf6ff78d2f46ece5d Signed-off-by: Fenglin Wu <quic_fenglinw@quicinc.com>
This commit is contained in:
parent
cd6f6c7ba3
commit
44ec5b55d0
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
|
@ -1792,10 +1792,17 @@ static int haptics_toggle_module_enable(struct haptics_chip *chip)
|
|||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Updating HAPTICS_EN would vote hBoost enable status. Add 100us
|
||||
* delay before updating HAPTICS_EN for hBoost to have enough time
|
||||
* to handle its power transition.
|
||||
*/
|
||||
usleep_range(100, 101);
|
||||
rc = haptics_module_enable(chip, false);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
usleep_range(100, 101);
|
||||
return haptics_module_enable(chip, true);
|
||||
}
|
||||
|
||||
|
|
@ -2258,6 +2265,46 @@ static u8 get_direct_play_max_amplitude(struct haptics_chip *chip)
|
|||
return (u8)amplitude;
|
||||
}
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = haptics_enable_play(chip, false);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* restore FIFO play rate back to T_LRA */
|
||||
rc = haptics_set_fifo_playrate(chip, T_LRA);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
haptics_fifo_empty_irq_config(chip, false);
|
||||
kvfree(chip->custom_effect->fifo->samples);
|
||||
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;
|
||||
}
|
||||
|
||||
static int haptics_upload_effect(struct input_dev *dev,
|
||||
struct ff_effect *effect, struct ff_effect *old)
|
||||
{
|
||||
|
|
@ -2327,46 +2374,21 @@ static int haptics_upload_effect(struct input_dev *dev,
|
|||
return rc;
|
||||
}
|
||||
|
||||
return haptics_wait_hboost_ready(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");
|
||||
return 0;
|
||||
rc = haptics_wait_hboost_ready(chip);
|
||||
if (rc < 0 && chip->play.pattern_src == FIFO) {
|
||||
/*
|
||||
* Call haptics_stop_fifo_play(chip) explicitly if hBoost is
|
||||
* not ready for the FIFO play. This drops current FIFO play
|
||||
* but it restores the SW back to initial status so that the
|
||||
* following FIFO play requests can still be served.
|
||||
*/
|
||||
dev_dbg(chip->dev, "stop FIFO play explicitly to restore SW status\n");
|
||||
mutex_lock(&chip->play.lock);
|
||||
haptics_stop_fifo_play(chip);
|
||||
mutex_unlock(&chip->play.lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = haptics_enable_play(chip, false);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* restore FIFO play rate back to T_LRA */
|
||||
rc = haptics_set_fifo_playrate(chip, T_LRA);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
haptics_fifo_empty_irq_config(chip, false);
|
||||
kvfree(chip->custom_effect->fifo->samples);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user