Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cace14e4 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 1ebc5a86 8c194abb
Loading
Loading
Loading
Loading
+54 −7
Original line number Diff line number Diff line
@@ -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>
@@ -511,6 +512,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;
@@ -529,6 +531,7 @@ struct haptics_chip {
	bool				clamp_at_5v;
	bool				hpwr_vreg_enabled;
	bool				is_hv_haptics;
	bool				hboost_enabled;
};

struct haptics_reg_info {
@@ -1292,6 +1295,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);
@@ -1304,13 +1310,16 @@ 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;
	}

	chip->hboost_enabled = en;
	return 0;
}

static bool is_swr_play_enabled(struct haptics_chip *chip)
{
	int rc;
@@ -1357,6 +1366,14 @@ static int haptics_wait_hboost_ready(struct haptics_chip *chip)

	if (is_haptics_external_powered(chip))
		return 0;

	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
@@ -1493,6 +1510,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;
@@ -1526,11 +1544,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;
@@ -4582,6 +4606,21 @@ static bool is_swr_supported(struct haptics_chip *chip)
	return true;
}

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;
@@ -4646,6 +4685,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);
@@ -4755,6 +4796,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;