mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 19:21:28 +02:00
input: qcom-hv-haptics: notify HBOOST to keep VREG on during play
HAPTICS module controls the output voltage of HAPTICS_BOOST module through hardware signals when playing a vibration. During FIFO mode playing, HAPTICS module would request HAPTICS_BOOST module to turn on/off the output based on FIFO empty status. HAPTICS_BOOST is turned off when FIFO is empty and it's turned on again when more FIFO samples are filled. During this voltage transition request (off->on), HAPTICS_BOOST module may have a race condition if this requests comes in rapid succession. This can lead to its FSM getting stuck. To avoid this race condition, notify HAPTICS_BOOST module to keep the output enabled until the playing is stopped. This is done by triggering a PBS sequence through a SDAM module. Change-Id: I5cef13df7a1fa4608dd64d509c802e0bcfde6b92 Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
This commit is contained in:
parent
5850a67068
commit
8a32254027
|
|
@ -430,6 +430,7 @@ struct haptics_chip {
|
|||
struct regulator_dev *swr_slave_rdev;
|
||||
struct mutex irq_lock;
|
||||
struct nvmem_cell *cl_brake_nvmem;
|
||||
struct nvmem_device *hap_cfg_nvmem;
|
||||
struct class hap_class;
|
||||
int fifo_empty_irq;
|
||||
u32 effects_count;
|
||||
|
|
@ -892,6 +893,40 @@ static int haptics_set_direct_play(struct haptics_chip *chip, u8 amplitude)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define PBS_ARG_REG 0x42
|
||||
#define HAP_VREG_ON_VAL 0x1
|
||||
#define HAP_VREG_OFF_VAL 0x2
|
||||
#define PBS_TRIG_SET_REG 0xE5
|
||||
#define PBS_TRIG_SET_VAL 0x1
|
||||
static int haptics_boost_vreg_enable(struct haptics_chip *chip, bool en)
|
||||
{
|
||||
int rc;
|
||||
u8 val;
|
||||
|
||||
if (chip->hap_cfg_nvmem == NULL) {
|
||||
dev_dbg(chip->dev, "nvmem device for hap_cfg is not defined\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = en ? HAP_VREG_ON_VAL : HAP_VREG_OFF_VAL;
|
||||
rc = nvmem_device_write(chip->hap_cfg_nvmem,
|
||||
PBS_ARG_REG, 1, &val);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "write SDAM %#x failed, rc=%d\n",
|
||||
PBS_ARG_REG, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
val = PBS_TRIG_SET_VAL;
|
||||
rc = nvmem_device_write(chip->hap_cfg_nvmem,
|
||||
PBS_TRIG_SET_REG, 1, &val);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "Write SDAM %#x failed, rc=%d\n",
|
||||
PBS_TRIG_SET_REG, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int haptics_enable_play(struct haptics_chip *chip, bool en)
|
||||
{
|
||||
struct haptics_play_info *play = &chip->play;
|
||||
|
|
@ -916,8 +951,17 @@ static int haptics_enable_play(struct haptics_chip *chip, bool en)
|
|||
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_SPMI_PLAY_REG, &val, 1);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Write SPMI_PLAY failed, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (play->pattern_src == FIFO) {
|
||||
rc = haptics_boost_vreg_enable(chip, en);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "Notify vreg %s failed, rc=%d\n",
|
||||
en ? "enabling" : "disabling", rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -3069,6 +3113,18 @@ static int haptics_parse_dt(struct haptics_chip *chip)
|
|||
}
|
||||
}
|
||||
|
||||
if (of_find_property(node, "nvmem", NULL)) {
|
||||
chip->hap_cfg_nvmem =
|
||||
devm_nvmem_device_get(chip->dev, "hap_cfg_sdam");
|
||||
if (IS_ERR(chip->hap_cfg_nvmem)) {
|
||||
rc = PTR_ERR(chip->hap_cfg_nvmem);
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dev_err(chip->dev, "Failed to get nvmem device, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
addr = of_get_address(node, 0, NULL, NULL);
|
||||
if (!addr) {
|
||||
dev_err(chip->dev, "Read HAPTICS_CFG address failed\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user