Skip to content

Commit

Permalink
input: touchscreen: edt-ft5x06: Suppress bogus data on startup
Browse files Browse the repository at this point in the history
commit 5171a96d17e35b7af7efbf6e9c9667f93fbd828f from
https://github.com/raspberrypi/linux.git rpi-6.6.y

When polled without the use of IRQ, FT5x06 registers may return
undefined initial data, causing unwanted touches or event spamming.
A simple way to filter this out is to suppress touches until the
TD_STATUS register changes for the first time.

Increase the delay before first polling to 300ms, to avoid
transient I2C read flakiness that seems to occur after reset.

Signed-off-by: Nick Hollinghurst <[email protected]>
Signed-off-by: Rajeshkumar Ramasamy <[email protected]>
  • Loading branch information
njhollinghurst authored and rajeshkumarwr committed Aug 9, 2024
1 parent 9d50251 commit c4647e8
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions drivers/input/touchscreen/edt-ft5x06.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
#define M06_REG_CMD(factory) ((factory) ? 0xf3 : 0xfc)
#define M06_REG_ADDR(factory, addr) ((factory) ? (addr) & 0x7f : (addr) & 0x3f)

#define RESET_DELAY_MS 300 /* reset deassert to I2C */
#define FIRST_POLL_DELAY_MS 300 /* in addition to the above */
#define POLL_INTERVAL_MS 17 /* 17ms = 60fps */

enum edt_pmode {
Expand Down Expand Up @@ -145,6 +147,7 @@ struct edt_ft5x06_ts_data {

char name[EDT_NAME_LEN];
char fw_version[EDT_NAME_LEN];
int init_td_status;

struct edt_reg_addr reg_addr;
enum edt_ver version;
Expand Down Expand Up @@ -324,6 +327,21 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
* points.
*/
num_points = min(rdbuf[2] & 0xf, tsdata->max_support_points);

/* When polling FT5x06 without IRQ: initial register contents
* could be stale or undefined; discard all readings until
* TD_STATUS changes for the first time (or num_points is 0).
*/
if (tsdata->init_td_status) {
if (tsdata->init_td_status < 0)
tsdata->init_td_status = rdbuf[2];

if (num_points && rdbuf[2] == tsdata->init_td_status)
goto out;

tsdata->init_td_status = 0;
}

if (!error && num_points)
error = regmap_bulk_read(tsdata->regmap,
tsdata->tdata_offset,
Expand Down Expand Up @@ -1300,7 +1318,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
if (tsdata->reset_gpio) {
usleep_range(5000, 6000);
gpiod_set_value_cansleep(tsdata->reset_gpio, 0);
msleep(300);
msleep(RESET_DELAY_MS);
}

input = devm_input_allocate_device(&client->dev);
Expand Down Expand Up @@ -1389,11 +1407,12 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
return error;
}
} else {
tsdata->init_td_status = -1; /* filter bogus initial data */
INIT_WORK(&tsdata->work_i2c_poll,
edt_ft5x06_ts_work_i2c_poll);
timer_setup(&tsdata->timer, edt_ft5x06_ts_irq_poll_timer, 0);
tsdata->timer.expires = jiffies +
msecs_to_jiffies(POLL_INTERVAL_MS);
tsdata->timer.expires =
jiffies + msecs_to_jiffies(FIRST_POLL_DELAY_MS);
add_timer(&tsdata->timer);
}

Expand Down

0 comments on commit c4647e8

Please sign in to comment.