diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 89c69e9cb1d1a..74dea38b9fad5 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -44,11 +44,11 @@ #define GOODIX_HAVE_KEY BIT(4) #define GOODIX_BUFFER_STATUS_TIMEOUT 20 -#define RESOLUTION_LOC 1 -#define MAX_CONTACTS_LOC 5 -#define TRIGGER_LOC 6 +#define RESOLUTION_LOC 1 +#define MAX_CONTACTS_LOC 5 +#define TRIGGER_LOC 6 -#define POLL_INTERVAL_MS 17 /* 17ms = 60fps */ +#define GOODIX_POLL_INTERVAL_MS 17 /* 17ms = 60fps */ /* Our special handling for GPIO accesses through ACPI is x86 specific */ #if defined CONFIG_X86 && defined CONFIG_ACPI @@ -299,6 +299,14 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) return 0; } + if (!ts->client->irq) + /* + * No point in retrying if polling, particularly as some + * versions continuously report "not ready" if there are + * no touch points. + */ + break; + usleep_range(1000, 2000); /* Poll every 1 - 2 ms */ } while (time_before(jiffies, max_timeout)); @@ -499,6 +507,14 @@ static void goodix_process_events(struct goodix_ts_data *ts) input_sync(ts->input_dev); } +static void goodix_ts_work_i2c_poll(struct input_dev *input) +{ + struct goodix_ts_data *ts = input_get_drvdata(input); + + goodix_process_events(ts); + goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0); +} + /** * goodix_ts_irq_handler - The IRQ handler * @@ -515,67 +531,32 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static void goodix_ts_irq_poll_timer(struct timer_list *t) -{ - struct goodix_ts_data *ts = from_timer(ts, t, timer); - - schedule_work(&ts->work_i2c_poll); - mod_timer(&ts->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS)); -} - -static void goodix_ts_work_i2c_poll(struct work_struct *work) -{ - struct goodix_ts_data *ts = container_of(work, - struct goodix_ts_data, work_i2c_poll); - - goodix_process_events(ts); - goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0); -} - static void goodix_enable_irq(struct goodix_ts_data *ts) { - if (ts->client->irq) { + if (ts->client->irq) enable_irq(ts->client->irq); - } else { - ts->timer.expires = jiffies + msecs_to_jiffies(POLL_INTERVAL_MS); - add_timer(&ts->timer); - } } static void goodix_disable_irq(struct goodix_ts_data *ts) { - if (ts->client->irq) { + if (ts->client->irq) disable_irq(ts->client->irq); - } else { - del_timer(&ts->timer); - cancel_work_sync(&ts->work_i2c_poll); - } } static void goodix_free_irq(struct goodix_ts_data *ts) { - if (ts->client->irq) { + if (ts->client->irq) devm_free_irq(&ts->client->dev, ts->client->irq, ts); - } else { - del_timer(&ts->timer); - cancel_work_sync(&ts->work_i2c_poll); - } } static int goodix_request_irq(struct goodix_ts_data *ts) { - if (ts->client->irq) { - return devm_request_threaded_irq(&ts->client->dev, ts->client->irq, - NULL, goodix_ts_irq_handler, - ts->irq_flags, ts->client->name, ts); - } else { - INIT_WORK(&ts->work_i2c_poll, - goodix_ts_work_i2c_poll); - timer_setup(&ts->timer, goodix_ts_irq_poll_timer, 0); - if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) - goodix_enable_irq(ts); + if (!ts->client->irq) return 0; - } + + return devm_request_threaded_irq(&ts->client->dev, ts->client->irq, + NULL, goodix_ts_irq_handler, + ts->irq_flags, ts->client->name, ts); } static int goodix_check_cfg_8(struct goodix_ts_data *ts, const u8 *cfg, int len) @@ -1194,10 +1175,7 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) return -ENOMEM; } - snprintf(ts->name, GOODIX_NAME_MAX_LEN, "%s Goodix Capacitive TouchScreen", - dev_name(&ts->client->dev)); - - ts->input_dev->name = ts->name; + ts->input_dev->name = "Goodix Capacitive TouchScreen"; ts->input_dev->phys = "input/ts"; ts->input_dev->id.bustype = BUS_I2C; ts->input_dev->id.vendor = 0x0416; @@ -1275,6 +1253,18 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) return error; } + input_set_drvdata(ts->input_dev, ts); + + if (!ts->client->irq) { + error = input_setup_polling(ts->input_dev, goodix_ts_work_i2c_poll); + if (error) { + dev_err(&ts->client->dev, + "could not set up polling mode, %d\n", error); + return error; + } + input_set_poll_interval(ts->input_dev, GOODIX_POLL_INTERVAL_MS); + } + error = input_register_device(ts->input_dev); if (error) { dev_err(&ts->client->dev, @@ -1463,11 +1453,6 @@ static void goodix_ts_remove(struct i2c_client *client) { struct goodix_ts_data *ts = i2c_get_clientdata(client); - if (!client->irq) { - del_timer(&ts->timer); - cancel_work_sync(&ts->work_i2c_poll); - } - if (ts->load_cfg_from_disk) wait_for_completion(&ts->firmware_loading_complete); } diff --git a/drivers/input/touchscreen/goodix.h b/drivers/input/touchscreen/goodix.h index 235dd5f264c52..87797cc88b324 100644 --- a/drivers/input/touchscreen/goodix.h +++ b/drivers/input/touchscreen/goodix.h @@ -57,8 +57,6 @@ #define GOODIX_CONFIG_MAX_LENGTH 240 #define GOODIX_MAX_KEYS 7 -#define GOODIX_NAME_MAX_LEN 38 - enum goodix_irq_pin_access_method { IRQ_PIN_ACCESS_NONE, IRQ_PIN_ACCESS_GPIO, @@ -93,7 +91,6 @@ struct goodix_ts_data { enum gpiod_flags gpiod_rst_flags; char id[GOODIX_ID_MAX_LEN + 1]; char cfg_name[64]; - char name[GOODIX_NAME_MAX_LEN]; u16 version; bool reset_controller_at_probe; bool load_cfg_from_disk; @@ -107,8 +104,6 @@ struct goodix_ts_data { u8 main_clk[GOODIX_MAIN_CLK_LEN]; int bak_ref_len; u8 *bak_ref; - struct timer_list timer; - struct work_struct work_i2c_poll; }; int goodix_i2c_read(struct i2c_client *client, u16 reg, u8 *buf, int len);