d13982e9badb36bf9f713e540045ef8f83a830f1
[openwrt/staging/pepe2k.git] /
1 From 97638920f1a40e2e0cab363d1e03837ff50c5478 Mon Sep 17 00:00:00 2001
2 From: eng33 <eng33@waveshare.com>
3 Date: Thu, 5 Dec 2024 17:19:23 +0800
4 Subject: [PATCH] drivers:input:touchscreen: Add support for no irq to ili210x
5 driver
6
7 Signed-off-by: eng33 <eng33@waveshare.com>
8 ---
9 drivers/input/touchscreen/ili210x.c | 63 ++++++++++++++++++++++++-----
10 1 file changed, 52 insertions(+), 11 deletions(-)
11
12 --- a/drivers/input/touchscreen/ili210x.c
13 +++ b/drivers/input/touchscreen/ili210x.c
14 @@ -67,6 +67,8 @@ struct ili210x {
15 u8 version_proto[2];
16 u8 ic_mode[2];
17 bool stop;
18 + struct timer_list poll_timer;
19 + struct work_struct poll_work;
20 };
21
22 static int ili210x_read_reg(struct i2c_client *client,
23 @@ -360,6 +362,34 @@ static irqreturn_t ili210x_irq(int irq,
24 return IRQ_HANDLED;
25 }
26
27 +static void ili210x_poll_work(struct work_struct *work)
28 +{
29 + struct ili210x *priv = container_of(work, struct ili210x, poll_work);
30 + struct i2c_client *client = priv->client;
31 + const struct ili2xxx_chip *chip = priv->chip;
32 + u8 touchdata[ILI210X_DATA_SIZE] = { 0 };
33 + bool touch;
34 + int error;
35 +
36 + error = chip->get_touch_data(client, touchdata);
37 + if (error) {
38 + dev_err(&client->dev, "Unable to get touch data: %d\n", error);
39 + return;
40 + }
41 +
42 + touch = ili210x_report_events(priv, touchdata);
43 +}
44 +
45 +static void ili210x_poll_timer_callback(struct timer_list *t)
46 +{
47 + struct ili210x *priv = from_timer(priv, t, poll_timer);
48 +
49 + schedule_work(&priv->poll_work);
50 +
51 + if (!priv->stop)
52 + mod_timer(&priv->poll_timer, jiffies + msecs_to_jiffies(ILI2XXX_POLL_PERIOD));
53 +}
54 +
55 static int ili251x_firmware_update_resolution(struct device *dev)
56 {
57 struct i2c_client *client = to_i2c_client(dev);
58 @@ -945,11 +975,6 @@ static int ili210x_i2c_probe(struct i2c_
59 return -ENODEV;
60 }
61
62 - if (client->irq <= 0) {
63 - dev_err(dev, "No IRQ!\n");
64 - return -EINVAL;
65 - }
66 -
67 reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
68 if (IS_ERR(reset_gpio))
69 return PTR_ERR(reset_gpio);
70 @@ -1001,12 +1026,17 @@ static int ili210x_i2c_probe(struct i2c_
71 return error;
72 }
73
74 - error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
75 - IRQF_ONESHOT, client->name, priv);
76 - if (error) {
77 - dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
78 - error);
79 - return error;
80 + if (client->irq) {
81 + error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
82 + IRQF_ONESHOT, client->name, priv);
83 + if (error) {
84 + dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", error);
85 + return error;
86 + }
87 + } else {
88 + timer_setup(&priv->poll_timer, ili210x_poll_timer_callback, 0);
89 + mod_timer(&priv->poll_timer, jiffies + msecs_to_jiffies(ILI2XXX_POLL_PERIOD));
90 + INIT_WORK(&priv->poll_work, ili210x_poll_work);
91 }
92
93 error = devm_add_action_or_reset(dev, ili210x_stop, priv);
94 @@ -1029,6 +1059,16 @@ static int ili210x_i2c_probe(struct i2c_
95 return 0;
96 }
97
98 +static void ili210x_i2c_remove(struct i2c_client *client)
99 +{
100 + struct ili210x *tsdata = i2c_get_clientdata(client);
101 +
102 + if (!client->irq) {
103 + del_timer(&tsdata->poll_timer);
104 + cancel_work_sync(&tsdata->poll_work);
105 + }
106 +}
107 +
108 static const struct i2c_device_id ili210x_i2c_id[] = {
109 { "ili210x", (long)&ili210x_chip },
110 { "ili2117", (long)&ili211x_chip },
111 @@ -1054,6 +1094,7 @@ static struct i2c_driver ili210x_ts_driv
112 },
113 .id_table = ili210x_i2c_id,
114 .probe = ili210x_i2c_probe,
115 + .remove = ili210x_i2c_remove,
116 };
117
118 module_i2c_driver(ili210x_ts_driver);