Skip to content

Commit 0bf2d9a

Browse files
Joseph-Guo-nxp6by9
authored andcommitted
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>
1 parent 799567e commit 0bf2d9a

1 file changed

Lines changed: 44 additions & 6 deletions

File tree

drivers/input/touchscreen/goodix.c

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@
4444
#define GOODIX_HAVE_KEY BIT(4)
4545
#define GOODIX_BUFFER_STATUS_TIMEOUT 20
4646

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 */
5052

5153
/* Our special handling for GPIO accesses through ACPI is x86 specific */
5254
#if defined CONFIG_X86 && defined CONFIG_ACPI
@@ -497,6 +499,14 @@ static void goodix_process_events(struct goodix_ts_data *ts)
497499
input_sync(ts->input_dev);
498500
}
499501

502+
static void goodix_ts_work_i2c_poll(struct input_dev *input)
503+
{
504+
struct goodix_ts_data *ts = input_get_drvdata(input);
505+
506+
goodix_process_events(ts);
507+
goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0);
508+
}
509+
500510
/**
501511
* goodix_ts_irq_handler - The IRQ handler
502512
*
@@ -513,13 +523,29 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
513523
return IRQ_HANDLED;
514524
}
515525

526+
static void goodix_enable_irq(struct goodix_ts_data *ts)
527+
{
528+
if (ts->client->irq)
529+
enable_irq(ts->client->irq);
530+
}
531+
532+
static void goodix_disable_irq(struct goodix_ts_data *ts)
533+
{
534+
if (ts->client->irq)
535+
disable_irq(ts->client->irq);
536+
}
537+
516538
static void goodix_free_irq(struct goodix_ts_data *ts)
517539
{
518-
devm_free_irq(&ts->client->dev, ts->client->irq, ts);
540+
if (ts->client->irq)
541+
devm_free_irq(&ts->client->dev, ts->client->irq, ts);
519542
}
520543

521544
static int goodix_request_irq(struct goodix_ts_data *ts)
522545
{
546+
if (!ts->client->irq)
547+
return 0;
548+
523549
return devm_request_threaded_irq(&ts->client->dev, ts->client->irq,
524550
NULL, goodix_ts_irq_handler,
525551
ts->irq_flags, ts->client->name, ts);
@@ -1219,6 +1245,18 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
12191245
return error;
12201246
}
12211247

1248+
input_set_drvdata(ts->input_dev, ts);
1249+
1250+
if (!ts->client->irq) {
1251+
error = input_setup_polling(ts->input_dev, goodix_ts_work_i2c_poll);
1252+
if (error) {
1253+
dev_err(&ts->client->dev,
1254+
"could not set up polling mode, %d\n", error);
1255+
return error;
1256+
}
1257+
input_set_poll_interval(ts->input_dev, GOODIX_POLL_INTERVAL_MS);
1258+
}
1259+
12221260
error = input_register_device(ts->input_dev);
12231261
if (error) {
12241262
dev_err(&ts->client->dev,
@@ -1422,7 +1460,7 @@ static int goodix_suspend(struct device *dev)
14221460

14231461
/* We need gpio pins to suspend/resume */
14241462
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
1425-
disable_irq(client->irq);
1463+
goodix_disable_irq(ts);
14261464
return 0;
14271465
}
14281466

@@ -1466,7 +1504,7 @@ static int goodix_resume(struct device *dev)
14661504
int error;
14671505

14681506
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
1469-
enable_irq(client->irq);
1507+
goodix_enable_irq(ts);
14701508
return 0;
14711509
}
14721510

0 commit comments

Comments
 (0)