From 468928c5956b21a0f42357bb6209b2b9260dc9b4 Mon Sep 17 00:00:00 2001 From: Umang Chheda Date: Wed, 24 Nov 2021 21:34:45 +0530 Subject: [PATCH 1/4] input: qcom-hv-haptics: Disable INT and module in shutdown cb On SKUs with MSM + Co-proc there can be possiblity that because of Interrupts enabled from MSM side (SPMI) the exit of LPM might not work because PBS gets locked because of which the sequence to exit LPM might not get triggered. Add support for shutdown callback and disable INT in shutdown cb to ensure that INT are disabled before entering LPM. Change-Id: I29bafb72bef3a5591839015f2a598fa4ad85072a Signed-off-by: Umang Chheda --- drivers/input/misc/qcom-hv-haptics.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index c73c25c35cc6..402e318bf51d 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -5647,6 +5647,16 @@ static int haptics_restore(struct device *dev) return rc; return haptics_module_enable(chip, true); + +} + +static void haptics_shutdown(struct platform_device *pdev) +{ + struct haptics_chip *chip = platform_get_drvdata(pdev); + + haptics_suspend_config(chip->dev); + + haptics_ds_suspend_config(chip->dev); } static const struct dev_pm_ops haptics_pm_ops = { @@ -5676,6 +5686,7 @@ static struct platform_driver haptics_driver = { .pm = &haptics_pm_ops, }, .probe = haptics_probe, + .shutdown = haptics_shutdown, .remove = haptics_remove, }; module_platform_driver(haptics_driver); From cbda83d0be01589ac8a8403a93943e77cfa89d16 Mon Sep 17 00:00:00 2001 From: Hui Liu Date: Wed, 17 Aug 2022 17:27:29 +0800 Subject: [PATCH 2/4] input: qcom-hv-haptics: move predefined effect preload logging Move the logging after calculating Vmax so that the right Vmax value can be printed out. Change-Id: I8d916a13685c8d85f1363e7a8bc766aeb4d5e2ba Signed-off-by: Hui Liu --- drivers/input/misc/qcom-hv-haptics.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index 402e318bf51d..b9db7e428b49 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -2410,9 +2410,6 @@ static int haptics_load_periodic_effect(struct haptics_chip *chip, return -EINVAL; } - dev_dbg(chip->dev, "upload %s effect %d, vmax=%d\n", primitive ? "primitive" : "predefined", - effects[i].id, play->vmax_mv); - mutex_lock(&chip->play.lock); if (chip->play.in_calibration) { dev_err(chip->dev, "calibration in progress, ignore playing predefined effect\n"); @@ -2421,6 +2418,9 @@ static int haptics_load_periodic_effect(struct haptics_chip *chip, } play->vmax_mv = (magnitude * effects[i].vmax_mv) / 0x7fff; + dev_dbg(chip->dev, "upload %s effect %d, vmax=%d\n", primitive ? "primitive" : "predefined", + effects[i].id, play->vmax_mv); + rc = haptics_load_predefined_effect(chip, &effects[i]); if (rc < 0) { dev_err(chip->dev, "Play predefined effect%d failed, rc=%d\n", From d6bb90e31cd92a78e38ffa6db0cf3b3b0a220da1 Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Mon, 22 Aug 2022 16:52:18 -0700 Subject: [PATCH 3/4] input: qcom-hv-haptics: Update autoresonance registers for F0 calibration Update the register configuration for F0 detection/calibration based on hardware recommendation. Change-Id: I423ed84bf10508dc6ded2bc4248ac9ce396ce8cb Signed-off-by: Anjelique Melendez --- drivers/input/misc/qcom-hv-haptics.c | 42 +++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index b9db7e428b49..01b2589565c1 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -140,6 +140,12 @@ #define HAP_CFG_DRV_DUTY_CFG_REG 0x60 #define ADT_DRV_DUTY_EN_BIT BIT(7) +#define ADT_BRK_DUTY_EN_BIT BIT(6) +#define DRV_DUTY_MASK GENMASK(5, 3) +#define DRV_DUTY_62P5_PCT 2 +#define DRV_DUTY_SHIFT 3 +#define BRK_DUTY_MASK GENMASK(2, 0) +#define BRK_DUTY_75_PCT 6 #define HAP_CFG_ADT_DRV_DUTY_CFG_REG 0x61 #define HAP_CFG_ZX_WIND_CFG_REG 0x62 @@ -149,6 +155,7 @@ #define AUTORES_EN_DLY_MASK GENMASK(5, 2) #define AUTORES_EN_DLY(cycles) ((cycles) * 2) #define AUTORES_EN_DLY_6_CYCLES AUTORES_EN_DLY(6) +#define AUTORES_EN_DLY_7_CYCLES AUTORES_EN_DLY(7) #define AUTORES_EN_DLY_SHIFT 2 #define AUTORES_ERR_WINDOW_MASK GENMASK(1, 0) #define AUTORES_ERR_WINDOW_12P5_PERCENT 0x0 @@ -5072,7 +5079,7 @@ static int haptics_detect_lra_impedance(struct haptics_chip *chip) static int haptics_detect_lra_frequency(struct haptics_chip *chip) { int rc; - u8 autores_cfg, amplitude; + u8 autores_cfg, drv_duty_cfg, amplitude, mask, val; u32 vmax_mv = chip->config.vmax_mv; rc = haptics_read(chip, chip->cfg_addr_base, @@ -5082,16 +5089,38 @@ static int haptics_detect_lra_frequency(struct haptics_chip *chip) return rc; } + rc = haptics_read(chip, chip->cfg_addr_base, + HAP_CFG_DRV_DUTY_CFG_REG, &drv_duty_cfg, 1); + if (rc < 0) { + dev_err(chip->dev, "Read DRV_DUTY_CFG failed, rc=%d\n", rc); + return rc; + } + + if (chip->hw_type == HAP525_HV) + val = AUTORES_EN_DLY_7_CYCLES << AUTORES_EN_DLY_SHIFT| + AUTORES_ERR_WINDOW_25_PERCENT | AUTORES_EN_BIT; + else + val = AUTORES_EN_DLY_6_CYCLES << AUTORES_EN_DLY_SHIFT| + AUTORES_ERR_WINDOW_50_PERCENT | AUTORES_EN_BIT; + rc = haptics_masked_write(chip, chip->cfg_addr_base, HAP_CFG_AUTORES_CFG_REG, AUTORES_EN_BIT | AUTORES_EN_DLY_MASK | AUTORES_ERR_WINDOW_MASK, - AUTORES_EN_DLY_6_CYCLES << AUTORES_EN_DLY_SHIFT - | AUTORES_ERR_WINDOW_50_PERCENT | AUTORES_EN_BIT); + val); if (rc < 0) return rc; + if (chip->hw_type == HAP525_HV) { + mask = ADT_DRV_DUTY_EN_BIT | ADT_BRK_DUTY_EN_BIT | + DRV_DUTY_MASK | BRK_DUTY_MASK; + val = DRV_DUTY_62P5_PCT << DRV_DUTY_SHIFT | BRK_DUTY_75_PCT; + } else { + mask = ADT_DRV_DUTY_EN_BIT; + val = 0; + } + rc = haptics_masked_write(chip, chip->cfg_addr_base, - HAP_CFG_DRV_DUTY_CFG_REG, ADT_DRV_DUTY_EN_BIT, 0); + HAP_CFG_DRV_DUTY_CFG_REG, mask, val); if (rc < 0) goto restore; @@ -5150,9 +5179,8 @@ static int haptics_detect_lra_frequency(struct haptics_chip *chip) if (rc < 0) return rc; - rc = haptics_masked_write(chip, chip->cfg_addr_base, - HAP_CFG_DRV_DUTY_CFG_REG, ADT_DRV_DUTY_EN_BIT, - ADT_DRV_DUTY_EN_BIT); + rc = haptics_write(chip, chip->cfg_addr_base, + HAP_CFG_DRV_DUTY_CFG_REG, &drv_duty_cfg, 1); return rc; } From 531d907590efd4fd887d21b5ef4f7dddfa957cb0 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Wed, 24 Aug 2022 15:21:18 +0800 Subject: [PATCH 4/4] input: qcom-hv-haptics: update configuration for PATx_MEM mode Disable auto resonance explicitly for PATx_MEM mode play according to HW recommendation. Also, clear MEM_PAT_ACCESS_BIT after written PATx_MEM samples and it reduces device quiescent current in power off state. Change-Id: Iafaca15482bf1a03a19a49ee4d5e30faeb2fdeeb Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index 01b2589565c1..cb0aebfb29ae 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -1844,7 +1844,10 @@ static int haptics_update_pat_mem_samples(struct haptics_chip *chip, if (rc < 0) return rc; - return haptics_update_memory_data(chip, samples, length); + rc = haptics_update_memory_data(chip, samples, length); + rc |= haptics_masked_write(chip, chip->ptn_addr_base, + HAP_PTN_MEM_OP_ACCESS_REG, MEM_PAT_ACCESS_BIT, 0); + return rc; } static int haptics_get_fifo_fill_status(struct haptics_chip *chip, u32 *fill) @@ -2182,6 +2185,11 @@ static int haptics_load_predefined_effect(struct haptics_chip *chip, return -EINVAL; } + /* disable auto resonance for PATx_MEM mode */ + rc = haptics_enable_autores(chip, false); + if (rc < 0) + return rc; + dev_dbg(chip->dev, "Ignore loading data for preload FIFO effect: %d\n", play->effect->id); }