mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
input: qcom-hv-haptics: discard 1-byte FIFO write for HAP_PTN_V2
For haptics module with HAP_PTN_V2 revision, the HW would only read 1 valid byte in every 4 bytes if the 1-byte FIFO write clashes with the FIFO read operation. To avoid this, don't use 1-byte write but just pad zeros at end of the pattern to keep the samples 4-byte aligned and always use 4-byte write for FIFO programming. Change-Id: I3ebde0fe7378c0dcffb5c51e15e6ffaae5af3e29 Signed-off-by: Fenglin Wu <quic_fenglinw@quicinc.com>
This commit is contained in:
parent
b3a8a1b143
commit
c38c0c90d7
1 changed files with 35 additions and 21 deletions
|
|
@ -1818,13 +1818,17 @@ static int haptics_set_manual_rc_clk_cal(struct haptics_chip *chip)
|
|||
static int haptics_update_fifo_samples(struct haptics_chip *chip,
|
||||
u8 *samples, u32 length)
|
||||
{
|
||||
int rc, count, i;
|
||||
int rc = 0, count, i, remain;
|
||||
u8 tmp[HAP_PTN_V2_FIFO_DIN_NUM] = {0};
|
||||
|
||||
if (samples == NULL) {
|
||||
dev_err(chip->dev, "no FIFO samples available\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!length)
|
||||
return 0;
|
||||
|
||||
if (chip->ptn_revision == HAP_PTN_V1) {
|
||||
for (i = 0; i < length; i++) {
|
||||
rc = haptics_update_fifo_sample_v1(chip, samples[i]);
|
||||
|
|
@ -1833,6 +1837,7 @@ static int haptics_update_fifo_samples(struct haptics_chip *chip,
|
|||
}
|
||||
} else {
|
||||
count = length / HAP_PTN_V2_FIFO_DIN_NUM;
|
||||
remain = length % HAP_PTN_V2_FIFO_DIN_NUM;
|
||||
for (i = 0; i < count; i++) {
|
||||
rc = haptics_update_fifo_sample_v2(chip,
|
||||
samples, HAP_PTN_V2_FIFO_DIN_NUM);
|
||||
|
|
@ -1842,16 +1847,26 @@ static int haptics_update_fifo_samples(struct haptics_chip *chip,
|
|||
samples += HAP_PTN_V2_FIFO_DIN_NUM;
|
||||
}
|
||||
|
||||
if (length % HAP_PTN_V2_FIFO_DIN_NUM) {
|
||||
rc = haptics_update_fifo_sample_v2(chip,
|
||||
samples,
|
||||
length % HAP_PTN_V2_FIFO_DIN_NUM);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (remain) {
|
||||
/*
|
||||
* In HAP_PTN_V2 module, when 1-byte FIFO write clashes
|
||||
* with the HW FIFO read operation, the HW will only read
|
||||
* 1 valid byte in every 4 bytes FIFO samples. So avoid
|
||||
* this by keeping the samples 4-byte aligned and always
|
||||
* use 4-byte write for HAP_PTN_V2 module.
|
||||
*/
|
||||
if (chip->ptn_revision == HAP_PTN_V2) {
|
||||
memcpy(tmp, samples, remain);
|
||||
rc = haptics_update_fifo_sample_v2(chip,
|
||||
tmp, HAP_PTN_V2_FIFO_DIN_NUM);
|
||||
} else {
|
||||
rc = haptics_update_fifo_sample_v2(chip,
|
||||
samples, remain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int haptics_set_fifo_playrate(struct haptics_chip *chip,
|
||||
|
|
@ -1984,6 +1999,10 @@ static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
|||
return available;
|
||||
|
||||
num = min_t(u32, available, num);
|
||||
/* Keep the FIFO programming 4-byte aligned if FIFO refilling is needed */
|
||||
if ((num < fifo->num_s) && (num % HAP_PTN_V2_FIFO_DIN_NUM))
|
||||
num = round_down(num, HAP_PTN_V2_FIFO_DIN_NUM);
|
||||
|
||||
rc = haptics_update_fifo_samples(chip, fifo->samples, num);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "write FIFO samples failed, rc=%d\n", rc);
|
||||
|
|
@ -2875,23 +2894,18 @@ static irqreturn_t fifo_empty_irq_handler(int irq, void *data)
|
|||
if (num < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* With HAPTICS_PATTERN module revision 2.0 and above, if use
|
||||
* 1-byte write before 4-byte write, the hardware would insert
|
||||
* zeros in between to keep the FIFO samples 4-byte aligned, and
|
||||
* the inserted 0 values would cause HW stop driving hence spurs
|
||||
* will be seen on the haptics output. So only use 1-byte write
|
||||
* at the end of FIFO streaming.
|
||||
*/
|
||||
if (samples_left <= num)
|
||||
num = samples_left;
|
||||
else if ((chip->ptn_revision >= HAP_PTN_V2) &&
|
||||
(num % HAP_PTN_V2_FIFO_DIN_NUM))
|
||||
num -= (num % HAP_PTN_V2_FIFO_DIN_NUM);
|
||||
|
||||
samples = fifo->samples + status->samples_written;
|
||||
|
||||
/* Write more pattern data into FIFO memory. */
|
||||
/*
|
||||
* Always use 4-byte burst write in the middle of FIFO programming to
|
||||
* avoid HW padding zeros during 1-byte write which would cause the HW
|
||||
* stop driving for the unexpected padding zeros.
|
||||
*/
|
||||
if (num < samples_left)
|
||||
num = round_down(num, HAP_PTN_V2_FIFO_DIN_NUM);
|
||||
else
|
||||
num = samples_left;
|
||||
|
||||
rc = haptics_update_fifo_samples(chip, samples, num);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Update FIFO samples failed, rc=%d\n",
|
||||
|
|
|
|||
Loading…
Reference in a new issue