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 <quic_fenglinw@quicinc.com>
This commit is contained in:
Fenglin Wu 2022-01-13 18:04:20 +08:00 committed by David Collins
parent eeca4b54e1
commit e8e7d6a836

View File

@ -27,6 +27,8 @@
#include <linux/uaccess.h>
#include <linux/qpnp/qpnp-pbs.h>
#include <linux/soc/qcom/battery_charger.h>
/* 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);