Skip to content

Commit a007721

Browse files
Marek Vasutdtor
authored andcommitted
Input: ili210x - add support for polling mode
There are designs incorporating Ilitek ILI2xxx touch controller that do not connect interrupt pin, for example Waveshare 13.3" DSI display. To support such systems use polling mode for the input device when I2C client does not have interrupt assigned to it. Factor out ili210x_firmware_update_noirq() to allow conditional scoped guard around this code. The scoped guard has to be applied only in case the IRQ line is connected, and not applied otherwise. Reviewed-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org> Link: https://patch.msgid.link/20260121230736.114623-2-marek.vasut+renesas@mailbox.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 87ac7cf commit a007721

1 file changed

Lines changed: 55 additions & 20 deletions

File tree

drivers/input/touchscreen/ili210x.c

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,8 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
327327
return contact;
328328
}
329329

330-
static irqreturn_t ili210x_irq(int irq, void *irq_data)
330+
static void ili210x_process_events(struct ili210x *priv)
331331
{
332-
struct ili210x *priv = irq_data;
333332
struct i2c_client *client = priv->client;
334333
const struct ili2xxx_chip *chip = priv->chip;
335334
u8 touchdata[ILI210X_DATA_SIZE] = { 0 };
@@ -356,8 +355,22 @@ static irqreturn_t ili210x_irq(int irq, void *irq_data)
356355
usleep_range(time_delta, time_delta + 1000);
357356
}
358357
} while (!priv->stop && keep_polling);
358+
}
359+
360+
static irqreturn_t ili210x_irq(int irq, void *irq_data)
361+
{
362+
struct ili210x *priv = irq_data;
363+
364+
ili210x_process_events(priv);
359365

360366
return IRQ_HANDLED;
367+
};
368+
369+
static void ili210x_work_i2c_poll(struct input_dev *input)
370+
{
371+
struct ili210x *priv = input_get_drvdata(input);
372+
373+
ili210x_process_events(priv);
361374
}
362375

363376
static int ili251x_firmware_update_resolution(struct device *dev)
@@ -829,12 +842,32 @@ static int ili210x_do_firmware_update(struct ili210x *priv,
829842
return 0;
830843
}
831844

845+
static ssize_t ili210x_firmware_update(struct device *dev, const u8 *fwbuf,
846+
u16 ac_end, u16 df_end)
847+
{
848+
struct i2c_client *client = to_i2c_client(dev);
849+
struct ili210x *priv = i2c_get_clientdata(client);
850+
const char *fwname = ILI251X_FW_FILENAME;
851+
int error;
852+
853+
dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
854+
855+
ili210x_hardware_reset(priv->reset_gpio);
856+
857+
error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);
858+
859+
ili210x_hardware_reset(priv->reset_gpio);
860+
861+
dev_dbg(dev, "Firmware update ended, error=%i\n", error);
862+
863+
return error;
864+
}
865+
832866
static ssize_t ili210x_firmware_update_store(struct device *dev,
833867
struct device_attribute *attr,
834868
const char *buf, size_t count)
835869
{
836870
struct i2c_client *client = to_i2c_client(dev);
837-
struct ili210x *priv = i2c_get_clientdata(client);
838871
const char *fwname = ILI251X_FW_FILENAME;
839872
u16 ac_end, df_end;
840873
int error;
@@ -860,16 +893,11 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
860893
* the touch controller to disable the IRQs during update, so we have
861894
* to do it this way here.
862895
*/
863-
scoped_guard(disable_irq, &client->irq) {
864-
dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
865-
866-
ili210x_hardware_reset(priv->reset_gpio);
867-
868-
error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);
869-
870-
ili210x_hardware_reset(priv->reset_gpio);
871-
872-
dev_dbg(dev, "Firmware update ended, error=%i\n", error);
896+
if (client->irq > 0) {
897+
guard(disable_irq)(&client->irq);
898+
error = ili210x_firmware_update(dev, fwbuf, ac_end, df_end);
899+
} else {
900+
error = ili210x_firmware_update(dev, fwbuf, ac_end, df_end);
873901
}
874902

875903
return error ?: count;
@@ -945,9 +973,6 @@ static int ili210x_i2c_probe(struct i2c_client *client)
945973
if (!chip)
946974
return dev_err_probe(&client->dev, -ENODEV, "unknown device model\n");
947975

948-
if (client->irq <= 0)
949-
return dev_err_probe(dev, -EINVAL, "No IRQ!\n");
950-
951976
reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
952977
if (IS_ERR(reset_gpio))
953978
return PTR_ERR(reset_gpio);
@@ -997,10 +1022,20 @@ static int ili210x_i2c_probe(struct i2c_client *client)
9971022
if (error)
9981023
return dev_err_probe(dev, error, "Unable to set up slots\n");
9991024

1000-
error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
1001-
IRQF_ONESHOT, client->name, priv);
1002-
if (error)
1003-
return dev_err_probe(dev, error, "Unable to request touchscreen IRQ\n");
1025+
input_set_drvdata(input, priv);
1026+
1027+
if (client->irq > 0) {
1028+
error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
1029+
IRQF_ONESHOT, client->name, priv);
1030+
if (error)
1031+
return dev_err_probe(dev, error, "Unable to request touchscreen IRQ\n");
1032+
} else {
1033+
error = input_setup_polling(input, ili210x_work_i2c_poll);
1034+
if (error)
1035+
return dev_err_probe(dev, error, "Could not set up polling mode\n");
1036+
1037+
input_set_poll_interval(input, ILI2XXX_POLL_PERIOD);
1038+
}
10041039

10051040
error = devm_add_action_or_reset(dev, ili210x_stop, priv);
10061041
if (error)

0 commit comments

Comments
 (0)