From 6daa29c301fc9068b46c438eaee546c6c41e5924 Mon Sep 17 00:00:00 2001 From: Fenglin Wu Date: Wed, 20 May 2020 12:14:43 +0800 Subject: [PATCH] input: qcom-hv-haptics: adjust T_LRA for auto RC CLK calibration case When auto RC clock calibration mode is selected, the 32.768 KHz sleep clock is used as the reference clock but the hardware module assumes the reference clock is 32 KHz. This results in inaccuracy on output drive frequency. Correct this by scaling the LRA period using a factor of 1.024 in auto RC clock calibration case. Change-Id: I1d4f6cb90c00ffbd9932928e64666a2122d8d4af Signed-off-by: Fenglin Wu --- drivers/input/misc/qcom-hv-haptics.c | 40 ++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/input/misc/qcom-hv-haptics.c b/drivers/input/misc/qcom-hv-haptics.c index 2ae879327dde..3193746e3858 100644 --- a/drivers/input/misc/qcom-hv-haptics.c +++ b/drivers/input/misc/qcom-hv-haptics.c @@ -140,6 +140,7 @@ #define HAP_CFG_CAL_EN_REG 0x72 #define CAL_RC_CLK_MASK GENMASK(3, 2) #define CAL_RC_CLK_SHIFT 2 +#define CAL_RC_CLK_AUTO_VAL 1 #define CAL_RC_CLK_MANUAL_VAL 2 /* version register definitions for HAPTICS_PATTERN module */ @@ -676,6 +677,26 @@ static int get_brake_play_length_us(struct brake_cfg *brake, u32 t_lra_us) #define V1_CL_TLRA_STEP_AUTO_RES_CAL_NOT_DONE_NS 5000 #define V1_CL_TLRA_STEP_AUTO_RES_CAL_DONE_NS 3333 +#define AUTO_CAL_CLK_SCALE_DEN 1000 +#define AUTO_CAL_CLK_SCALE_NUM 1024 +static int haptics_adjust_lra_period(struct haptics_chip *chip, u32 *t_lra_us) +{ + int rc; + u8 val; + + rc = haptics_read(chip, chip->cfg_addr_base, + HAP_CFG_CAL_EN_REG, &val, 1); + if (rc < 0) + return rc; + + if ((val & CAL_RC_CLK_MASK) == + (CAL_RC_CLK_AUTO_VAL << CAL_RC_CLK_SHIFT)) + *t_lra_us = div_u64((u64)(*t_lra_us) * AUTO_CAL_CLK_SCALE_NUM, + AUTO_CAL_CLK_SCALE_DEN); + + return 0; +} + static int haptics_get_closeloop_lra_period_v1( struct haptics_chip *chip) { @@ -715,7 +736,6 @@ static int haptics_get_closeloop_lra_period_v1( config->cl_t_lra_us = (tmp * step_ns) / 1000; return 0; - } #define CL_TLRA_STEP_NS 1666 @@ -765,6 +785,10 @@ static int haptics_get_closeloop_lra_period(struct haptics_chip *chip) return rc; } + rc = haptics_adjust_lra_period(chip, &chip->config.cl_t_lra_us); + if (rc < 0) + return rc; + dev_dbg(chip->dev, "OL_TLRA %u us, CL_TLRA %u us\n", chip->config.t_lra_us, chip->config.cl_t_lra_us); @@ -895,6 +919,7 @@ static int haptics_set_pattern(struct haptics_chip *chip, u8 values[SAMPLES_PER_PATTERN * 3] = { 0 }; u8 ptn_tlra_addr, ptn_cfg_addr; int i, rc, tmp; + u32 play_rate_us; if (src != PATTERN1 && src != PATTERN2) { dev_err(chip->dev, "no pattern src specified!\n"); @@ -908,8 +933,14 @@ static int haptics_set_pattern(struct haptics_chip *chip, ptn_cfg_addr = HAP_PTN_PTRN2_CFG_REG; } + /* Adjust T_LRA before programming it into HW */ + play_rate_us = pattern->play_rate_us; + rc = haptics_adjust_lra_period(chip, &play_rate_us); + if (rc < 0) + return rc; + /* Configure T_LRA for this pattern */ - tmp = pattern->play_rate_us / TLRA_STEP_US; + tmp = play_rate_us / TLRA_STEP_US; values[0] = (tmp >> 8) & TLRA_OL_MSB_MASK; values[1] = tmp & TLRA_OL_LSB_MASK; rc = haptics_write(chip, chip->ptn_addr_base, ptn_tlra_addr, @@ -1753,6 +1784,11 @@ static int haptics_config_openloop_lra_period(struct haptics_chip *chip, { u32 tmp; u8 val[2]; + int rc; + + rc = haptics_adjust_lra_period(chip, &t_lra_us); + if (rc < 0) + return rc; tmp = t_lra_us / TLRA_STEP_US; val[0] = (tmp >> 8) & TLRA_OL_MSB_MASK;