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

Commit 93176040 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: qpnp-haptic: Add support for haptics on PM660"

parents c299352b 3dde7b3e
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ pwm(pulse width modulation) and audio.
Required Properties:
 - compatible: must be "qcom,qpnp-haptic"
 - reg: address of device
 - qcom,pmic-revid : phandle to fetch PMIC revid
 - qcom,actuator-type: must be one of "erm" or "lra"
 - qcom,play-mode : must be one of "buffer", "direct", "pwm" or "audio"

@@ -63,7 +64,13 @@ Optional properties when qcom,actuator-type is "lra"
			"max-qwd" : Maximum QWD
			"zxd-eop" : ZXD + End of pattern (This is the Default)
 - qcom,lra-high-z : High Z configuration for auto resonance. Possible string values are
			"none", "opt1", "opt2" and "opt3" (default)
			"none", "opt1", "opt2" and "opt3" (default). For PM660,
			"opt0" is valid value for 1 LRA period.
 - qcom,lra-qwd-drive-duration : Drive duration of LRA in QWD mode for PM660.
			Possible values are: 0: 1/4 LRA PERIOD and 1: 3/8 LRA PERIOD
 - qcom,lra-calibrate-at-eop : To calibrate at End of Pattern for PM660.
			Possible values are: 0 to disable and 1 to enable Calibration
			at End of Pattern
 - qcom,lra-res-cal-period : Auto resonance calibration period. The values range from
			4 to 32(default)
 - qcom,perform-lra-auto-resonance-search : boolean, define this property if:
@@ -109,6 +116,7 @@ Example:
			interrupts = <0x3 0xc0 0x0>,
				     <0x3 0xc0 0x1>;
			interrupt-names = "sc-irq", "play-irq";
			qcom,pmic-revid = <&pm660_revid>;
			vcc_pon-supply = <&pon_perph_reg>;
			qcom,play-mode = "direct";
			qcom,wave-play-rate-us = <5263>;
+3 −2
Original line number Diff line number Diff line
@@ -607,6 +607,7 @@
			interrupts = <0x1 0xc0 0x0 IRQ_TYPE_NONE>,
				     <0x1 0xc0 0x1 IRQ_TYPE_NONE>;
			interrupt-names = "sc-irq", "play-irq";
			qcom,pmic-revid = <&pm660_revid>;
			qcom,actuator-type = "lra";
			qcom,play-mode = "direct";
			qcom,vmax-mv = <3200>;
@@ -619,9 +620,9 @@
			qcom,brake-pattern = [03 03 00 00];
			qcom,use-play-irq;
			qcom,use-sc-irq;
			qcom,lra-high-z = "opt1";
			qcom,lra-high-z = "opt0";
			qcom,lra-auto-res-mode = "qwd";
			qcom,lra-res-cal-period = <4>;
			qcom,lra-calibrate-at-eop = <0>;
			qcom,correct-lra-drive-freq;
			qcom,misc-trim-error-rc19p2-clk-reg-present;
		};
+1 −0
Original line number Diff line number Diff line
@@ -631,6 +631,7 @@
			interrupts = <0x3 0xc0 0x0 IRQ_TYPE_NONE>,
				     <0x3 0xc0 0x1 IRQ_TYPE_NONE>;
			interrupt-names = "sc-irq", "play-irq";
			qcom,pmic-revid = <&pmi8998_revid>;
			qcom,actuator-type = "lra";
			qcom,play-mode = "direct";
			qcom,vmax-mv = <3200>;
+209 −53
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/qpnp/pwm.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/qpnp/qpnp-revid.h>
#include <linux/qpnp/qpnp-haptic.h>
#include "../../staging/android/timed_output.h"

