Input: edt-ft5x06: Poll the device if no interrupt is configured.

Not all systems have the interrupt line wired up, so switch to
polling the touchscreen off a timer if no interrupt line is
configured.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
This commit is contained in:
Dave Stevenson
2020-11-06 18:45:10 +00:00
committed by popcornmix
parent 23bc47c796
commit ca61fdaba7

View File

@@ -69,6 +69,8 @@
#define EDT_RAW_DATA_RETRIES 100 #define EDT_RAW_DATA_RETRIES 100
#define EDT_RAW_DATA_DELAY 1000 /* usec */ #define EDT_RAW_DATA_DELAY 1000 /* usec */
#define POLL_INTERVAL_MS 17 /* 17ms = 60fps */
enum edt_pmode { enum edt_pmode {
EDT_PMODE_NOT_SUPPORTED, EDT_PMODE_NOT_SUPPORTED,
EDT_PMODE_HIBERNATE, EDT_PMODE_HIBERNATE,
@@ -126,6 +128,9 @@ struct edt_ft5x06_ts_data {
struct edt_reg_addr reg_addr; struct edt_reg_addr reg_addr;
enum edt_ver version; enum edt_ver version;
struct timer_list timer;
struct work_struct work_i2c_poll;
}; };
struct edt_i2c_chip_data { struct edt_i2c_chip_data {
@@ -275,6 +280,22 @@ out:
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void edt_ft5x06_ts_irq_poll_timer(struct timer_list *t)
{
struct edt_ft5x06_ts_data *tsdata = from_timer(tsdata, t, timer);
schedule_work(&tsdata->work_i2c_poll);
mod_timer(&tsdata->timer, jiffies + msecs_to_jiffies(POLL_INTERVAL_MS));
}
static void edt_ft5x06_ts_work_i2c_poll(struct work_struct *work)
{
struct edt_ft5x06_ts_data *tsdata = container_of(work,
struct edt_ft5x06_ts_data, work_i2c_poll);
edt_ft5x06_ts_isr(0, tsdata);
}
static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
u8 addr, u8 value) u8 addr, u8 value)
{ {
@@ -1221,17 +1242,27 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
i2c_set_clientdata(client, tsdata); i2c_set_clientdata(client, tsdata);
irq_flags = irq_get_trigger_type(client->irq); if (client->irq) {
if (irq_flags == IRQF_TRIGGER_NONE) irq_flags = irq_get_trigger_type(client->irq);
irq_flags = IRQF_TRIGGER_FALLING; if (irq_flags == IRQF_TRIGGER_NONE)
irq_flags |= IRQF_ONESHOT; irq_flags = IRQF_TRIGGER_FALLING;
irq_flags |= IRQF_ONESHOT;
error = devm_request_threaded_irq(&client->dev, client->irq, error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, edt_ft5x06_ts_isr, irq_flags, NULL, edt_ft5x06_ts_isr,
client->name, tsdata); irq_flags, client->name,
if (error) { tsdata);
dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); if (error) {
return error; dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
return error;
}
} else {
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);
add_timer(&tsdata->timer);
} }
error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group); error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group);