mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
Merge "input: qcom-hv-haptics: update LRA period calculations"
This commit is contained in:
commit
ee576fa636
1 changed files with 178 additions and 25 deletions
|
|
@ -29,7 +29,9 @@
|
|||
#define AUTO_RES_CAL_DONE_BIT BIT(5)
|
||||
#define CAL_TLRA_CL_STS_MSB_MASK GENMASK(4, 0)
|
||||
/* STATUS_DATA_MSB definition in V2 while MOD_STATUS_SEL is 3 */
|
||||
#define LAST_GOOD_TLRA_CL_MASK GENMASK(4, 0)
|
||||
#define LAST_GOOD_TLRA_CL_MSB_MASK GENMASK(4, 0)
|
||||
/* STATUS_DATA_MSB definition in V2 while MOD_STATUS_SEL is 4 */
|
||||
#define TLRA_CL_ERR_MSB_MASK GENMASK(4, 0)
|
||||
/* STATUS_DATA_MSB definition in V1 while MOD_STATUS_SEL is 5 */
|
||||
#define FIFO_REAL_TIME_FILL_STATUS_MASK_V1 GENMASK(6, 0)
|
||||
/* STATUS DATA_MSB definition in V2 while MOD_STATUS_SEL is 5 */
|
||||
|
|
@ -135,6 +137,7 @@
|
|||
#define HAP_CFG_MOD_STATUS_SEL_REG 0x70
|
||||
#define MOD_STATUS_SEL_CAL_TLRA_CL_STS_VAL 0
|
||||
#define MOD_STATUS_SEL_LAST_GOOD_TLRA_VAL 3
|
||||
#define MOD_STATUS_SEL_TLRA_CL_ERR_STS_VAL 4
|
||||
#define MOD_STATUS_SEL_FIFO_FILL_STATUS_VAL 5
|
||||
#define MOD_STATUS_SEL_BRAKE_CAL_RNAT_RCAL_VAL 6
|
||||
|
||||
|
|
@ -145,6 +148,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_DISABLED_VAL 0
|
||||
#define CAL_RC_CLK_AUTO_VAL 1
|
||||
#define CAL_RC_CLK_MANUAL_VAL 2
|
||||
|
||||
|
|
@ -430,6 +434,7 @@ struct haptics_chip {
|
|||
struct regulator_dev *swr_slave_rdev;
|
||||
struct mutex irq_lock;
|
||||
struct nvmem_cell *cl_brake_nvmem;
|
||||
struct nvmem_device *hap_cfg_nvmem;
|
||||
struct class hap_class;
|
||||
int fifo_empty_irq;
|
||||
u32 effects_count;
|
||||
|
|
@ -756,25 +761,48 @@ static int haptics_get_closeloop_lra_period_v1(
|
|||
tmp = ((val[0] & CAL_TLRA_CL_STS_MSB_MASK) << 8) | val[1];
|
||||
config->cl_t_lra_us = (tmp * step_ns) / 1000;
|
||||
|
||||
return 0;
|
||||
return haptics_adjust_lra_period(chip, &config->cl_t_lra_us);
|
||||
}
|
||||
|
||||
#define CL_TLRA_STEP_NS 1666
|
||||
#define TLRA_AUTO_RES_ERR_NO_CAL_STEP_PSEC 1667000
|
||||
#define TLRA_AUTO_RES_NO_CAL_STEP_PSEC 3333000
|
||||
#define TLRA_AUTO_RES_ERR_AUTO_CAL_STEP_PSEC 1627700
|
||||
#define TLRA_AUTO_RES_AUTO_CAL_STEP_PSEC 813850
|
||||
static int haptics_get_closeloop_lra_period_v2(
|
||||
struct haptics_chip *chip)
|
||||
{
|
||||
struct haptics_hw_config *config = &chip->config;
|
||||
u16 cal_tlra_cl_sts, tlra_cl_err_sts, tlra_ol, last_good_tlra_cl_sts;
|
||||
u8 val[2], rc_clk_cal;
|
||||
bool auto_res_done;
|
||||
u64 tmp;
|
||||
int rc;
|
||||
u8 val[2];
|
||||
u32 tmp;
|
||||
|
||||
val[0] = MOD_STATUS_XT_SEL_LAST_GOOD_TLRA_VAL;
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_MOD_STATUS_XT_V2_REG, val, 1);
|
||||
/* read RC_CLK_CAL enabling mode */
|
||||
rc = haptics_read(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_CAL_EN_REG, val, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
val[0] = MOD_STATUS_SEL_LAST_GOOD_TLRA_VAL;
|
||||
rc_clk_cal = ((val[0] & CAL_RC_CLK_MASK) >> CAL_RC_CLK_SHIFT);
|
||||
/* read auto resonance calibration result */
|
||||
val[0] = MOD_STATUS_SEL_CAL_TLRA_CL_STS_VAL;
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_MOD_STATUS_SEL_REG, val, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = haptics_read(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_STATUS_DATA_MSB_REG, val, 2);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
auto_res_done = !!(val[0] & AUTO_RES_CAL_DONE_BIT);
|
||||
cal_tlra_cl_sts =
|
||||
((val[0] & CAL_TLRA_CL_STS_MSB_MASK) << 8) | val[1];
|
||||
|
||||
/* read auto resonance calibration error status */
|
||||
val[0] = MOD_STATUS_SEL_TLRA_CL_ERR_STS_VAL;
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_MOD_STATUS_SEL_REG, val, 1);
|
||||
if (rc < 0)
|
||||
|
|
@ -784,15 +812,77 @@ static int haptics_get_closeloop_lra_period_v2(
|
|||
HAP_CFG_STATUS_DATA_MSB_REG, val, 2);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
/*
|
||||
* Calculate the closed loop T_LRA with the following equations
|
||||
* for PM8350B V2:
|
||||
* LAST_GOOD_TLRA_CL_STS[12:0] = STATUS_DATA_MSB[4:0] |
|
||||
* STATUS_DATA_LSB[7:0]
|
||||
* LAST_GOOD_TLRA_CL = LAST_GOOD_TLRA_CL_STS[12:0] * 1.666 us
|
||||
*/
|
||||
tmp = ((val[0] & LAST_GOOD_TLRA_CL_MASK) << 8) | val[1];
|
||||
config->cl_t_lra_us = (tmp * CL_TLRA_STEP_NS) / 1000;
|
||||
|
||||
tlra_cl_err_sts =
|
||||
((val[0] & TLRA_CL_ERR_MSB_MASK) << 8) | val[1];
|
||||
|
||||
dev_dbg(chip->dev, "rc_clk_cal = %u, auto_res_done = %d\n",
|
||||
rc_clk_cal, auto_res_done);
|
||||
|
||||
if (rc_clk_cal == CAL_RC_CLK_DISABLED_VAL && !auto_res_done) {
|
||||
/* TLRA_CL_ERR(us) = TLRA_CL_ERR_STS * 1.667 us */
|
||||
tmp = tlra_cl_err_sts * TLRA_AUTO_RES_ERR_NO_CAL_STEP_PSEC;
|
||||
} else if (rc_clk_cal == CAL_RC_CLK_DISABLED_VAL && auto_res_done) {
|
||||
/*
|
||||
* CAL_TLRA_CL_STS_NO_CAL = CAL_TLRA_CL_STS
|
||||
* TLRA_AUTO_RES(us) = CAL_TLRA_CL_STS_NO_CAL * 3.333 us
|
||||
*/
|
||||
tmp = cal_tlra_cl_sts * TLRA_AUTO_RES_NO_CAL_STEP_PSEC;
|
||||
} else if (rc_clk_cal == CAL_RC_CLK_AUTO_VAL && !auto_res_done) {
|
||||
/*
|
||||
* CAL_TLRA_OL = CAL_TLRA_CL_STS;
|
||||
* TLRA_CL_ERR(us) = TLRA_CL_ERR_STS *
|
||||
* (TLRA_OL / CAL_TLRA_OL) * 1.6277 us
|
||||
*/
|
||||
|
||||
/* read the TLRA_OL setting */
|
||||
rc = haptics_read(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_TLRA_OL_HIGH_REG, val, 2);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
tlra_ol = (val[0] & TLRA_OL_MSB_MASK) << 8 | val[1];
|
||||
tmp = tlra_cl_err_sts * tlra_ol;
|
||||
tmp *= TLRA_AUTO_RES_ERR_AUTO_CAL_STEP_PSEC;
|
||||
tmp = div_u64(tmp, cal_tlra_cl_sts);
|
||||
} else if (rc_clk_cal == CAL_RC_CLK_AUTO_VAL && auto_res_done) {
|
||||
/*
|
||||
* CAL_TLRA_CL_STS_W_CAL = CAL_TLRA_CL_STS;
|
||||
* TLRA_AUTO_RES(us) = LAST_GOOD_TLRA_CL_STS * 0.81385 us *
|
||||
* (LAST_GOOD_TLRA_CL_STS / CAL_TLRA_CL_STS_AUTO_CAL)
|
||||
*/
|
||||
|
||||
/* read LAST_GOOD_TLRA_CL_STS */
|
||||
val[0] = MOD_STATUS_XT_SEL_LAST_GOOD_TLRA_VAL;
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_MOD_STATUS_XT_V2_REG, val, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
val[0] = MOD_STATUS_SEL_LAST_GOOD_TLRA_VAL;
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_MOD_STATUS_SEL_REG, val, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = haptics_read(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_STATUS_DATA_MSB_REG, val, 2);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
last_good_tlra_cl_sts =
|
||||
((val[0] & LAST_GOOD_TLRA_CL_MSB_MASK) << 8) | val[1];
|
||||
|
||||
tmp = last_good_tlra_cl_sts * last_good_tlra_cl_sts;
|
||||
tmp *= TLRA_AUTO_RES_AUTO_CAL_STEP_PSEC;
|
||||
tmp = div_u64(tmp, cal_tlra_cl_sts);
|
||||
} else {
|
||||
dev_err(chip->dev, "Can't get close-loop LRA period in rc_clk_cal mode %u\n",
|
||||
rc_clk_cal);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config->cl_t_lra_us = div_u64(tmp, 1000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -807,17 +897,13 @@ static int haptics_get_closeloop_lra_period(struct haptics_chip *chip)
|
|||
rc = haptics_get_closeloop_lra_period_v2(chip);
|
||||
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "get close loop T LRA failed, rc=%d\n", rc);
|
||||
dev_err(chip->dev, "get close loop T LRA failed, rc=%d\n",
|
||||
rc);
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -892,6 +978,40 @@ static int haptics_set_direct_play(struct haptics_chip *chip, u8 amplitude)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define PBS_ARG_REG 0x42
|
||||
#define HAP_VREG_ON_VAL 0x1
|
||||
#define HAP_VREG_OFF_VAL 0x2
|
||||
#define PBS_TRIG_SET_REG 0xE5
|
||||
#define PBS_TRIG_SET_VAL 0x1
|
||||
static int haptics_boost_vreg_enable(struct haptics_chip *chip, bool en)
|
||||
{
|
||||
int rc;
|
||||
u8 val;
|
||||
|
||||
if (chip->hap_cfg_nvmem == NULL) {
|
||||
dev_dbg(chip->dev, "nvmem device for hap_cfg is not defined\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = en ? HAP_VREG_ON_VAL : HAP_VREG_OFF_VAL;
|
||||
rc = nvmem_device_write(chip->hap_cfg_nvmem,
|
||||
PBS_ARG_REG, 1, &val);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "write SDAM %#x failed, rc=%d\n",
|
||||
PBS_ARG_REG, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
val = PBS_TRIG_SET_VAL;
|
||||
rc = nvmem_device_write(chip->hap_cfg_nvmem,
|
||||
PBS_TRIG_SET_REG, 1, &val);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "Write SDAM %#x failed, rc=%d\n",
|
||||
PBS_TRIG_SET_REG, rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int haptics_enable_play(struct haptics_chip *chip, bool en)
|
||||
{
|
||||
struct haptics_play_info *play = &chip->play;
|
||||
|
|
@ -916,8 +1036,17 @@ static int haptics_enable_play(struct haptics_chip *chip, bool en)
|
|||
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_SPMI_PLAY_REG, &val, 1);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Write SPMI_PLAY failed, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (play->pattern_src == FIFO) {
|
||||
rc = haptics_boost_vreg_enable(chip, en);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "Notify vreg %s failed, rc=%d\n",
|
||||
en ? "enabling" : "disabling", rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1874,6 +2003,7 @@ static int haptics_hw_init(struct haptics_chip *chip)
|
|||
struct haptics_effect *effect;
|
||||
int rc = 0, i;
|
||||
u8 val[2];
|
||||
u32 t_lra_us;
|
||||
|
||||
/* Store CL brake settings */
|
||||
rc = haptics_store_cl_brake_settings(chip);
|
||||
|
|
@ -1918,12 +2048,23 @@ static int haptics_hw_init(struct haptics_chip *chip)
|
|||
if (config->is_erm)
|
||||
return 0;
|
||||
|
||||
/* set AUTO_mode RC CLK calibration by default */
|
||||
val[0] = CAL_RC_CLK_AUTO_VAL << CAL_RC_CLK_SHIFT;
|
||||
rc = haptics_masked_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_CAL_EN_REG, CAL_RC_CLK_MASK, val[0]);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = haptics_get_closeloop_lra_period(chip);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Config T_LRA */
|
||||
rc = haptics_config_openloop_lra_period(chip, chip->config.cl_t_lra_us);
|
||||
t_lra_us = chip->config.t_lra_us;
|
||||
if (chip->config.cl_t_lra_us != 0)
|
||||
t_lra_us = chip->config.cl_t_lra_us;
|
||||
|
||||
rc = haptics_config_openloop_lra_period(chip, t_lra_us);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
|
@ -3069,6 +3210,18 @@ static int haptics_parse_dt(struct haptics_chip *chip)
|
|||
}
|
||||
}
|
||||
|
||||
if (of_find_property(node, "nvmem", NULL)) {
|
||||
chip->hap_cfg_nvmem =
|
||||
devm_nvmem_device_get(chip->dev, "hap_cfg_sdam");
|
||||
if (IS_ERR(chip->hap_cfg_nvmem)) {
|
||||
rc = PTR_ERR(chip->hap_cfg_nvmem);
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dev_err(chip->dev, "Failed to get nvmem device, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
addr = of_get_address(node, 0, NULL, NULL);
|
||||
if (!addr) {
|
||||
dev_err(chip->dev, "Read HAPTICS_CFG address failed\n");
|
||||
|
|
|
|||
Loading…
Reference in a new issue