Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: goodix - add support for polling mode

There are designs incorporating Goodix touch controller that do not
connect interrupt pin, for example Raspberry Pi. To support such systems
use polling mode for the input device when I2C client does not have
interrupt assigned to it.

Signed-off-by: Joseph Guo <qijian.guo@nxp.com>
Reviewed-by: Haibo Chen <haibo.chen@nxp.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20250522020418.1963422-1-qijian.guo@nxp.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Joseph Guo and committed by
Dmitry Torokhov
409fe0ce 43a8440f

+44 -6
+44 -6
drivers/input/touchscreen/goodix.c
··· 44 44 #define GOODIX_HAVE_KEY BIT(4) 45 45 #define GOODIX_BUFFER_STATUS_TIMEOUT 20 46 46 47 - #define RESOLUTION_LOC 1 48 - #define MAX_CONTACTS_LOC 5 49 - #define TRIGGER_LOC 6 47 + #define RESOLUTION_LOC 1 48 + #define MAX_CONTACTS_LOC 5 49 + #define TRIGGER_LOC 6 50 + 51 + #define GOODIX_POLL_INTERVAL_MS 17 /* 17ms = 60fps */ 50 52 51 53 /* Our special handling for GPIO accesses through ACPI is x86 specific */ 52 54 #if defined CONFIG_X86 && defined CONFIG_ACPI ··· 499 497 input_sync(ts->input_dev); 500 498 } 501 499 500 + static void goodix_ts_work_i2c_poll(struct input_dev *input) 501 + { 502 + struct goodix_ts_data *ts = input_get_drvdata(input); 503 + 504 + goodix_process_events(ts); 505 + goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0); 506 + } 507 + 502 508 /** 503 509 * goodix_ts_irq_handler - The IRQ handler 504 510 * ··· 523 513 return IRQ_HANDLED; 524 514 } 525 515 516 + static void goodix_enable_irq(struct goodix_ts_data *ts) 517 + { 518 + if (ts->client->irq) 519 + enable_irq(ts->client->irq); 520 + } 521 + 522 + static void goodix_disable_irq(struct goodix_ts_data *ts) 523 + { 524 + if (ts->client->irq) 525 + disable_irq(ts->client->irq); 526 + } 527 + 526 528 static void goodix_free_irq(struct goodix_ts_data *ts) 527 529 { 528 - devm_free_irq(&ts->client->dev, ts->client->irq, ts); 530 + if (ts->client->irq) 531 + devm_free_irq(&ts->client->dev, ts->client->irq, ts); 529 532 } 530 533 531 534 static int goodix_request_irq(struct goodix_ts_data *ts) 532 535 { 536 + if (!ts->client->irq) 537 + return 0; 538 + 533 539 return devm_request_threaded_irq(&ts->client->dev, ts->client->irq, 534 540 NULL, goodix_ts_irq_handler, 535 541 ts->irq_flags, ts->client->name, ts); ··· 1245 1219 return error; 1246 1220 } 1247 1221 1222 + input_set_drvdata(ts->input_dev, ts); 1223 + 1224 + if (!ts->client->irq) { 1225 + error = input_setup_polling(ts->input_dev, goodix_ts_work_i2c_poll); 1226 + if (error) { 1227 + dev_err(&ts->client->dev, 1228 + "could not set up polling mode, %d\n", error); 1229 + return error; 1230 + } 1231 + input_set_poll_interval(ts->input_dev, GOODIX_POLL_INTERVAL_MS); 1232 + } 1233 + 1248 1234 error = input_register_device(ts->input_dev); 1249 1235 if (error) { 1250 1236 dev_err(&ts->client->dev, ··· 1460 1422 1461 1423 /* We need gpio pins to suspend/resume */ 1462 1424 if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) { 1463 - disable_irq(client->irq); 1425 + goodix_disable_irq(ts); 1464 1426 return 0; 1465 1427 } 1466 1428 ··· 1504 1466 int error; 1505 1467 1506 1468 if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) { 1507 - enable_irq(client->irq); 1469 + goodix_enable_irq(ts); 1508 1470 return 0; 1509 1471 } 1510 1472