@@ -37,6 +38,7 @@
#define QPNP_HAP_LRA_AUTO_RES_HI(b)     (b + 0x0C)
#define QPNP_HAP_EN_CTL_REG(b)		(b + 0x46)
#define QPNP_HAP_EN_CTL2_REG(b)		(b + 0x48)
#define QPNP_HAP_AUTO_RES_CTRL(b)	(b + 0x4B)
#define QPNP_HAP_ACT_TYPE_REG(b)	(b + 0x4C)
#define QPNP_HAP_WAV_SHAPE_REG(b)	(b + 0x4D)
#define QPNP_HAP_PLAY_MODE_REG(b)	(b + 0x4E)
@@ -62,13 +64,25 @@
#define QPNP_HAP_ACT_TYPE_MASK		0xFE
#define QPNP_HAP_LRA			0x0
#define QPNP_HAP_ERM			0x1
#define QPNP_HAP_AUTO_RES_MODE_MASK	0x8F
#define QPNP_HAP_AUTO_RES_MODE_MASK	GENMASK(6, 4)
#define QPNP_HAP_AUTO_RES_MODE_SHIFT	4
#define QPNP_HAP_LRA_HIGH_Z_MASK	0xF3
#define QPNP_HAP_PM660_AUTO_RES_MODE_BIT	BIT(7)
#define QPNP_HAP_PM660_AUTO_RES_MODE_SHIFT	7
#define QPNP_HAP_PM660_CALIBRATE_DURATION_MASK	GENMASK(6, 5)
#define QPNP_HAP_PM660_CALIBRATE_DURATION_SHIFT	5
#define QPNP_HAP_PM660_QWD_DRIVE_DURATION_BIT	BIT(4)
#define QPNP_HAP_PM660_QWD_DRIVE_DURATION_SHIFT	4
#define QPNP_HAP_PM660_CALIBRATE_AT_EOP_BIT	BIT(3)
#define QPNP_HAP_PM660_CALIBRATE_AT_EOP_SHIFT	3
#define QPNP_HAP_PM660_LRA_ZXD_CAL_PERIOD_BIT	GENMASK(2, 0)
#define QPNP_HAP_LRA_HIGH_Z_MASK	GENMASK(3, 2)
#define QPNP_HAP_LRA_HIGH_Z_SHIFT	2
#define QPNP_HAP_LRA_RES_CAL_PER_MASK	0xFC
#define QPNP_HAP_LRA_RES_CAL_PER_MASK	GENMASK(1, 0)
#define QPNP_HAP_PM660_LRA_RES_CAL_PER_MASK	GENMASK(2, 0)
#define QPNP_HAP_RES_CAL_PERIOD_MIN	4
#define QPNP_HAP_RES_CAL_PERIOD_MAX	32
#define QPNP_HAP_PM660_RES_CAL_PERIOD_MIN	4
#define QPNP_HAP_PM660_RES_CAL_PERIOD_MAX	256
#define QPNP_HAP_PLAY_MODE_MASK		0xCF
#define QPNP_HAP_PLAY_MODE_SHFT		4
#define QPNP_HAP_VMAX_MASK		0xC1
@@ -130,7 +144,6 @@
#define QPNP_HAP_TEST2_AUTO_RES_MASK	0x7F
#define QPNP_HAP_SEC_UNLOCK		0xA5
#define AUTO_RES_ENABLE			0x80
#define AUTO_RES_DISABLE		0x00
#define AUTO_RES_ERR_BIT		0x10
#define SC_FOUND_BIT			0x08
#define SC_MAX_DURATION			5
@@ -222,9 +235,14 @@ enum qpnp_hap_auto_res_mode {
	QPNP_HAP_AUTO_RES_ZXD_EOP,
};

enum qpnp_hap_pm660_auto_res_mode {
	QPNP_HAP_PM660_AUTO_RES_ZXD,
	QPNP_HAP_PM660_AUTO_RES_QWD,
};

