From eeca4b54e1536c019809ad0f606cc2f83a6f58b2 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Mon, 14 Mar 2022 16:03:54 +0800 Subject: [PATCH 1/2] input: qcom-hv-haptics: enable SW_CTRL_HBST workarounds for PM8550B V1 Enable SW_CTRL_HBST workarounds for haptics module in PM8550B V1 silicon in which the HAPTICS_BOOST module is having digital revision as V0.1. Change-Id: Ida824ae0846cef1e2be6adade0f3b4ac2461bf06 Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index 160cd0e92076..fea2f37299c3 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -257,6 +257,7 @@ #define HAP_BOOST_REVISION2 0x01 #define HAP_BOOST_V0P0 0x0000 #define HAP_BOOST_V0P1 0x0001 +#define HAP_BOOST_V0P2 0x0002 #define HAP_BOOST_STATUS4_REG 0x0B #define BOOST_DTEST1_STATUS_BIT BIT(0) @@ -2912,7 +2913,10 @@ static int haptics_config_wa(struct haptics_chip *chip) TOGGLE_EN_TO_FLUSH_FIFO | RECOVER_SWR_SLAVE; break; case HAP520_MV: + break; case HAP525_HV: + if (chip->hbst_revision == HAP_BOOST_V0P1) + chip->wa_flags |= SW_CTRL_HBST; break; default: dev_err(chip->dev, "HW type %d does not match\n", From e8e7d6a83638fb4ecd919c36df96af4483f36fc8 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Thu, 13 Jan 2022 18:04:20 +0800 Subject: [PATCH 2/2] input: qcom-hv-haptics: Handle VMAX_CLAMP notification Handle VMAX_CLAMP notification which contains a desired Vmax value when hBoost is enabled by the charger firmware. Any vibration after this notification should be set to a Vmax not higher than that to avoid hBoost overloading. Change-Id: I6fb1b66663df60041967e2cad0a914f57c310158 Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index fea2f37299c3..07eafe654a32 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -27,6 +27,8 @@ #include #include +#include + /* status register definitions in HAPTICS_CFG module */ #define HAP_CFG_REVISION2_REG 0x01 #define HAP_CFG_V1 0x1 @@ -546,12 +548,14 @@ struct haptics_chip { struct class hap_class; struct regulator *hpwr_vreg; struct hrtimer hbst_off_timer; + struct notifier_block hboost_nb; int fifo_empty_irq; u32 hpwr_voltage_mv; u32 effects_count; u32 cfg_addr_base; u32 ptn_addr_base; u32 hbst_addr_base; + u32 clamped_vmax_mv; u32 wa_flags; u8 cfg_revision; u8 ptn_revision; @@ -1122,6 +1126,9 @@ static int haptics_set_vmax_mv(struct haptics_chip *chip, u32 vmax_mv) return -EINVAL; } + if ((chip->clamped_vmax_mv != 0) && (vmax_mv > chip->clamped_vmax_mv)) + vmax_mv = chip->clamped_vmax_mv; + if (chip->clamp_at_5v && (vmax_mv > CLAMPED_VMAX_MV)) vmax_mv = CLAMPED_VMAX_MV; @@ -4803,6 +4810,31 @@ static enum hrtimer_restart haptics_disable_hbst_timer(struct hrtimer *timer) return HRTIMER_NORESTART; } +static int haptics_boost_notifier(struct notifier_block *nb, unsigned long event, void *val) +{ + struct haptics_chip *chip = container_of(nb, struct haptics_chip, hboost_nb); + u32 vmax_mv; + + switch (event) { + case VMAX_CLAMP: + vmax_mv = *(u32 *)val; + if (vmax_mv > MAX_HV_VMAX_MV) { + dev_err(chip->dev, "voted Vmax (%u mV) is higher than maximum (%u mV)\n", + vmax_mv, MAX_HV_VMAX_MV); + return -EINVAL; + } + + chip->clamped_vmax_mv = vmax_mv; + dev_dbg(chip->dev, "Vmax is clamped at %u mV to support hBoost concurrency\n", + vmax_mv); + break; + default: + break; + } + + return 0; +} + static int haptics_probe(struct platform_device *pdev) { struct haptics_chip *chip; @@ -4914,6 +4946,8 @@ static int haptics_probe(struct platform_device *pdev) goto destroy_ff; } + chip->hboost_nb.notifier_call = haptics_boost_notifier; + register_hboost_event_notifier(&chip->hboost_nb); #ifdef CONFIG_DEBUG_FS rc = haptics_create_debugfs(chip); if (rc < 0) @@ -4932,6 +4966,7 @@ static int haptics_remove(struct platform_device *pdev) if (chip->pbs_node) of_node_put(chip->pbs_node); + unregister_hboost_event_notifier(&chip->hboost_nb); class_unregister(&chip->hap_class); #ifdef CONFIG_DEBUG_FS debugfs_remove_recursive(chip->debugfs_dir);