From 97638920f1a40e2e0cab363d1e03837ff50c5478 Mon Sep 17 00:00:00 2001 From: eng33 Date: Thu, 5 Dec 2024 17:19:23 +0800 Subject: [PATCH] drivers:input:touchscreen: Add support for no irq to ili210x driver Signed-off-by: eng33 --- drivers/input/touchscreen/ili210x.c | 63 ++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 11 deletions(-) --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -67,6 +67,8 @@ struct ili210x { u8 version_proto[2]; u8 ic_mode[2]; bool stop; + struct timer_list poll_timer; + struct work_struct poll_work; }; static int ili210x_read_reg(struct i2c_client *client, @@ -360,6 +362,34 @@ static irqreturn_t ili210x_irq(int irq, return IRQ_HANDLED; } +static void ili210x_poll_work(struct work_struct *work) +{ + struct ili210x *priv = container_of(work, struct ili210x, poll_work); + struct i2c_client *client = priv->client; + const struct ili2xxx_chip *chip = priv->chip; + u8 touchdata[ILI210X_DATA_SIZE] = { 0 }; + bool touch; + int error; + + error = chip->get_touch_data(client, touchdata); + if (error) { + dev_err(&client->dev, "Unable to get touch data: %d\n", error); + return; + } + + touch = ili210x_report_events(priv, touchdata); +} + +static void ili210x_poll_timer_callback(struct timer_list *t) +{ + struct ili210x *priv = from_timer(priv, t, poll_timer); + + schedule_work(&priv->poll_work); + + if (!priv->stop) + mod_timer(&priv->poll_timer, jiffies + msecs_to_jiffies(ILI2XXX_POLL_PERIOD)); +} + static int ili251x_firmware_update_resolution(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -945,11 +975,6 @@ static int ili210x_i2c_probe(struct i2c_ return -ENODEV; } - if (client->irq <= 0) { - dev_err(dev, "No IRQ!\n"); - return -EINVAL; - } - reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset_gpio)) return PTR_ERR(reset_gpio); @@ -1001,12 +1026,17 @@ static int ili210x_i2c_probe(struct i2c_ return error; } - error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, - IRQF_ONESHOT, client->name, priv); - if (error) { - dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", - error); - return error; + if (client->irq) { + error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, + IRQF_ONESHOT, client->name, priv); + if (error) { + dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", error); + return error; + } + } else { + timer_setup(&priv->poll_timer, ili210x_poll_timer_callback, 0); + mod_timer(&priv->poll_timer, jiffies + msecs_to_jiffies(ILI2XXX_POLL_PERIOD)); + INIT_WORK(&priv->poll_work, ili210x_poll_work); } error = devm_add_action_or_reset(dev, ili210x_stop, priv); @@ -1029,6 +1059,16 @@ static int ili210x_i2c_probe(struct i2c_ return 0; } +static void ili210x_i2c_remove(struct i2c_client *client) +{ + struct ili210x *tsdata = i2c_get_clientdata(client); + + if (!client->irq) { + del_timer(&tsdata->poll_timer); + cancel_work_sync(&tsdata->poll_work); + } +} + static const struct i2c_device_id ili210x_i2c_id[] = { { "ili210x", (long)&ili210x_chip }, { "ili2117", (long)&ili211x_chip }, @@ -1054,6 +1094,7 @@ static struct i2c_driver ili210x_ts_driv }, .id_table = ili210x_i2c_id, .probe = ili210x_i2c_probe, + .remove = ili210x_i2c_remove, }; module_i2c_driver(ili210x_ts_driver);