/* high Z option lines */
enum qpnp_hap_high_z {
	QPNP_HAP_LRA_HIGH_Z_NONE,
	QPNP_HAP_LRA_HIGH_Z_NONE, /* opt0 for PM660 */
	QPNP_HAP_LRA_HIGH_Z_OPT1,
	QPNP_HAP_LRA_HIGH_Z_OPT2,
	QPNP_HAP_LRA_HIGH_Z_OPT3,
@@ -240,7 +258,7 @@ enum qpnp_hap_mode {

/* status flags */
enum qpnp_hap_status {
	AUTO_RESONANCE_ENABLED = 1,
	AUTO_RESONANCE_ENABLED = BIT(0),
};

/* pwm channel info */
@@ -271,6 +289,7 @@ struct qpnp_pwm_info {
      percentage variation on the higher side.
 *  @ drive_period_code_min_limit - calculated drive period code with
      percentage variation on the lower side
 *  @ lra_res_cal_period - LRA resonance calibration period
 *  @ play_mode - play mode
 *  @ auto_res_mode - auto resonace mode
 *  @ lra_high_z - high z option line
@@ -327,8 +346,9 @@ struct qpnp_hap {
	struct mutex			wf_lock;
	struct completion		completion;
	enum qpnp_hap_mode		play_mode;
	enum qpnp_hap_auto_res_mode	auto_res_mode;
	enum qpnp_hap_high_z		lra_high_z;
	int				lra_qwd_drive_duration;
	int				calibrate_at_eop;
	u32				init_drive_period_code;
	u32				timeout_ms;
	u32				time_required_to_generate_back_emf_us;
@@ -346,6 +366,7 @@ struct qpnp_hap {
	u16				base;
	u16				drive_period_code_max_limit;
	u16				drive_period_code_min_limit;
	u16				lra_res_cal_period;
	u8			drive_period_code_max_limit_percent_variation;
	u8			drive_period_code_min_limit_percent_variation;
	u8				act_type;
@@ -355,9 +376,10 @@ struct qpnp_hap {
	u8				brake_pat[QPNP_HAP_BRAKE_PAT_LEN];
	u8				reg_en_ctl;
	u8				reg_play;
	u8				lra_res_cal_period;
	u8				sc_duration;
	u8				ext_pwm_dtest_line;
	u8				pmic_subtype;
	u8				auto_res_mode;
	bool				vcc_pon_enabled;
	bool				state;
	bool				use_play_irq;
@@ -403,6 +425,21 @@ static int qpnp_hap_write_reg(struct qpnp_hap *hap, u8 *data, u16 addr)
	return rc;
}

static int
qpnp_hap_masked_write_reg(struct qpnp_hap *hap, u8 val, u16 addr, u8 mask)
{
	int rc;

	rc = regmap_update_bits(hap->regmap, addr, mask, val);
	if (rc < 0)
		pr_err("Unable to update bits from 0x%04X, rc = %d\n", addr,
			rc);
	else
		pr_debug("Wrote 0x%02X to addr 0x%04X\n", val, addr);

	return rc;
}

/* helper to access secure registers */
static int qpnp_hap_sec_access(struct qpnp_hap *hap)
{
@@ -1413,24 +1450,24 @@ static int calculate_lra_code(struct qpnp_hap *hap)
static int qpnp_hap_auto_res_enable(struct qpnp_hap *hap, int enable)
{
	int rc = 0;
	u8 val;

	rc = qpnp_hap_read_reg(hap, &val, QPNP_HAP_TEST2_REG(hap->base));
	if (rc < 0)
		return rc;
	val &= QPNP_HAP_TEST2_AUTO_RES_MASK;
	u8 val = 0;
	u16 addr;

	if (enable)
		val |= AUTO_RES_ENABLE;
	else
		val |= AUTO_RES_DISABLE;

	if (hap->pmic_subtype == PM660_SUBTYPE) {
		addr = QPNP_HAP_AUTO_RES_CTRL(hap->base);
	} else {
		addr = QPNP_HAP_TEST2_REG(hap->base);
		/* TEST2 is a secure access register */
		rc = qpnp_hap_sec_access(hap);
		if (rc)
			return rc;
	}

	rc = qpnp_hap_write_reg(hap, &val, QPNP_HAP_TEST2_REG(hap->base));
	if (enable)
		val |= AUTO_RES_ENABLE;

	rc = qpnp_hap_masked_write_reg(hap, val, addr, AUTO_RES_ENABLE);
	if (rc)
		return rc;

@@ -1512,6 +1549,7 @@ static enum hrtimer_restart detect_auto_res_error(struct hrtimer *timer)
/* set api for haptics */
static int qpnp_hap_set(struct qpnp_hap *hap, int on)
{
	u8 auto_res_mode_qwd;
	int rc = 0;
	unsigned long timeout_ns = POLL_TIME_AUTO_RES_ERR_NS;
	u32 back_emf_delay_us = hap->time_required_to_generate_back_emf_us;
@@ -1536,9 +1574,16 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)
			 * and enable it after the sleep of
			 * 'time_required_to_generate_back_emf_us' is completed.
			 */
			if (hap->pmic_subtype == PM660_SUBTYPE)
				auto_res_mode_qwd = (hap->auto_res_mode ==
						QPNP_HAP_PM660_AUTO_RES_QWD);
			else
				auto_res_mode_qwd = (hap->auto_res_mode ==
							QPNP_HAP_AUTO_RES_QWD);

			if ((hap->act_type == QPNP_HAP_LRA) &&
				(hap->correct_lra_drive_freq ||
				hap->auto_res_mode == QPNP_HAP_AUTO_RES_QWD))
				auto_res_mode_qwd))
				qpnp_hap_auto_res_enable(hap, 0);

			rc = qpnp_hap_mod_enable(hap, on);
@@ -1549,7 +1594,7 @@ static int qpnp_hap_set(struct qpnp_hap *hap, int on)

			if ((hap->act_type == QPNP_HAP_LRA) &&
				(hap->correct_lra_drive_freq ||
				hap->auto_res_mode == QPNP_HAP_AUTO_RES_QWD)) {
				auto_res_mode_qwd)) {
				usleep_range(back_emf_delay_us,
						(back_emf_delay_us + 1));

@@ -1782,7 +1827,7 @@ static SIMPLE_DEV_PM_OPS(qpnp_haptic_pm_ops, qpnp_haptic_suspend, NULL);
/* Configuration api for haptics registers */
static int qpnp_hap_config(struct qpnp_hap *hap)
{
	u8 reg = 0, unlock_val;
	u8 reg = 0, unlock_val, mask;
	u32 temp;
	int rc, i;
	uint error_code = 0;
@@ -1804,24 +1849,66 @@ static int qpnp_hap_config(struct qpnp_hap *hap)

	/* Configure auto resonance parameters */
	if (hap->act_type == QPNP_HAP_LRA) {
		if (hap->lra_res_cal_period < QPNP_HAP_RES_CAL_PERIOD_MIN)
			hap->lra_res_cal_period = QPNP_HAP_RES_CAL_PERIOD_MIN;
		else if (hap->lra_res_cal_period > QPNP_HAP_RES_CAL_PERIOD_MAX)
			hap->lra_res_cal_period = QPNP_HAP_RES_CAL_PERIOD_MAX;

		rc = qpnp_hap_read_reg(hap, &reg,
					QPNP_HAP_LRA_AUTO_RES_REG(hap->base));
		if (rc < 0)
			return rc;
		reg &= QPNP_HAP_AUTO_RES_MODE_MASK;
		reg |= (hap->auto_res_mode << QPNP_HAP_AUTO_RES_MODE_SHIFT);
		reg &= QPNP_HAP_LRA_HIGH_Z_MASK;
		if (hap->pmic_subtype == PM660_SUBTYPE) {
			if (hap->lra_res_cal_period <
					QPNP_HAP_PM660_RES_CAL_PERIOD_MIN)
				hap->lra_res_cal_period =
					QPNP_HAP_PM660_RES_CAL_PERIOD_MIN;
			else if (hap->lra_res_cal_period >
					QPNP_HAP_PM660_RES_CAL_PERIOD_MAX)
				hap->lra_res_cal_period =
					QPNP_HAP_PM660_RES_CAL_PERIOD_MAX;
		} else if (hap->pmic_subtype != PM660_SUBTYPE) {
			if (hap->lra_res_cal_period <
					QPNP_HAP_RES_CAL_PERIOD_MIN)
				hap->lra_res_cal_period =
					QPNP_HAP_RES_CAL_PERIOD_MIN;
			else if (hap->lra_res_cal_period >
					QPNP_HAP_RES_CAL_PERIOD_MAX)
				hap->lra_res_cal_period =
					QPNP_HAP_RES_CAL_PERIOD_MAX;
		}
		if (hap->pmic_subtype == PM660_SUBTYPE &&
			hap->auto_res_mode == QPNP_HAP_PM660_AUTO_RES_QWD) {
			hap->lra_res_cal_period = 0;
		}

		reg = mask = 0;
		if (hap->pmic_subtype == PM660_SUBTYPE) {
			reg |= hap->auto_res_mode <<
				QPNP_HAP_PM660_AUTO_RES_MODE_SHIFT;
			mask = QPNP_HAP_PM660_AUTO_RES_MODE_BIT;
			reg |= hap->lra_high_z <<
					QPNP_HAP_PM660_CALIBRATE_DURATION_SHIFT;
			mask |= QPNP_HAP_PM660_CALIBRATE_DURATION_MASK;
			if (hap->lra_qwd_drive_duration != -EINVAL) {
				reg |= hap->lra_qwd_drive_duration <<
					QPNP_HAP_PM660_QWD_DRIVE_DURATION_SHIFT;
				mask |= QPNP_HAP_PM660_QWD_DRIVE_DURATION_BIT;
			}
			if (hap->calibrate_at_eop != -EINVAL) {
				reg |= hap->calibrate_at_eop <<
					QPNP_HAP_PM660_CALIBRATE_AT_EOP_SHIFT;
				mask |= QPNP_HAP_PM660_CALIBRATE_AT_EOP_BIT;
			}
			if (hap->lra_res_cal_period) {
				temp = fls(hap->lra_res_cal_period) - 1;
				reg |= (temp - 1);
			}
			mask |= QPNP_HAP_PM660_LRA_RES_CAL_PER_MASK;
		} else {
			reg |= (hap->auto_res_mode <<
						QPNP_HAP_AUTO_RES_MODE_SHIFT);
			mask = QPNP_HAP_AUTO_RES_MODE_MASK;
			reg |= (hap->lra_high_z << QPNP_HAP_LRA_HIGH_Z_SHIFT);
		reg &= QPNP_HAP_LRA_RES_CAL_PER_MASK;
			mask |= QPNP_HAP_LRA_HIGH_Z_MASK;
			temp = fls(hap->lra_res_cal_period) - 1;
			reg |= (temp - 2);
		rc = qpnp_hap_write_reg(hap, &reg,
					QPNP_HAP_LRA_AUTO_RES_REG(hap->base));
			mask |= QPNP_HAP_LRA_RES_CAL_PER_MASK;
		}
		rc = qpnp_hap_masked_write_reg(hap, reg,
					QPNP_HAP_LRA_AUTO_RES_REG(hap->base),
					mask);
		if (rc)
			return rc;
	} else {
@@ -1867,8 +1954,13 @@ static int qpnp_hap_config(struct qpnp_hap *hap)

	/* Configure the INTERNAL_PWM register */
	if (hap->int_pwm_freq_khz <= QPNP_HAP_INT_PWM_FREQ_253_KHZ) {
		if (hap->pmic_subtype == PM660_SUBTYPE) {
			hap->int_pwm_freq_khz = QPNP_HAP_INT_PWM_FREQ_505_KHZ;
			temp = 1;
		} else {
			hap->int_pwm_freq_khz = QPNP_HAP_INT_PWM_FREQ_253_KHZ;
			temp = 0;
		}
	} else if (hap->int_pwm_freq_khz <= QPNP_HAP_INT_PWM_FREQ_505_KHZ) {
		hap->int_pwm_freq_khz = QPNP_HAP_INT_PWM_FREQ_505_KHZ;
		temp = 1;
@@ -2108,20 +2200,36 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
	}

	if (hap->act_type == QPNP_HAP_LRA) {
		hap->auto_res_mode = QPNP_HAP_AUTO_RES_ZXD_EOP;
		rc = of_property_read_string(pdev->dev.of_node,
				"qcom,lra-auto-res-mode", &temp_str);
		if (!rc) {
			if (hap->pmic_subtype == PM660_SUBTYPE) {
				hap->auto_res_mode =
						QPNP_HAP_PM660_AUTO_RES_QWD;
				if (strcmp(temp_str, "zxd") == 0)
					hap->auto_res_mode =
						QPNP_HAP_PM660_AUTO_RES_ZXD;
				else if (strcmp(temp_str, "qwd") == 0)
					hap->auto_res_mode =
						QPNP_HAP_PM660_AUTO_RES_QWD;
			} else {
				hap->auto_res_mode = QPNP_HAP_AUTO_RES_ZXD_EOP;
				if (strcmp(temp_str, "none") == 0)
				hap->auto_res_mode = QPNP_HAP_AUTO_RES_NONE;
					hap->auto_res_mode =
						QPNP_HAP_AUTO_RES_NONE;
				else if (strcmp(temp_str, "zxd") == 0)
				hap->auto_res_mode = QPNP_HAP_AUTO_RES_ZXD;
					hap->auto_res_mode =
						QPNP_HAP_AUTO_RES_ZXD;
				else if (strcmp(temp_str, "qwd") == 0)
				hap->auto_res_mode = QPNP_HAP_AUTO_RES_QWD;
					hap->auto_res_mode =
						QPNP_HAP_AUTO_RES_QWD;
				else if (strcmp(temp_str, "max-qwd") == 0)
				hap->auto_res_mode = QPNP_HAP_AUTO_RES_MAX_QWD;
					hap->auto_res_mode =
						QPNP_HAP_AUTO_RES_MAX_QWD;
				else
				hap->auto_res_mode = QPNP_HAP_AUTO_RES_ZXD_EOP;
					hap->auto_res_mode =
						QPNP_HAP_AUTO_RES_ZXD_EOP;
			}
		} else if (rc != -EINVAL) {
			dev_err(&pdev->dev, "Unable to read auto res mode\n");
			return rc;
@@ -2133,6 +2241,11 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
		if (!rc) {
			if (strcmp(temp_str, "none") == 0)
				hap->lra_high_z = QPNP_HAP_LRA_HIGH_Z_NONE;
			if (hap->pmic_subtype == PM660_SUBTYPE) {
				if (strcmp(temp_str, "opt0") == 0)
					hap->lra_high_z =
						QPNP_HAP_LRA_HIGH_Z_NONE;
			}
			else if (strcmp(temp_str, "opt1") == 0)
				hap->lra_high_z = QPNP_HAP_LRA_HIGH_Z_OPT1;
			else if (strcmp(temp_str, "opt2") == 0)
@@ -2144,6 +2257,15 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
			return rc;
		}

		hap->lra_qwd_drive_duration = -EINVAL;
		rc = of_property_read_u32(pdev->dev.of_node,
				"qcom,lra-qwd-drive-duration",
				&hap->lra_qwd_drive_duration);

		hap->calibrate_at_eop = -EINVAL;
		rc = of_property_read_u32(pdev->dev.of_node,
			"qcom,lra-calibrate-at-eop", &hap->calibrate_at_eop);

		hap->lra_res_cal_period = QPNP_HAP_RES_CAL_PERIOD_MAX;
		rc = of_property_read_u32(pdev->dev.of_node,
				"qcom,lra-res-cal-period", &temp);
@@ -2321,6 +2443,34 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap)
	return 0;
}

static int qpnp_hap_get_pmic_revid(struct qpnp_hap *hap)
{
	struct pmic_revid_data *pmic_rev_id;
	struct device_node *revid_dev_node;

	revid_dev_node = of_parse_phandle(hap->pdev->dev.of_node,
					"qcom,pmic-revid", 0);
	if (!revid_dev_node) {
		pr_err("Missing qcom,pmic-revid property - driver failed\n");
		return -EINVAL;
	}
	pmic_rev_id = get_revid_data(revid_dev_node);
	if (IS_ERR_OR_NULL(pmic_rev_id)) {
		pr_err("Unable to get pmic_revid rc=%ld\n",
						PTR_ERR(pmic_rev_id));
		/*
		 * the revid peripheral must be registered, any failure
		 * here only indicates that the rev-id module has not
		 * probed yet.
		 */
		return -EPROBE_DEFER;
	}

	hap->pmic_subtype = pmic_rev_id->pmic_subtype;

	return 0;
}

static int qpnp_haptic_probe(struct platform_device *pdev)
{
	struct qpnp_hap *hap;
@@ -2350,6 +2500,12 @@ static int qpnp_haptic_probe(struct platform_device *pdev)

	dev_set_drvdata(&pdev->dev, hap);

	rc = qpnp_hap_get_pmic_revid(hap);
	if (rc) {
		pr_err("Unable to check PMIC version rc=%d\n", rc);
		return rc;
	}

	rc = qpnp_hap_parse_dt(hap);
	if (rc) {
		dev_err(&pdev->dev, "DT parsing failed\n");