Skip to content

Commit f6aabe1

Browse files
aduggan-synadtor
authored andcommitted
Input: synaptics-rmi4 - disable the relative position IRQ in the F12 driver
This patch fixes an issue seen on HID touchpads which report finger positions using RMI4 Function 12. The issue manifests itself as spurious button presses as described in: https://www.spinics.net/lists/linux-input/msg58618.html Commit 24d28e4 ("Input: synaptics-rmi4 - convert irq distribution to irq_domain") switched the RMI4 driver to using an irq_domain to handle RMI4 function interrupts. Functions with more then one interrupt now have each interrupt mapped to their own IRQ and IRQ handler. The result of this change is that the F12 IRQ handler was now getting called twice. Once for the absolute data interrupt and once for the relative data interrupt. For HID devices, calling rmi_f12_attention() a second time causes the attn_data data pointer and size to be set incorrectly. When the touchpad button is pressed, F30 will generate an interrupt and attempt to read the F30 data from the invalid attn_data data pointer and report incorrect button events. This patch disables the F12 relative interrupt which prevents rmi_f12_attention() from being called twice. Signed-off-by: Andrew Duggan <[email protected]> Reported-by: Simon Wood <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 003f01c commit f6aabe1

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

drivers/input/rmi4/rmi_f12.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ struct f12_data {
5555

5656
const struct rmi_register_desc_item *data15;
5757
u16 data15_offset;
58+
59+
unsigned long *abs_mask;
60+
unsigned long *rel_mask;
5861
};
5962

6063
static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
@@ -291,9 +294,18 @@ static int rmi_f12_write_control_regs(struct rmi_function *fn)
291294
static int rmi_f12_config(struct rmi_function *fn)
292295
{
293296
struct rmi_driver *drv = fn->rmi_dev->driver;
297+
struct f12_data *f12 = dev_get_drvdata(&fn->dev);
298+
struct rmi_2d_sensor *sensor;
294299
int ret;
295300

296-
drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
301+
sensor = &f12->sensor;
302+
303+
if (!sensor->report_abs)
304+
drv->clear_irq_bits(fn->rmi_dev, f12->abs_mask);
305+
else
306+
drv->set_irq_bits(fn->rmi_dev, f12->abs_mask);
307+
308+
drv->clear_irq_bits(fn->rmi_dev, f12->rel_mask);
297309

298310
ret = rmi_f12_write_control_regs(fn);
299311
if (ret)
@@ -315,9 +327,12 @@ static int rmi_f12_probe(struct rmi_function *fn)
315327
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
316328
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
317329
u16 data_offset = 0;
330+
int mask_size;
318331

319332
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "%s\n", __func__);
320333

334+
mask_size = BITS_TO_LONGS(drvdata->irq_count) * sizeof(unsigned long);
335+
321336
ret = rmi_read(fn->rmi_dev, query_addr, &buf);
322337
if (ret < 0) {
323338
dev_err(&fn->dev, "Failed to read general info register: %d\n",
@@ -332,10 +347,19 @@ static int rmi_f12_probe(struct rmi_function *fn)
332347
return -ENODEV;
333348
}
334349

335-
f12 = devm_kzalloc(&fn->dev, sizeof(struct f12_data), GFP_KERNEL);
350+
f12 = devm_kzalloc(&fn->dev, sizeof(struct f12_data) + mask_size * 2,
351+
GFP_KERNEL);
336352
if (!f12)
337353
return -ENOMEM;
338354

355+
f12->abs_mask = (unsigned long *)((char *)f12
356+
+ sizeof(struct f12_data));
357+
f12->rel_mask = (unsigned long *)((char *)f12
358+
+ sizeof(struct f12_data) + mask_size);
359+
360+
set_bit(fn->irq_pos, f12->abs_mask);
361+
set_bit(fn->irq_pos + 1, f12->rel_mask);
362+
339363
f12->has_dribble = !!(buf & BIT(3));
340364

341365
if (fn->dev.of_node) {

0 commit comments

Comments
 (0)