Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: Add support for ILITEK Lego Series

Add support for ILITEK Lego series of touch devices.
Lego series includes ILITEK 213X/23XX/25XX.

Tested/passed with evaluation board with ILI2520/2322 IC.

Signed-off-by: Joe Hung <joe_hung@ilitek.com>
Link: https://lore.kernel.org/r/20210324122601.125873-2-joe_hung@ilitek.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Joe Hung and committed by
Dmitry Torokhov
42370681 7c06272f

+703
+12
drivers/input/touchscreen/Kconfig
··· 426 426 To compile this driver as a module, choose M here: the 427 427 module will be called ili210x. 428 428 429 + config TOUCHSCREEN_ILITEK 430 + tristate "Ilitek I2C 213X/23XX/25XX/Lego Series Touch ICs" 431 + depends on I2C 432 + help 433 + Say Y here if you have touchscreen with ILITEK touch IC, 434 + it supports 213X/23XX/25XX and other Lego series. 435 + 436 + If unsure, say N. 437 + 438 + To compile this driver as a module, choose M here: the 439 + module will be called ilitek_ts_i2c. 440 + 429 441 config TOUCHSCREEN_IPROC 430 442 tristate "IPROC touch panel driver support" 431 443 depends on ARCH_BCM_IPROC || COMPILE_TEST
+1
drivers/input/touchscreen/Makefile
··· 46 46 obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o 47 47 obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o 48 48 obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o 49 + obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek_ts_i2c.o 49 50 obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o 50 51 obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o 51 52 obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o
+690
drivers/input/touchscreen/ilitek_ts_i2c.c
··· 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 + 43 + struct ilitek_protocol_info { 44 + u16 ver; 45 + u8 ver_major; 46 + }; 47 + 48 + struct 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 + 70 + struct 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 + 76 + enum 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 */ 92 + static 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 */ 137 + static 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 + 148 + static 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 + 206 + err_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 */ 213 + static 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 + 230 + static 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 + 247 + static 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 + 265 + static 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 + 281 + static 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 + 300 + static 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 + 321 + static 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 + 336 + static 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 + 345 + static 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 + 354 + static 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 */ 391 + static 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 + 401 + static 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 + 422 + static 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 + 457 + static 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 + 495 + static 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 + 509 + static 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 + } 522 + static DEVICE_ATTR_RO(firmware_version); 523 + 524 + static 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 + } 533 + static DEVICE_ATTR_RO(product_id); 534 + 535 + static struct attribute *ilitek_sysfs_attrs[] = { 536 + &dev_attr_firmware_version.attr, 537 + &dev_attr_product_id.attr, 538 + NULL 539 + }; 540 + 541 + static struct attribute_group ilitek_attrs_group = { 542 + .attrs = ilitek_sysfs_attrs, 543 + }; 544 + 545 + static 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 + 608 + static 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 + 625 + static 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 + 644 + static SIMPLE_DEV_PM_OPS(ilitek_pm_ops, ilitek_suspend, ilitek_resume); 645 + 646 + static const struct i2c_device_id ilitek_ts_i2c_id[] = { 647 + { ILITEK_TS_NAME, 0 }, 648 + { }, 649 + }; 650 + MODULE_DEVICE_TABLE(i2c, ilitek_ts_i2c_id); 651 + 652 + #ifdef CONFIG_ACPI 653 + static const struct acpi_device_id ilitekts_acpi_id[] = { 654 + { "ILTK0001", 0 }, 655 + { }, 656 + }; 657 + MODULE_DEVICE_TABLE(acpi, ilitekts_acpi_id); 658 + #endif 659 + 660 + #ifdef CONFIG_OF 661 + static 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 + }; 673 + MODULE_DEVICE_TABLE(of, ilitek_ts_i2c_match); 674 + #endif 675 + 676 + static 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 + }; 686 + module_i2c_driver(ilitek_ts_i2c_driver); 687 + 688 + MODULE_AUTHOR("ILITEK"); 689 + MODULE_DESCRIPTION("ILITEK I2C Touchscreen Driver"); 690 + MODULE_LICENSE("GPL");