mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 11:37:06 +02:00
input: misc: qcom-hv-haptics: Add support for V2 HW module
HV-haptics module with V2 revision supports 640 bytes FIFO memory and each byte contains a FIFO sample. There are 4 adjacent SPMI registers which can be used for filling 4 FIFO samples together by using SPMI burst writes and also a single register for filling FIFO samples while the samples are less than 4. Also update the logic of writing FIFO samples: Check the available FIFO memory first and then write FIFO with samples no more than the available FIFO memory space. With this new logic, it's not necessory to read FIFO_READY_STS register before writing FIFO samples and this helps on reducing FIFO writing latency. Change-Id: If65a81327dfd2c6af0d58055c0ae93ad6c1dcba0 Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
This commit is contained in:
parent
8f9d499001
commit
08e6fb57aa
|
|
@ -27,10 +27,16 @@
|
|||
/* STATUS_DATA_MSB definitions while MOD_STATUS_SEL is 0 */
|
||||
#define AUTO_RES_CAL_DONE_BIT BIT(5)
|
||||
#define CAL_TLRA_CL_STS_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 */
|
||||
#define FIFO_REAL_TIME_FILL_STATUS_MSB_MASK_V2 GENMASK(1, 0)
|
||||
|
||||
#define HAP_CFG_STATUS_DATA_LSB_REG 0x0A
|
||||
/* STATUS_DATA_MSB definitions while MOD_STATUS_SEL is 0 */
|
||||
/* STATUS_DATA_MSB definition while MOD_STATUS_SEL is 0 */
|
||||
#define CAL_TLRA_CL_STS_LSB_MASK GENMASK(7, 0)
|
||||
/* STATUS_DATA_LSB definition in V2 while MOD_STATUS_SEL is 5 */
|
||||
#define FIFO_REAL_TIME_FILL_STATUS_LSB_MASK_V2 GENMASK(7, 0)
|
||||
|
||||
#define HAP_CFG_FAULT_STATUS_REG 0x0C
|
||||
#define SC_FLAG_BIT BIT(2)
|
||||
|
|
@ -109,6 +115,17 @@
|
|||
#define VMAX_HDRM_MASK GENMASK(6, 0)
|
||||
#define VMAX_HDRM_STEP_MV 50
|
||||
|
||||
#define HAP_CFG_MOD_STATUS_SEL_REG 0x70
|
||||
#define MOD_STATUS_SEL_FIFO_FILL_STATUS_VAL 5
|
||||
|
||||
#define HAP_CFG_MOD_STATUS_XT_V2_REG 0x71
|
||||
#define MOD_STATUS_XT_V2_FIFO_FILL_STATUS_VAL 0x80
|
||||
|
||||
/* version register definitions for HAPTICS_PATTERN module */
|
||||
#define HAP_PTN_REVISION2_REG 0x01
|
||||
#define HAP_PTN_V1 0x1
|
||||
#define HAP_PTN_V2 0x2
|
||||
|
||||
/* status register definition for HAPTICS_PATTERN module */
|
||||
#define HAP_PTN_FIFO_READY_STS_REG 0x08
|
||||
#define FIFO_READY_BIT BIT(0)
|
||||
|
|
@ -116,19 +133,32 @@
|
|||
#define HAP_PTN_NUM_PAT_REG 0x09
|
||||
|
||||
/* config register definition for HAPTICS_PATTERN module */
|
||||
#define HAP_PTN_FIFO_DIN_MSB_REG 0x20
|
||||
#define HAP_PTN_FIFO_DIN_MSB_BIT BIT(0)
|
||||
#define HAP_PTN_FIFO_DIN_LSB_REG 0x21
|
||||
#define HAP_PTN_FIFO_DIN_LSB_MASK GENMASK(7, 0)
|
||||
/* FIFO configuration registers in V1 chip */
|
||||
#define HAP_PTN_V1_FIFO_DIN_MSB_REG 0x20
|
||||
#define HAP_PTN_V1_FIFO_DIN_MSB_BIT BIT(0)
|
||||
#define HAP_PTN_V1_FIFO_DIN_LSB_REG 0x21
|
||||
#define HAP_PTN_V1_FIFO_DIN_LSB_MASK GENMASK(7, 0)
|
||||
|
||||
#define HAP_PTN_FIFO_PLAY_RATE_REG 0x22
|
||||
#define HAP_PTN_V1_FIFO_PLAY_RATE_REG 0x22
|
||||
#define FIFO_PLAY_RATE_MASK GENMASK(3, 0)
|
||||
|
||||
#define HAP_PTN_FIFO_EMPTY_CFG_REG 0x23
|
||||
#define HAP_PTN_V1_FIFO_EMPTY_CFG_REG 0x23
|
||||
#define EMPTY_THRESH_MASK GENMASK(3, 0)
|
||||
#define HAP_PTN_V1_FIFO_THRESH_LSB 4
|
||||
|
||||
#define HAP_PTN_FIFO_DEPTH_CFG_REG 0x24
|
||||
#define HAP_PTN_V1_FIFO_DEPTH_CFG_REG 0x24
|
||||
|
||||
/* FIFO configuration registers in V2 chip */
|
||||
#define HAP_PTN_V2_FIFO_DIN_0_REG 0x20
|
||||
#define HAP_PTN_V2_FIFO_DIN_NUM 4
|
||||
|
||||
#define HAP_PTN_V2_FIFO_PLAY_RATE_REG 0x24
|
||||
#define HAP_PTN_V2_FIFO_EMPTY_CFG_REG 0x2A
|
||||
#define HAP_PTN_V2_FIFO_THRESH_LSB 40
|
||||
#define HAP_PTN_V2_FIFO_DEPTH_CFG_REG 0x2B
|
||||
#define HAP_PTN_V2_FIFO_DIN_1B_REG 0x2C
|
||||
|
||||
/* shared registers between V1 and V2 chips */
|
||||
#define HAP_PTN_DIRECT_PLAY_REG 0x26
|
||||
|
||||
#define HAP_PTN_AUTORES_CAL_CFG_REG 0x28
|
||||
|
|
@ -152,10 +182,8 @@
|
|||
/* constant parameters */
|
||||
#define SAMPLES_PER_PATTERN 8
|
||||
#define BRAKE_SAMPLE_COUNT 8
|
||||
#define MAX_FIFO_SAMPLES 104
|
||||
#define DEFAULT_ERM_PLAY_RATE_US 5000
|
||||
#define MAX_EFFECT_COUNT 64
|
||||
#define FIFO_EMPTY_THRESHOLD 48
|
||||
#define FIFO_READY_TIMEOUT_MS 1000
|
||||
#define CHAR_PER_PATTERN_S 48
|
||||
#define CHAR_PER_SAMPLE 8
|
||||
|
|
@ -163,6 +191,11 @@
|
|||
#define CHAR_BRAKE_MODE 24
|
||||
#define HW_BRAKE_CYCLES 5
|
||||
|
||||
#define MAX_FIFO_SAMPLES(chip) \
|
||||
((chip)->ptn_revision == HAP_PTN_V1 ? 104 : 640)
|
||||
#define FIFO_EMPTY_THRESHOLD(chip) \
|
||||
((chip)->ptn_revision == HAP_PTN_V1 ? 48 : 280)
|
||||
|
||||
enum drv_sig_shape {
|
||||
WF_SQUARE,
|
||||
WF_SINE,
|
||||
|
|
@ -267,7 +300,7 @@ struct pattern_cfg {
|
|||
};
|
||||
|
||||
struct fifo_cfg {
|
||||
u16 *samples;
|
||||
u8 *samples;
|
||||
u32 num_s;
|
||||
enum s_period period_per_s;
|
||||
u32 play_length_us;
|
||||
|
|
@ -332,6 +365,7 @@ struct haptics_chip {
|
|||
u32 effects_count;
|
||||
u32 cfg_addr_base;
|
||||
u32 ptn_addr_base;
|
||||
u8 ptn_revision;
|
||||
bool fifo_empty_irq_en;
|
||||
bool swr_slave_enabled;
|
||||
};
|
||||
|
|
@ -726,41 +760,30 @@ static int haptics_set_pattern(struct haptics_chip *chip,
|
|||
|
||||
}
|
||||
|
||||
static int haptics_update_fifo_sample(struct haptics_chip *chip, u16 sample)
|
||||
static int haptics_update_fifo_sample_v1(struct haptics_chip *chip, u8 sample)
|
||||
{
|
||||
int rc = 0;
|
||||
u8 val;
|
||||
bool ready;
|
||||
|
||||
rc = haptics_read(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_FIFO_READY_STS_REG, &val, 1);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "read FIFO_READY_STS failed, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ready = !!(val & FIFO_READY_BIT);
|
||||
/* sleep no more than 10us if FIFO memory is not ready */
|
||||
if (!ready)
|
||||
usleep_range(1, 10);
|
||||
|
||||
/*
|
||||
* Fill FIFO_DIN registers to update FIFO memory,
|
||||
* need to fill LSB first then MSB
|
||||
* need to fill LSB first then MSB.
|
||||
* The FIFO memory width in V1 chip is 9-bit so shift
|
||||
* 1 bit to left on the 8-bit FIFO sample to achieve a
|
||||
* 9-bit data and fill it into the FIFO_DIN registers.
|
||||
*/
|
||||
val = sample & HAP_PTN_FIFO_DIN_LSB_MASK;
|
||||
val = (sample << 1) & HAP_PTN_V1_FIFO_DIN_LSB_MASK;
|
||||
rc = haptics_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_FIFO_DIN_LSB_REG, &val, 1);
|
||||
HAP_PTN_V1_FIFO_DIN_LSB_REG, &val, 1);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "write FIFO LSB failed, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
val = (sample >> 8) & HAP_PTN_FIFO_DIN_MSB_BIT;
|
||||
val = (sample >> 7) & HAP_PTN_V1_FIFO_DIN_MSB_BIT;
|
||||
rc = haptics_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_FIFO_DIN_MSB_REG, &val, 1);
|
||||
HAP_PTN_V1_FIFO_DIN_MSB_REG, &val, 1);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "write FIFO MSB failed, rc=%d\n",
|
||||
rc);
|
||||
|
|
@ -770,11 +793,127 @@ static int haptics_update_fifo_sample(struct haptics_chip *chip, u16 sample)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int haptics_update_fifo_sample_v2(struct haptics_chip *chip,
|
||||
u8 *samples, u32 num)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
if (num > HAP_PTN_V2_FIFO_DIN_NUM)
|
||||
return -EINVAL;
|
||||
|
||||
if (num == HAP_PTN_V2_FIFO_DIN_NUM) {
|
||||
rc = haptics_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_V2_FIFO_DIN_0_REG, samples, num);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "bulk write FIFO_DIN failed, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
} else if (num < HAP_PTN_V2_FIFO_DIN_NUM) {
|
||||
for (i = 0; i < num; i++) {
|
||||
rc = haptics_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_V2_FIFO_DIN_1B_REG,
|
||||
(samples + i), 1);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "write FIFO_DIN_1B failed, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int haptics_get_available_fifo_memory(struct haptics_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
u8 val[2];
|
||||
u32 fill, available;
|
||||
|
||||
val[0] = MOD_STATUS_SEL_FIFO_FILL_STATUS_VAL;
|
||||
if (chip->ptn_revision == HAP_PTN_V1) {
|
||||
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, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
fill = val[0] & FIFO_REAL_TIME_FILL_STATUS_MASK_V1;
|
||||
} else {
|
||||
val[1] = MOD_STATUS_XT_V2_FIFO_FILL_STATUS_VAL;
|
||||
rc = haptics_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_MOD_STATUS_SEL_REG, val, 2);
|
||||
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;
|
||||
|
||||
fill = ((val[0] & FIFO_REAL_TIME_FILL_STATUS_MSB_MASK_V2)
|
||||
<< 8) | val[1];
|
||||
}
|
||||
|
||||
if (fill > MAX_FIFO_SAMPLES(chip)) {
|
||||
dev_err(chip->dev, "Filled FIFO number %d exceed the max %d\n",
|
||||
fill, MAX_FIFO_SAMPLES(chip));
|
||||
return -EINVAL;
|
||||
} else if (fill == MAX_FIFO_SAMPLES(chip)) {
|
||||
dev_err(chip->dev, "no FIFO space available\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
available = MAX_FIFO_SAMPLES(chip) - fill;
|
||||
dev_dbg(chip->dev, "Available FIFO memory: %d bytes\n", available);
|
||||
return available;
|
||||
}
|
||||
|
||||
static int haptics_update_fifo_samples(struct haptics_chip *chip,
|
||||
u8 *samples, u32 length)
|
||||
{
|
||||
int rc, count, i;
|
||||
|
||||
if (chip->ptn_revision == HAP_PTN_V1) {
|
||||
for (i = 0; i < length; i++) {
|
||||
rc = haptics_update_fifo_sample_v1(chip, samples[i]);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
count = 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);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
||||
{
|
||||
struct fifo_play_status *status = &chip->play.fifo_status;
|
||||
u32 num, fifo_thresh;
|
||||
int rc, i;
|
||||
int rc, thresh_per_bit, available;
|
||||
u8 reg;
|
||||
|
||||
if (atomic_read(&status->is_busy) == 1) {
|
||||
dev_err(chip->dev, "FIFO is busy\n");
|
||||
|
|
@ -782,9 +921,10 @@ static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
|||
}
|
||||
|
||||
/* Configure FIFO play rate */
|
||||
reg = (chip->ptn_revision == HAP_PTN_V1) ?
|
||||
HAP_PTN_V1_FIFO_PLAY_RATE_REG : HAP_PTN_V2_FIFO_PLAY_RATE_REG;
|
||||
rc = haptics_masked_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_FIFO_PLAY_RATE_REG,
|
||||
FIFO_PLAY_RATE_MASK, fifo->period_per_s);
|
||||
reg, FIFO_PLAY_RATE_MASK, fifo->period_per_s);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
|
@ -793,18 +933,19 @@ static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
|||
|
||||
/*
|
||||
* Write the 1st set of the data into FIFO if there are
|
||||
* more than 104 samples, the rest will be written if
|
||||
* any FIFO memory is available after playing.
|
||||
* more than MAX_FIFO_SAMPLES samples, the rest will be
|
||||
* written if any FIFO memory is available after playing.
|
||||
*/
|
||||
if (fifo->num_s > MAX_FIFO_SAMPLES)
|
||||
num = MAX_FIFO_SAMPLES;
|
||||
else
|
||||
num = fifo->num_s;
|
||||
num = min_t(u32, fifo->num_s, MAX_FIFO_SAMPLES(chip));
|
||||
available = haptics_get_available_fifo_memory(chip);
|
||||
if (available < 0)
|
||||
return available;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
rc = haptics_update_fifo_sample(chip, fifo->samples[i]);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
num = min_t(u32, available, 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);
|
||||
return rc;
|
||||
}
|
||||
|
||||
atomic_set(&status->is_busy, 1);
|
||||
|
|
@ -814,7 +955,7 @@ static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
|||
atomic_set(&status->written_done, 1);
|
||||
} else {
|
||||
reinit_completion(&status->fifo_ready);
|
||||
fifo_thresh = FIFO_EMPTY_THRESHOLD;
|
||||
fifo_thresh = FIFO_EMPTY_THRESHOLD(chip);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -822,9 +963,12 @@ static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
|||
* more data can be written into FIFO memory after
|
||||
* the IRQ is triggered.
|
||||
*/
|
||||
reg = (chip->ptn_revision == HAP_PTN_V1) ?
|
||||
HAP_PTN_V1_FIFO_EMPTY_CFG_REG : HAP_PTN_V2_FIFO_EMPTY_CFG_REG;
|
||||
thresh_per_bit = (chip->ptn_revision == HAP_PTN_V1) ?
|
||||
HAP_PTN_V1_FIFO_THRESH_LSB : HAP_PTN_V2_FIFO_THRESH_LSB;
|
||||
rc = haptics_masked_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_FIFO_EMPTY_CFG_REG, EMPTY_THRESH_MASK,
|
||||
fifo_thresh / 4);
|
||||
reg, EMPTY_THRESH_MASK, fifo_thresh / thresh_per_bit);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
|
@ -1145,11 +1289,12 @@ static void update_fifo_work(struct work_struct *work)
|
|||
struct haptics_chip, fifo_work);
|
||||
struct fifo_cfg *fifo = chip->play.effect->fifo;
|
||||
struct fifo_play_status *status = &chip->play.fifo_status;
|
||||
u32 num, samples_written, samples_left;
|
||||
int rc, i;
|
||||
u32 samples_written, samples_left;
|
||||
u8 *samples;
|
||||
u8 reg;
|
||||
int rc, num;
|
||||
|
||||
samples_written = status->samples_written;
|
||||
num = MAX_FIFO_SAMPLES - FIFO_EMPTY_THRESHOLD;
|
||||
samples_left = fifo->num_s - samples_written;
|
||||
|
||||
while (samples_left > 0) {
|
||||
|
|
@ -1161,17 +1306,23 @@ static void update_fifo_work(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
num = haptics_get_available_fifo_memory(chip);
|
||||
if (num < 0)
|
||||
return;
|
||||
|
||||
if (samples_left <= num)
|
||||
num = samples_left;
|
||||
else
|
||||
reinit_completion(&status->fifo_ready);
|
||||
|
||||
/* Write more pattern data into FIFO memory */
|
||||
for (i = 0; i < num; i++) {
|
||||
rc = haptics_update_fifo_sample(chip,
|
||||
fifo->samples[samples_written + i]);
|
||||
if (rc < 0)
|
||||
return;
|
||||
samples = fifo->samples + samples_written;
|
||||
|
||||
/* Write more pattern data into FIFO memory. */
|
||||
rc = haptics_update_fifo_samples(chip, samples, num);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Update FIFO samples failed in fifo_work, rc=%d\n",
|
||||
rc);
|
||||
return;
|
||||
}
|
||||
|
||||
samples_written += num;
|
||||
|
|
@ -1187,9 +1338,10 @@ static void update_fifo_work(struct work_struct *work)
|
|||
*/
|
||||
dev_dbg(chip->dev, "FIFO programmed done\n");
|
||||
atomic_set(&chip->play.fifo_status.written_done, 1);
|
||||
reg = (chip->ptn_revision == HAP_PTN_V1) ?
|
||||
HAP_PTN_V1_FIFO_EMPTY_CFG_REG : HAP_PTN_V2_FIFO_EMPTY_CFG_REG;
|
||||
rc = haptics_masked_write(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_FIFO_EMPTY_CFG_REG,
|
||||
EMPTY_THRESH_MASK, 0);
|
||||
reg, EMPTY_THRESH_MASK, 0);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "set FIFO empty threshold to 0 failed, rc=%d\n",
|
||||
rc);
|
||||
|
|
@ -1435,7 +1587,7 @@ static ssize_t fifo_s_dbgfs_write(struct file *fp,
|
|||
char *kbuf, *token;
|
||||
int rc, i = 0;
|
||||
u32 val;
|
||||
u16 *samples;
|
||||
u8 *samples;
|
||||
|
||||
kbuf = kzalloc(count + 1, GFP_KERNEL);
|
||||
if (!kbuf)
|
||||
|
|
@ -1450,7 +1602,7 @@ static ssize_t fifo_s_dbgfs_write(struct file *fp,
|
|||
kbuf[count] = '\0';
|
||||
*ppos += count;
|
||||
|
||||
samples = kcalloc(fifo->num_s, sizeof(u16), GFP_KERNEL);
|
||||
samples = kcalloc(fifo->num_s, sizeof(*samples), GFP_KERNEL);
|
||||
if (!samples) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
|
|
@ -1463,16 +1615,16 @@ static ssize_t fifo_s_dbgfs_write(struct file *fp,
|
|||
goto exit2;
|
||||
}
|
||||
|
||||
if (val > 0x1ff)
|
||||
val = 0x1ff;
|
||||
if (val > 0xff)
|
||||
val = 0xff;
|
||||
|
||||
samples[i++] = (u16)val;
|
||||
samples[i++] = val;
|
||||
/* only support fifo pattern no longer than before */
|
||||
if (i >= fifo->num_s)
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(fifo->samples, samples, sizeof(*fifo->samples) * fifo->num_s);
|
||||
memcpy(fifo->samples, samples, fifo->num_s);
|
||||
fifo->play_length_us = get_fifo_play_length_us(fifo, effect->t_lra_us);
|
||||
if (fifo->play_length_us == -EINVAL) {
|
||||
pr_err("get fifo play length failed\n");
|
||||
|
|
@ -1918,7 +2070,7 @@ static int haptics_parse_per_effect_dt(struct haptics_chip *chip,
|
|||
}
|
||||
}
|
||||
|
||||
tmp = of_property_count_u16_elems(node, "qcom,wf-fifo-data");
|
||||
tmp = of_property_count_u8_elems(node, "qcom,wf-fifo-data");
|
||||
if (tmp > 0) {
|
||||
effect->fifo = devm_kzalloc(chip->dev,
|
||||
sizeof(*effect->fifo), GFP_KERNEL);
|
||||
|
|
@ -1926,11 +2078,11 @@ static int haptics_parse_per_effect_dt(struct haptics_chip *chip,
|
|||
return -ENOMEM;
|
||||
|
||||
effect->fifo->samples = devm_kcalloc(chip->dev,
|
||||
tmp, sizeof(u16), GFP_KERNEL);
|
||||
tmp, sizeof(u8), GFP_KERNEL);
|
||||
if (!effect->fifo->samples)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = of_property_read_u16_array(node, "qcom,wf-fifo-data",
|
||||
rc = of_property_read_u8_array(node, "qcom,wf-fifo-data",
|
||||
effect->fifo->samples, tmp);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Read wf-fifo-data failed, rc=%d\n",
|
||||
|
|
@ -2152,6 +2304,22 @@ static int haptics_parse_lra_dt(struct haptics_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int haptics_get_revision(struct haptics_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
u8 val;
|
||||
|
||||
rc = haptics_read(chip, chip->ptn_addr_base,
|
||||
HAP_PTN_REVISION2_REG, &val, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
chip->ptn_revision = val;
|
||||
dev_dbg(chip->dev, "haptics ptn module revision: %#x\n",
|
||||
chip->ptn_revision);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int haptics_parse_dt(struct haptics_chip *chip)
|
||||
{
|
||||
struct haptics_hw_config *config = &chip->config;
|
||||
|
|
@ -2176,6 +2344,12 @@ static int haptics_parse_dt(struct haptics_chip *chip)
|
|||
}
|
||||
|
||||
chip->ptn_addr_base = be32_to_cpu(*addr);
|
||||
rc = haptics_get_revision(chip);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Get revision failed, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->fifo_empty_irq = platform_get_irq_byname(pdev, "fifo-empty");
|
||||
if (!chip->fifo_empty_irq) {
|
||||
dev_err(chip->dev, "Get fifo-empty IRQ failed\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user