From e8e7d6a83638fb4ecd919c36df96af4483f36fc8 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Thu, 13 Jan 2022 18:04:20 +0800 Subject: [PATCH] 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);