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: 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>

authored by

Marek Vasut and committed by
Dmitry Torokhov
a0077217 87ac7cfa

+55 -20
+55 -20
drivers/input/touchscreen/ili210x.c
··· 327 327 return contact; 328 328 } 329 329 330 - static irqreturn_t ili210x_irq(int irq, void *irq_data) 330 + static void ili210x_process_events(struct ili210x *priv) 331 331 { 332 - struct ili210x *priv = irq_data; 333 332 struct i2c_client *client = priv->client; 334 333 const struct ili2xxx_chip *chip = priv->chip; 335 334 u8 touchdata[ILI210X_DATA_SIZE] = { 0 }; ··· 355 356 usleep_range(time_delta, time_delta + 1000); 356 357 } 357 358 } while (!priv->stop && keep_polling); 359 + } 360 + 361 + static irqreturn_t ili210x_irq(int irq, void *irq_data) 362 + { 363 + struct ili210x *priv = irq_data; 364 + 365 + ili210x_process_events(priv); 358 366 359 367 return IRQ_HANDLED; 368 + }; 369 + 370 + static void ili210x_work_i2c_poll(struct input_dev *input) 371 + { 372 + struct ili210x *priv = input_get_drvdata(input); 373 + 374 + ili210x_process_events(priv); 360 375 } 361 376 362 377 static int ili251x_firmware_update_resolution(struct device *dev) ··· 842 829 return 0; 843 830 } 844 831 832 + static ssize_t ili210x_firmware_update(struct device *dev, const u8 *fwbuf, 833 + u16 ac_end, u16 df_end) 834 + { 835 + struct i2c_client *client = to_i2c_client(dev); 836 + struct ili210x *priv = i2c_get_clientdata(client); 837 + const char *fwname = ILI251X_FW_FILENAME; 838 + int error; 839 + 840 + dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname); 841 + 842 + ili210x_hardware_reset(priv->reset_gpio); 843 + 844 + error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); 845 + 846 + ili210x_hardware_reset(priv->reset_gpio); 847 + 848 + dev_dbg(dev, "Firmware update ended, error=%i\n", error); 849 + 850 + return error; 851 + } 852 + 845 853 static ssize_t ili210x_firmware_update_store(struct device *dev, 846 854 struct device_attribute *attr, 847 855 const char *buf, size_t count) 848 856 { 849 857 struct i2c_client *client = to_i2c_client(dev); 850 - struct ili210x *priv = i2c_get_clientdata(client); 851 858 const char *fwname = ILI251X_FW_FILENAME; 852 859 u16 ac_end, df_end; 853 860 int error; ··· 893 860 * the touch controller to disable the IRQs during update, so we have 894 861 * to do it this way here. 895 862 */ 896 - scoped_guard(disable_irq, &client->irq) { 897 - dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname); 898 - 899 - ili210x_hardware_reset(priv->reset_gpio); 900 - 901 - error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); 902 - 903 - ili210x_hardware_reset(priv->reset_gpio); 904 - 905 - dev_dbg(dev, "Firmware update ended, error=%i\n", error); 863 + if (client->irq > 0) { 864 + guard(disable_irq)(&client->irq); 865 + error = ili210x_firmware_update(dev, fwbuf, ac_end, df_end); 866 + } else { 867 + error = ili210x_firmware_update(dev, fwbuf, ac_end, df_end); 906 868 } 907 869 908 870 return error ?: count; ··· 973 945 if (!chip) 974 946 return dev_err_probe(&client->dev, -ENODEV, "unknown device model\n"); 975 947 976 - if (client->irq <= 0) 977 - return dev_err_probe(dev, -EINVAL, "No IRQ!\n"); 978 - 979 948 reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 980 949 if (IS_ERR(reset_gpio)) 981 950 return PTR_ERR(reset_gpio); ··· 1022 997 if (error) 1023 998 return dev_err_probe(dev, error, "Unable to set up slots\n"); 1024 999 1025 - error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, 1026 - IRQF_ONESHOT, client->name, priv); 1027 - if (error) 1028 - return dev_err_probe(dev, error, "Unable to request touchscreen IRQ\n"); 1000 + input_set_drvdata(input, priv); 1001 + 1002 + if (client->irq > 0) { 1003 + error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, 1004 + IRQF_ONESHOT, client->name, priv); 1005 + if (error) 1006 + return dev_err_probe(dev, error, "Unable to request touchscreen IRQ\n"); 1007 + } else { 1008 + error = input_setup_polling(input, ili210x_work_i2c_poll); 1009 + if (error) 1010 + return dev_err_probe(dev, error, "Could not set up polling mode\n"); 1011 + 1012 + input_set_poll_interval(input, ILI2XXX_POLL_PERIOD); 1013 + } 1029 1014 1030 1015 error = devm_add_action_or_reset(dev, ili210x_stop, priv); 1031 1016 if (error)