Merge "input: qcom-hv-haptics: delay hBoost turning off"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
532272d596
@@ -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;
|
||||
|
Reference in New Issue
Block a user