Merge "input: qcom-hv-haptics: delay hBoost turning off"

This commit is contained in:
qctecmdr
2022-01-06 05:16:22 -08:00
committed by Gerrit - the friendly Code Review server

View File

@@ -8,6 +8,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/hrtimer.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -486,6 +487,7 @@ struct haptics_chip {
struct device_node *pbs_node;
struct class hap_class;
struct regulator *hpwr_vreg;
struct hrtimer hbst_off_timer;
int fifo_empty_irq;
u32 hpwr_voltage_mv;
u32 effects_count;
@@ -499,6 +501,7 @@ struct haptics_chip {
bool swr_slave_enabled;
bool clamp_at_5v;
bool hpwr_vreg_enabled;
bool hboost_enabled;
};
struct haptics_reg_info {
@@ -1177,6 +1180,9 @@ static int haptics_boost_vreg_enable(struct haptics_chip *chip, bool en)
return 0;
}
if (chip->hboost_enabled == en)
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);
@@ -1189,11 +1195,14 @@ static int haptics_boost_vreg_enable(struct haptics_chip *chip, bool en)
val = PBS_TRIG_SET_VAL;
rc = nvmem_device_write(chip->hap_cfg_nvmem,
PBS_TRIG_SET_REG, 1, &val);
if (rc < 0)
if (rc < 0) {
dev_err(chip->dev, "Write SDAM %#x failed, rc=%d\n",
PBS_TRIG_SET_REG, rc);
return rc;
}
return rc;
chip->hboost_enabled = en;
return 0;
}
static bool is_swr_play_enabled(struct haptics_chip *chip)
@@ -1237,6 +1246,13 @@ static int haptics_wait_hboost_ready(struct haptics_chip *chip)
int i, rc;
u8 val;
if ((hrtimer_get_remaining(&chip->hbst_off_timer) > 0) ||
hrtimer_active(&chip->hbst_off_timer)) {
hrtimer_cancel(&chip->hbst_off_timer);
dev_dbg(chip->dev, "hboost is still on, ignore\n");
return 0;
}
/*
* Wait ~20ms until hBoost is ready, otherwise
* bail out and return -EBUSY
@@ -1372,6 +1388,7 @@ static int haptics_open_loop_drive_config(struct haptics_chip *chip, bool en)
return rc;
}
#define BOOST_VREG_OFF_DELAY_SECONDS 2
static int haptics_enable_play(struct haptics_chip *chip, bool en)
{
struct haptics_play_info *play = &chip->play;
@@ -1405,11 +1422,17 @@ static int haptics_enable_play(struct haptics_chip *chip, bool en)
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);
if (en) {
rc = haptics_boost_vreg_enable(chip, true);
if (rc < 0) {
dev_err(chip->dev, "Keep boost vreg on failed, rc=%d\n",
rc);
return rc;
}
} else {
hrtimer_start(&chip->hbst_off_timer,
ktime_set(BOOST_VREG_OFF_DELAY_SECONDS, 0),
HRTIMER_MODE_REL);
}
return rc;
@@ -4373,6 +4396,21 @@ static struct attribute *hap_class_attrs[] = {
};
ATTRIBUTE_GROUPS(hap_class);
static enum hrtimer_restart haptics_disable_hbst_timer(struct hrtimer *timer)
{
struct haptics_chip *chip = container_of(timer,
struct haptics_chip, hbst_off_timer);
int rc;
rc = haptics_boost_vreg_enable(chip, false);
if (rc < 0)
dev_err(chip->dev, "disable boost vreg failed, rc=%d\n", rc);
else
dev_dbg(chip->dev, "boost vreg is disabled\n");
return HRTIMER_NORESTART;
}
static int haptics_probe(struct platform_device *pdev)
{
struct haptics_chip *chip;
@@ -4432,6 +4470,8 @@ static int haptics_probe(struct platform_device *pdev)
mutex_init(&chip->play.lock);
disable_irq_nosync(chip->fifo_empty_irq);
chip->fifo_empty_irq_en = false;
hrtimer_init(&chip->hbst_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
chip->hbst_off_timer.function = haptics_disable_hbst_timer;
atomic_set(&chip->play.fifo_status.is_busy, 0);
atomic_set(&chip->play.fifo_status.written_done, 0);
@@ -4541,6 +4581,12 @@ static int haptics_suspend(struct device *dev)
}
mutex_unlock(&play->lock);
/*
* Cancel the hBoost turning off timer and disable
* hBoost if it's still enabled
*/
hrtimer_cancel(&chip->hbst_off_timer);
haptics_boost_vreg_enable(chip, false);
rc = haptics_enable_hpwr_vreg(chip, false);
if (rc < 0)
return rc;