linux/drivers/input/touchscreen/ilitek_ts_i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * ILITEK Touch IC driver for 23XX, 25XX and Lego series
   4 *
   5 * Copyright (C) 2011 ILI Technology Corporation.
   6 * Copyright (C) 2020 Luca Hsu <luca_hsu@ilitek.com>
   7 * Copyright (C) 2021 Joe Hung <joe_hung@ilitek.com>
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/input.h>
  13#include <linux/input/mt.h>
  14#include <linux/i2c.h>
  15#include <linux/slab.h>
  16#include <linux/delay.h>
  17#include <linux/interrupt.h>
  18#include <linux/gpio.h>
  19#include <linux/gpio/consumer.h>
  20#include <linux/errno.h>
  21#include <linux/acpi.h>
  22#include <linux/input/touchscreen.h>
  23#include <asm/unaligned.h>
  24
  25
  26#define ILITEK_TS_NAME                                  "ilitek_ts"
  27#define BL_V1_8                                         0x108
  28#define BL_V1_7                                         0x107
  29#define BL_V1_6                                         0x106
  30
  31#define ILITEK_TP_CMD_GET_TP_RES                        0x20
  32#define ILITEK_TP_CMD_GET_SCRN_RES                      0x21
  33#define ILITEK_TP_CMD_SET_IC_SLEEP                      0x30
  34#define ILITEK_TP_CMD_SET_IC_WAKE                       0x31
  35#define ILITEK_TP_CMD_GET_FW_VER                        0x40
  36#define ILITEK_TP_CMD_GET_PRL_VER                       0x42
  37#define ILITEK_TP_CMD_GET_MCU_VER                       0x61
  38#define ILITEK_TP_CMD_GET_IC_MODE                       0xC0
  39
  40#define REPORT_COUNT_ADDRESS                            61
  41#define ILITEK_SUPPORT_MAX_POINT                        40
  42
  43struct ilitek_protocol_info {
  44        u16 ver;
  45        u8 ver_major;
  46};
  47
  48struct ilitek_ts_data {
  49        struct i2c_client               *client;
  50        struct gpio_desc                *reset_gpio;
  51        struct input_dev                *input_dev;
  52        struct touchscreen_properties   prop;
  53
  54        const struct ilitek_protocol_map *ptl_cb_func;
  55        struct ilitek_protocol_info     ptl;
  56
  57        char                            product_id[30];
  58        u16                             mcu_ver;
  59        u8                              ic_mode;
  60        u8                              firmware_ver[8];
  61
  62        s32                             reset_time;
  63        s32                             screen_max_x;
  64        s32                             screen_max_y;
  65        s32                             screen_min_x;
  66        s32                             screen_min_y;
  67        s32                             max_tp;
  68};
  69
  70struct ilitek_protocol_map {
  71        u16 cmd;
  72        const char *name;
  73        int (*func)(struct ilitek_ts_data *ts, u16 cmd, u8 *inbuf, u8 *outbuf);
  74};
  75
  76enum ilitek_cmds {
  77        /* common cmds */
  78        GET_PTL_VER = 0,
  79        GET_FW_VER,
  80        GET_SCRN_RES,
  81        GET_TP_RES,
  82        GET_IC_MODE,
  83        GET_MCU_VER,
  84        SET_IC_SLEEP,
  85        SET_IC_WAKE,
  86
  87        /* ALWAYS keep at the end */
  88        MAX_CMD_CNT
  89};
  90
  91/* ILITEK I2C R/W APIs */
  92static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
  93                                     u8 *cmd, int write_len, int delay,
  94                                     u8 *data, int read_len)
  95{
  96        int error;
  97        struct i2c_client *client = ts->client;
  98        struct i2c_msg msgs[] = {
  99                {
 100                        .addr = client->addr,
 101                        .flags = 0,
 102                        .len = write_len,
 103                        .buf = cmd,
 104                },
 105                {
 106                        .addr = client->addr,
 107                        .flags = I2C_M_RD,
 108                        .len = read_len,
 109                        .buf = data,
 110                },
 111        };
 112
 113        if (delay == 0 && write_len > 0 && read_len > 0) {
 114                error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 115                if (error < 0)
 116                        return error;
 117        } else {
 118                if (write_len > 0) {
 119                        error = i2c_transfer(client->adapter, msgs, 1);
 120                        if (error < 0)
 121                                return error;
 122                }
 123                if (delay > 0)
 124                        mdelay(delay);
 125
 126                if (read_len > 0) {
 127                        error = i2c_transfer(client->adapter, msgs + 1, 1);
 128                        if (error < 0)
 129                                return error;
 130                }
 131        }
 132
 133        return 0;
 134}
 135
 136/* ILITEK ISR APIs */
 137static void ilitek_touch_down(struct ilitek_ts_data *ts, unsigned int id,
 138                              unsigned int x, unsigned int y)
 139{
 140        struct input_dev *input = ts->input_dev;
 141
 142        input_mt_slot(input, id);
 143        input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
 144
 145        touchscreen_report_pos(input, &ts->prop, x, y, true);
 146}
 147
 148static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
 149{
 150        int error = 0;
 151        u8 buf[512];
 152        int packet_len = 5;
 153        int packet_max_point = 10;
 154        int report_max_point;
 155        int i, count;
 156        struct input_dev *input = ts->input_dev;
 157        struct device *dev = &ts->client->dev;
 158        unsigned int x, y, status, id;
 159
 160        error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
 161        if (error) {
 162                dev_err(dev, "get touch info failed, err:%d\n", error);
 163                goto err_sync_frame;
 164        }
 165
 166        report_max_point = buf[REPORT_COUNT_ADDRESS];
 167        if (report_max_point > ts->max_tp) {
 168                dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
 169                        report_max_point, ts->max_tp);
 170                error = -EINVAL;
 171                goto err_sync_frame;
 172        }
 173
 174        count = DIV_ROUND_UP(report_max_point, packet_max_point);
 175        for (i = 1; i < count; i++) {
 176                error = ilitek_i2c_write_and_read(ts, NULL, 0, 0,
 177                                                  buf + i * 64, 64);
 178                if (error) {
 179                        dev_err(dev, "get touch info. failed, cnt:%d, err:%d\n",
 180                                count, error);
 181                        goto err_sync_frame;
 182                }
 183        }
 184
 185        for (i = 0; i < report_max_point; i++) {
 186                status = buf[i * packet_len + 1] & 0x40;
 187                if (!status)
 188                        continue;
 189
 190                id = buf[i * packet_len + 1] & 0x3F;
 191
 192                x = get_unaligned_le16(buf + i * packet_len + 2);
 193                y = get_unaligned_le16(buf + i * packet_len + 4);
 194
 195                if (x > ts->screen_max_x || x < ts->screen_min_x ||
 196                    y > ts->screen_max_y || y < ts->screen_min_y) {
 197                        dev_warn(dev, "invalid position, X[%d,%u,%d], Y[%d,%u,%d]\n",
 198                                 ts->screen_min_x, x, ts->screen_max_x,
 199                                 ts->screen_min_y, y, ts->screen_max_y);
 200                        continue;
 201                }
 202
 203                ilitek_touch_down(ts, id, x, y);
 204        }
 205
 206err_sync_frame:
 207        input_mt_sync_frame(input);
 208        input_sync(input);
 209        return error;
 210}
 211
 212/* APIs of cmds for ILITEK Touch IC */
 213static int api_protocol_set_cmd(struct ilitek_ts_data *ts,
 214                                u16 idx, u8 *inbuf, u8 *outbuf)
 215{
 216        u16 cmd;
 217        int error;
 218
 219        if (idx >= MAX_CMD_CNT)
 220                return -EINVAL;
 221
 222        cmd = ts->ptl_cb_func[idx].cmd;
 223        error = ts->ptl_cb_func[idx].func(ts, cmd, inbuf, outbuf);
 224        if (error)
 225                return error;
 226
 227        return 0;
 228}
 229
 230static int api_protocol_get_ptl_ver(struct ilitek_ts_data *ts,
 231                                    u16 cmd, u8 *inbuf, u8 *outbuf)
 232{
 233        int error;
 234        u8 buf[64];
 235
 236        buf[0] = cmd;
 237        error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 3);
 238        if (error)
 239                return error;
 240
 241        ts->ptl.ver = get_unaligned_be16(outbuf);
 242        ts->ptl.ver_major = outbuf[0];
 243
 244        return 0;
 245}
 246
 247static int api_protocol_get_mcu_ver(struct ilitek_ts_data *ts,
 248                                    u16 cmd, u8 *inbuf, u8 *outbuf)
 249{
 250        int error;
 251        u8 buf[64];
 252
 253        buf[0] = cmd;
 254        error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 32);
 255        if (error)
 256                return error;
 257
 258        ts->mcu_ver = get_unaligned_le16(outbuf);
 259        memset(ts->product_id, 0, sizeof(ts->product_id));
 260        memcpy(ts->product_id, outbuf + 6, 26);
 261
 262        return 0;
 263}
 264
 265static int api_protocol_get_fw_ver(struct ilitek_ts_data *ts,
 266                                   u16 cmd, u8 *inbuf, u8 *outbuf)
 267{
 268        int error;
 269        u8 buf[64];
 270
 271        buf[0] = cmd;
 272        error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 8);
 273        if (error)
 274                return error;
 275
 276        memcpy(ts->firmware_ver, outbuf, 8);
 277
 278        return 0;
 279}
 280
 281static int api_protocol_get_scrn_res(struct ilitek_ts_data *ts,
 282                                     u16 cmd, u8 *inbuf, u8 *outbuf)
 283{
 284        int error;
 285        u8 buf[64];
 286
 287        buf[0] = cmd;
 288        error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 8);
 289        if (error)
 290                return error;
 291
 292        ts->screen_min_x = get_unaligned_le16(outbuf);
 293        ts->screen_min_y = get_unaligned_le16(outbuf + 2);
 294        ts->screen_max_x = get_unaligned_le16(outbuf + 4);
 295        ts->screen_max_y = get_unaligned_le16(outbuf + 6);
 296
 297        return 0;
 298}
 299
 300static int api_protocol_get_tp_res(struct ilitek_ts_data *ts,
 301                                   u16 cmd, u8 *inbuf, u8 *outbuf)
 302{
 303        int error;
 304        u8 buf[64];
 305
 306        buf[0] = cmd;
 307        error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 15);
 308        if (error)
 309                return error;
 310
 311        ts->max_tp = outbuf[8];
 312        if (ts->max_tp > ILITEK_SUPPORT_MAX_POINT) {
 313                dev_err(&ts->client->dev, "Invalid MAX_TP:%d from FW\n",
 314                        ts->max_tp);
 315                return -EINVAL;
 316        }
 317
 318        return 0;
 319}
 320
 321static int api_protocol_get_ic_mode(struct ilitek_ts_data *ts,
 322                                    u16 cmd, u8 *inbuf, u8 *outbuf)
 323{
 324        int error;
 325        u8 buf[64];
 326
 327        buf[0] = cmd;
 328        error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 2);
 329        if (error)
 330                return error;
 331
 332        ts->ic_mode = outbuf[0];
 333        return 0;
 334}
 335
 336static int api_protocol_set_ic_sleep(struct ilitek_ts_data *ts,
 337                                     u16 cmd, u8 *inbuf, u8 *outbuf)
 338{
 339        u8 buf[64];
 340
 341        buf[0] = cmd;
 342        return ilitek_i2c_write_and_read(ts, buf, 1, 0, NULL, 0);
 343}
 344
 345static int api_protocol_set_ic_wake(struct ilitek_ts_data *ts,
 346                                    u16 cmd, u8 *inbuf, u8 *outbuf)
 347{
 348        u8 buf[64];
 349
 350        buf[0] = cmd;
 351        return ilitek_i2c_write_and_read(ts, buf, 1, 0, NULL, 0);
 352}
 353
 354static const struct ilitek_protocol_map ptl_func_map[] = {
 355        /* common cmds */
 356        [GET_PTL_VER] = {
 357                ILITEK_TP_CMD_GET_PRL_VER, "GET_PTL_VER",
 358                api_protocol_get_ptl_ver
 359        },
 360        [GET_FW_VER] = {
 361                ILITEK_TP_CMD_GET_FW_VER, "GET_FW_VER",
 362                api_protocol_get_fw_ver
 363        },
 364        [GET_SCRN_RES] = {
 365                ILITEK_TP_CMD_GET_SCRN_RES, "GET_SCRN_RES",
 366                api_protocol_get_scrn_res
 367        },
 368        [GET_TP_RES] = {
 369                ILITEK_TP_CMD_GET_TP_RES, "GET_TP_RES",
 370                api_protocol_get_tp_res
 371        },
 372        [GET_IC_MODE] = {
 373                ILITEK_TP_CMD_GET_IC_MODE, "GET_IC_MODE",
 374                           api_protocol_get_ic_mode
 375        },
 376        [GET_MCU_VER] = {
 377                ILITEK_TP_CMD_GET_MCU_VER, "GET_MOD_VER",
 378                           api_protocol_get_mcu_ver
 379        },
 380        [SET_IC_SLEEP] = {
 381                ILITEK_TP_CMD_SET_IC_SLEEP, "SET_IC_SLEEP",
 382                api_protocol_set_ic_sleep
 383        },
 384        [SET_IC_WAKE] = {
 385                ILITEK_TP_CMD_SET_IC_WAKE, "SET_IC_WAKE",
 386                api_protocol_set_ic_wake
 387        },
 388};
 389
 390/* Probe APIs */
 391static void ilitek_reset(struct ilitek_ts_data *ts, int delay)
 392{
 393        if (ts->reset_gpio) {
 394                gpiod_set_value(ts->reset_gpio, 1);
 395                mdelay(10);
 396                gpiod_set_value(ts->reset_gpio, 0);
 397                mdelay(delay);
 398        }
 399}
 400
 401static int ilitek_protocol_init(struct ilitek_ts_data *ts)
 402{
 403        int error;
 404        u8 outbuf[64];
 405
 406        ts->ptl_cb_func = ptl_func_map;
 407        ts->reset_time = 600;
 408
 409        error = api_protocol_set_cmd(ts, GET_PTL_VER, NULL, outbuf);
 410        if (error)
 411                return error;
 412
 413        /* Protocol v3 is not support currently */
 414        if (ts->ptl.ver_major == 0x3 ||
 415            ts->ptl.ver == BL_V1_6 ||
 416            ts->ptl.ver == BL_V1_7)
 417                return -EINVAL;
 418
 419        return 0;
 420}
 421
 422static int ilitek_read_tp_info(struct ilitek_ts_data *ts, bool boot)
 423{
 424        u8 outbuf[256];
 425        int error;
 426
 427        error = api_protocol_set_cmd(ts, GET_PTL_VER, NULL, outbuf);
 428        if (error)
 429                return error;
 430
 431        error = api_protocol_set_cmd(ts, GET_MCU_VER, NULL, outbuf);
 432        if (error)
 433                return error;
 434
 435        error = api_protocol_set_cmd(ts, GET_FW_VER, NULL, outbuf);
 436        if (error)
 437                return error;
 438
 439        if (boot) {
 440                error = api_protocol_set_cmd(ts, GET_SCRN_RES, NULL,
 441                                             outbuf);
 442                if (error)
 443                        return error;
 444        }
 445
 446        error = api_protocol_set_cmd(ts, GET_TP_RES, NULL, outbuf);
 447        if (error)
 448                return error;
 449
 450        error = api_protocol_set_cmd(ts, GET_IC_MODE, NULL, outbuf);
 451        if (error)
 452                return error;
 453
 454        return 0;
 455}
 456
 457static int ilitek_input_dev_init(struct device *dev, struct ilitek_ts_data *ts)
 458{
 459        int error;
 460        struct input_dev *input;
 461
 462        input = devm_input_allocate_device(dev);
 463        if (!input)
 464                return -ENOMEM;
 465
 466        ts->input_dev = input;
 467        input->name = ILITEK_TS_NAME;
 468        input->id.bustype = BUS_I2C;
 469
 470        __set_bit(INPUT_PROP_DIRECT, input->propbit);
 471
 472        input_set_abs_params(input, ABS_MT_POSITION_X,
 473                             ts->screen_min_x, ts->screen_max_x, 0, 0);
 474        input_set_abs_params(input, ABS_MT_POSITION_Y,
 475                             ts->screen_min_y, ts->screen_max_y, 0, 0);
 476
 477        touchscreen_parse_properties(input, true, &ts->prop);
 478
 479        error = input_mt_init_slots(input, ts->max_tp,
 480                                    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
 481        if (error) {
 482                dev_err(dev, "initialize MT slots failed, err:%d\n", error);
 483                return error;
 484        }
 485
 486        error = input_register_device(input);
 487        if (error) {
 488                dev_err(dev, "register input device failed, err:%d\n", error);
 489                return error;
 490        }
 491
 492        return 0;
 493}
 494
 495static irqreturn_t ilitek_i2c_isr(int irq, void *dev_id)
 496{
 497        struct ilitek_ts_data *ts = dev_id;
 498        int error;
 499
 500        error = ilitek_process_and_report_v6(ts);
 501        if (error < 0) {
 502                dev_err(&ts->client->dev, "[%s] err:%d\n", __func__, error);
 503                return IRQ_NONE;
 504        }
 505
 506        return IRQ_HANDLED;
 507}
 508
 509static ssize_t firmware_version_show(struct device *dev,
 510                                     struct device_attribute *attr, char *buf)
 511{
 512        struct i2c_client *client = to_i2c_client(dev);
 513        struct ilitek_ts_data *ts = i2c_get_clientdata(client);
 514
 515        return scnprintf(buf, PAGE_SIZE,
 516                         "fw version: [%02X%02X.%02X%02X.%02X%02X.%02X%02X]\n",
 517                         ts->firmware_ver[0], ts->firmware_ver[1],
 518                         ts->firmware_ver[2], ts->firmware_ver[3],
 519                         ts->firmware_ver[4], ts->firmware_ver[5],
 520                         ts->firmware_ver[6], ts->firmware_ver[7]);
 521}
 522static DEVICE_ATTR_RO(firmware_version);
 523
 524static ssize_t product_id_show(struct device *dev,
 525                               struct device_attribute *attr, char *buf)
 526{
 527        struct i2c_client *client = to_i2c_client(dev);
 528        struct ilitek_ts_data *ts = i2c_get_clientdata(client);
 529
 530        return scnprintf(buf, PAGE_SIZE, "product id: [%04X], module: [%s]\n",
 531                         ts->mcu_ver, ts->product_id);
 532}
 533static DEVICE_ATTR_RO(product_id);
 534
 535static struct attribute *ilitek_sysfs_attrs[] = {
 536        &dev_attr_firmware_version.attr,
 537        &dev_attr_product_id.attr,
 538        NULL
 539};
 540
 541static struct attribute_group ilitek_attrs_group = {
 542        .attrs = ilitek_sysfs_attrs,
 543};
 544
 545static int ilitek_ts_i2c_probe(struct i2c_client *client,
 546                               const struct i2c_device_id *id)
 547{
 548        struct ilitek_ts_data *ts;
 549        struct device *dev = &client->dev;
 550        int error;
 551
 552        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 553                dev_err(dev, "i2c check functionality failed\n");
 554                return -ENXIO;
 555        }
 556
 557        ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
 558        if (!ts)
 559                return -ENOMEM;
 560
 561        ts->client = client;
 562        i2c_set_clientdata(client, ts);
 563
 564        ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 565        if (IS_ERR(ts->reset_gpio)) {
 566                error = PTR_ERR(ts->reset_gpio);
 567                dev_err(dev, "request gpiod failed: %d", error);
 568                return error;
 569        }
 570
 571        ilitek_reset(ts, 1000);
 572
 573        error = ilitek_protocol_init(ts);
 574        if (error) {
 575                dev_err(dev, "protocol init failed: %d", error);
 576                return error;
 577        }
 578
 579        error = ilitek_read_tp_info(ts, true);
 580        if (error) {
 581                dev_err(dev, "read tp info failed: %d", error);
 582                return error;
 583        }
 584
 585        error = ilitek_input_dev_init(dev, ts);
 586        if (error) {
 587                dev_err(dev, "input dev init failed: %d", error);
 588                return error;
 589        }
 590
 591        error = devm_request_threaded_irq(dev, ts->client->irq,
 592                                          NULL, ilitek_i2c_isr, IRQF_ONESHOT,
 593                                          "ilitek_touch_irq", ts);
 594        if (error) {
 595                dev_err(dev, "request threaded irq failed: %d\n", error);
 596                return error;
 597        }
 598
 599        error = devm_device_add_group(dev, &ilitek_attrs_group);
 600        if (error) {
 601                dev_err(dev, "sysfs create group failed: %d\n", error);
 602                return error;
 603        }
 604
 605        return 0;
 606}
 607
 608static int __maybe_unused ilitek_suspend(struct device *dev)
 609{
 610        struct i2c_client *client = to_i2c_client(dev);
 611        struct ilitek_ts_data *ts = i2c_get_clientdata(client);
 612        int error;
 613
 614        disable_irq(client->irq);
 615
 616        if (!device_may_wakeup(dev)) {
 617                error = api_protocol_set_cmd(ts, SET_IC_SLEEP, NULL, NULL);
 618                if (error)
 619                        return error;
 620        }
 621
 622        return 0;
 623}
 624
 625static int __maybe_unused ilitek_resume(struct device *dev)
 626{
 627        struct i2c_client *client = to_i2c_client(dev);
 628        struct ilitek_ts_data *ts = i2c_get_clientdata(client);
 629        int error;
 630
 631        if (!device_may_wakeup(dev)) {
 632                error = api_protocol_set_cmd(ts, SET_IC_WAKE, NULL, NULL);
 633                if (error)
 634                        return error;
 635
 636                ilitek_reset(ts, ts->reset_time);
 637        }
 638
 639        enable_irq(client->irq);
 640
 641        return 0;
 642}
 643
 644static SIMPLE_DEV_PM_OPS(ilitek_pm_ops, ilitek_suspend, ilitek_resume);
 645
 646static const struct i2c_device_id ilitek_ts_i2c_id[] = {
 647        { ILITEK_TS_NAME, 0 },
 648        { },
 649};
 650MODULE_DEVICE_TABLE(i2c, ilitek_ts_i2c_id);
 651
 652#ifdef CONFIG_ACPI
 653static const struct acpi_device_id ilitekts_acpi_id[] = {
 654        { "ILTK0001", 0 },
 655        { },
 656};
 657MODULE_DEVICE_TABLE(acpi, ilitekts_acpi_id);
 658#endif
 659
 660#ifdef CONFIG_OF
 661static const struct of_device_id ilitek_ts_i2c_match[] = {
 662        {.compatible = "ilitek,ili2130",},
 663        {.compatible = "ilitek,ili2131",},
 664        {.compatible = "ilitek,ili2132",},
 665        {.compatible = "ilitek,ili2316",},
 666        {.compatible = "ilitek,ili2322",},
 667        {.compatible = "ilitek,ili2323",},
 668        {.compatible = "ilitek,ili2326",},
 669        {.compatible = "ilitek,ili2520",},
 670        {.compatible = "ilitek,ili2521",},
 671        { },
 672};
 673MODULE_DEVICE_TABLE(of, ilitek_ts_i2c_match);
 674#endif
 675
 676static struct i2c_driver ilitek_ts_i2c_driver = {
 677        .driver = {
 678                .name = ILITEK_TS_NAME,
 679                .pm = &ilitek_pm_ops,
 680                .of_match_table = of_match_ptr(ilitek_ts_i2c_match),
 681                .acpi_match_table = ACPI_PTR(ilitekts_acpi_id),
 682        },
 683        .probe = ilitek_ts_i2c_probe,
 684        .id_table = ilitek_ts_i2c_id,
 685};
 686module_i2c_driver(ilitek_ts_i2c_driver);
 687
 688MODULE_AUTHOR("ILITEK");
 689MODULE_DESCRIPTION("ILITEK I2C Touchscreen Driver");
 690MODULE_LICENSE("GPL");
 691