Merge "input: qcom-hv-haptics: toggle HAPTICS_EN bit before playing FIFO"

This commit is contained in:
qctecmdr 2020-12-20 17:39:57 -08:00 • committed by Gerrit - the friendly Code Review server
commit 5ce82d413e

View file

@ -41,6 +41,8 @@
#define FIFO_REAL_TIME_FILL_STATUS_MASK_V1 GENMASK(6, 0)
/* STATUS_DATA_MSB definition in V2 while MOD_STATUS_SEL is 5 */
#define FIFO_REAL_TIME_FILL_STATUS_MSB_MASK_V2 GENMASK(1, 0)
#define FIFO_EMPTY_FLAG_BIT_V2 BIT(6)
#define FIFO_FULL_FLAG_BIT_V2 BIT(5)
#define HAP_CFG_STATUS_DATA_LSB_REG 0x0A
/* STATUS_DATA_MSB definition while MOD_STATUS_SEL is 0 */
@ -1205,13 +1207,12 @@ static int haptics_enable_hpwr_vreg(struct haptics_chip *chip, bool en)
static int haptics_open_loop_drive_config(struct haptics_chip *chip, bool en)
{
int rc;
int rc = 0;
u8 val;
if ((is_boost_vreg_enabled_in_open_loop(chip) ||
chip->hpwr_vreg != NULL) && en) {
/* Force VREG_RDY */
val = FORCE_VREG_RDY_BIT;
rc = haptics_masked_write(chip, chip->cfg_addr_base,
HAP_CFG_VSET_CFG_REG, FORCE_VREG_RDY_BIT,
FORCE_VREG_RDY_BIT);
@ -1242,11 +1243,10 @@ static int haptics_open_loop_drive_config(struct haptics_chip *chip, bool en)
dev_dbg(chip->dev, "Toggle CAL_EN in open-loop-VREG playing\n");
}
} else {
val = en ? FORCE_VREG_RDY_BIT : 0;
} else if (chip->hpwr_vreg == NULL) {
rc = haptics_masked_write(chip, chip->cfg_addr_base,
HAP_CFG_VSET_CFG_REG,
FORCE_VREG_RDY_BIT, val);
FORCE_VREG_RDY_BIT, 0);
}
return rc;
@ -1449,11 +1449,11 @@ static int haptics_update_fifo_sample_v2(struct haptics_chip *chip,
return 0;
}
static int haptics_get_available_fifo_memory(struct haptics_chip *chip)
static int haptics_get_fifo_fill_status(struct haptics_chip *chip, u32 *fill)
{
int rc;
u8 val[2];
u32 fill, available;
bool empty = false, full = false;
if (chip->ptn_revision == HAP_PTN_V1) {
val[0] = MOD_STATUS_SEL_FIFO_FILL_STATUS_VAL;
@ -1467,7 +1467,7 @@ static int haptics_get_available_fifo_memory(struct haptics_chip *chip)
if (rc < 0)
return rc;
fill = val[0] & FIFO_REAL_TIME_FILL_STATUS_MASK_V1;
*fill = val[0] & FIFO_REAL_TIME_FILL_STATUS_MASK_V1;
} else {
val[0] = MOD_STATUS_XT_V2_FIFO_FILL_STATUS_VAL;
rc = haptics_write(chip, chip->cfg_addr_base,
@ -1486,10 +1486,25 @@ static int haptics_get_available_fifo_memory(struct haptics_chip *chip)
if (rc < 0)
return rc;
fill = ((val[0] & FIFO_REAL_TIME_FILL_STATUS_MSB_MASK_V2)
*fill = ((val[0] & FIFO_REAL_TIME_FILL_STATUS_MSB_MASK_V2)
<< 8) | val[1];
empty = !!(val[0] & FIFO_EMPTY_FLAG_BIT_V2);
full = !!(val[0] & FIFO_FULL_FLAG_BIT_V2);
}
dev_dbg(chip->dev, "filled=%d, full=%d, empty=%d\n", *fill, full, empty);
return 0;
}
static int haptics_get_available_fifo_memory(struct haptics_chip *chip)
{
int rc;
u32 fill, available;
rc = haptics_get_fifo_fill_status(chip, &fill);
if (rc < 0)
return rc;
if (fill > MAX_FIFO_SAMPLES(chip)) {
dev_err(chip->dev, "Filled FIFO number %d exceed the max %d\n",
fill, MAX_FIFO_SAMPLES(chip));
@ -1601,6 +1616,33 @@ static int haptics_set_fifo_empty_threshold(struct haptics_chip *chip,
return rc;
}
static int haptics_module_enable(struct haptics_chip *chip, bool enable)
{
u8 val;
int rc;
val = enable ? HAPTICS_EN_BIT : 0;
rc = haptics_write(chip, chip->cfg_addr_base,
HAP_CFG_EN_CTL_REG, &val, 1);
if (rc < 0)
return rc;
dev_dbg(chip->dev, "haptics module %s\n",
enable ? "enabled" : "disabled");
return 0;
}
static int haptics_toggle_module_enable(struct haptics_chip *chip)
{
int rc;
rc = haptics_module_enable(chip, false);
if (rc < 0)
return rc;
return haptics_module_enable(chip, true);
}
static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
{
struct fifo_play_status *status = &chip->play.fifo_status;
@ -1734,6 +1776,13 @@ static int haptics_load_predefined_effect(struct haptics_chip *chip,
return -EINVAL;
play->effect = effect;
if (play->pattern_src == FIFO) {
/* Toggle HAPTICS_EN for a clear start point of FIFO playing */
rc = haptics_toggle_module_enable(chip);
if (rc < 0)
return rc;
}
/* Clamp VMAX for different vibration strength */
rc = haptics_set_vmax_mv(chip, play->vmax_mv);
if (rc < 0)
@ -1912,6 +1961,11 @@ static int haptics_load_custom_effect(struct haptics_chip *chip,
play->effect = chip->custom_effect;
play->brake = NULL;
play->vmax_mv = (magnitude * chip->custom_effect->vmax_mv) / 0x7fff;
/* Toggle HAPTICS_EN for a clear start point of FIFO playing */
rc = haptics_toggle_module_enable(chip);
if (rc < 0)
goto cleanup;
rc = haptics_set_vmax_mv(chip, play->vmax_mv);
if (rc < 0)
goto cleanup;
@ -2335,6 +2389,15 @@ static int haptics_hw_init(struct haptics_chip *chip)
if (rc < 0)
return rc;
/* Force VREG_RDY if non-HBoost is used for powering haptics */
if (chip->hpwr_vreg) {
rc = haptics_masked_write(chip, chip->cfg_addr_base,
HAP_CFG_VSET_CFG_REG, FORCE_VREG_RDY_BIT,
FORCE_VREG_RDY_BIT);
if (rc < 0)
return rc;
}
if (config->is_erm)
return 0;
@ -2404,11 +2467,8 @@ static irqreturn_t fifo_empty_irq_handler(int irq, void *data)
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);
if (!(val & FIFO_EMPTY_BIT))
return IRQ_HANDLED;
}
mutex_lock(&chip->play.lock);
if (atomic_read(&chip->play.fifo_status.written_done) == 1) {
@ -4286,7 +4346,6 @@ static int haptics_suspend(struct device *dev)
{
struct haptics_chip *chip = dev_get_drvdata(dev);
struct haptics_play_info *play = &chip->play;
u8 val = 0;
int rc;
if (chip->cfg_revision == HAP_CFG_V1)
@ -4319,20 +4378,17 @@ static int haptics_suspend(struct device *dev)
if (rc < 0)
return rc;
return haptics_write(chip, chip->cfg_addr_base,
HAP_CFG_EN_CTL_REG, &val, 1);
return haptics_module_enable(chip, false);
}
static int haptics_resume(struct device *dev)
{
struct haptics_chip *chip = dev_get_drvdata(dev);
u8 val = HAPTICS_EN_BIT;
if (chip->cfg_revision == HAP_CFG_V1)
return 0;
return haptics_write(chip, chip->cfg_addr_base,
HAP_CFG_EN_CTL_REG, &val, 1);
return haptics_module_enable(chip, true);
}
#endif