1ca96ea86SBastien Nocera /* 2ca96ea86SBastien Nocera * Driver for Goodix Touchscreens 3ca96ea86SBastien Nocera * 4ca96ea86SBastien Nocera * Copyright (c) 2014 Red Hat Inc. 5ca96ea86SBastien Nocera * 6ca96ea86SBastien Nocera * This code is based on gt9xx.c authored by andrew@goodix.com: 7ca96ea86SBastien Nocera * 8ca96ea86SBastien Nocera * 2010 - 2012 Goodix Technology. 9ca96ea86SBastien Nocera */ 10ca96ea86SBastien Nocera 11ca96ea86SBastien Nocera /* 12ca96ea86SBastien Nocera * This program is free software; you can redistribute it and/or modify it 13ca96ea86SBastien Nocera * under the terms of the GNU General Public License as published by the Free 14ca96ea86SBastien Nocera * Software Foundation; version 2 of the License. 15ca96ea86SBastien Nocera */ 16ca96ea86SBastien Nocera 17ca96ea86SBastien Nocera #include <linux/kernel.h> 18ca96ea86SBastien Nocera #include <linux/i2c.h> 19ca96ea86SBastien Nocera #include <linux/input.h> 20ca96ea86SBastien Nocera #include <linux/input/mt.h> 21ca96ea86SBastien Nocera #include <linux/module.h> 22ca96ea86SBastien Nocera #include <linux/delay.h> 23ca96ea86SBastien Nocera #include <linux/irq.h> 24ca96ea86SBastien Nocera #include <linux/interrupt.h> 25ca96ea86SBastien Nocera #include <linux/slab.h> 26ca96ea86SBastien Nocera #include <asm/unaligned.h> 27ca96ea86SBastien Nocera 28ca96ea86SBastien Nocera struct goodix_ts_data { 29ca96ea86SBastien Nocera struct i2c_client *client; 30ca96ea86SBastien Nocera struct input_dev *input_dev; 31ca96ea86SBastien Nocera int abs_x_max; 32ca96ea86SBastien Nocera int abs_y_max; 33ca96ea86SBastien Nocera unsigned int max_touch_num; 34ca96ea86SBastien Nocera unsigned int int_trigger_type; 35ca96ea86SBastien Nocera }; 36ca96ea86SBastien Nocera 37ca96ea86SBastien Nocera #define GOODIX_MAX_HEIGHT 4096 38ca96ea86SBastien Nocera #define GOODIX_MAX_WIDTH 4096 39ca96ea86SBastien Nocera #define GOODIX_INT_TRIGGER 1 40ca96ea86SBastien Nocera #define GOODIX_CONTACT_SIZE 8 41ca96ea86SBastien Nocera #define GOODIX_MAX_CONTACTS 10 42ca96ea86SBastien Nocera 43ca96ea86SBastien Nocera #define GOODIX_CONFIG_MAX_LENGTH 240 44ca96ea86SBastien Nocera 45ca96ea86SBastien Nocera /* Register defines */ 46ca96ea86SBastien Nocera #define GOODIX_READ_COOR_ADDR 0x814E 47ca96ea86SBastien Nocera #define GOODIX_REG_CONFIG_DATA 0x8047 48ca96ea86SBastien Nocera #define GOODIX_REG_VERSION 0x8140 49ca96ea86SBastien Nocera 50ca96ea86SBastien Nocera #define RESOLUTION_LOC 1 51ca96ea86SBastien Nocera #define TRIGGER_LOC 6 52ca96ea86SBastien Nocera 53ca96ea86SBastien Nocera static const unsigned long goodix_irq_flags[] = { 54ca96ea86SBastien Nocera IRQ_TYPE_EDGE_RISING, 55ca96ea86SBastien Nocera IRQ_TYPE_EDGE_FALLING, 56ca96ea86SBastien Nocera IRQ_TYPE_LEVEL_LOW, 57ca96ea86SBastien Nocera IRQ_TYPE_LEVEL_HIGH, 58ca96ea86SBastien Nocera }; 59ca96ea86SBastien Nocera 60ca96ea86SBastien Nocera /** 61ca96ea86SBastien Nocera * goodix_i2c_read - read data from a register of the i2c slave device. 62ca96ea86SBastien Nocera * 63ca96ea86SBastien Nocera * @client: i2c device. 64ca96ea86SBastien Nocera * @reg: the register to read from. 65ca96ea86SBastien Nocera * @buf: raw write data buffer. 66ca96ea86SBastien Nocera * @len: length of the buffer to write 67ca96ea86SBastien Nocera */ 68ca96ea86SBastien Nocera static int goodix_i2c_read(struct i2c_client *client, 69ca96ea86SBastien Nocera u16 reg, u8 *buf, int len) 70ca96ea86SBastien Nocera { 71ca96ea86SBastien Nocera struct i2c_msg msgs[2]; 72ca96ea86SBastien Nocera u16 wbuf = cpu_to_be16(reg); 73ca96ea86SBastien Nocera int ret; 74ca96ea86SBastien Nocera 75ca96ea86SBastien Nocera msgs[0].flags = 0; 76ca96ea86SBastien Nocera msgs[0].addr = client->addr; 77ca96ea86SBastien Nocera msgs[0].len = 2; 78ca96ea86SBastien Nocera msgs[0].buf = (u8 *) &wbuf; 79ca96ea86SBastien Nocera 80ca96ea86SBastien Nocera msgs[1].flags = I2C_M_RD; 81ca96ea86SBastien Nocera msgs[1].addr = client->addr; 82ca96ea86SBastien Nocera msgs[1].len = len; 83ca96ea86SBastien Nocera msgs[1].buf = buf; 84ca96ea86SBastien Nocera 85ca96ea86SBastien Nocera ret = i2c_transfer(client->adapter, msgs, 2); 86ca96ea86SBastien Nocera return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0); 87ca96ea86SBastien Nocera } 88ca96ea86SBastien Nocera 89ca96ea86SBastien Nocera static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) 90ca96ea86SBastien Nocera { 91ca96ea86SBastien Nocera int touch_num; 92ca96ea86SBastien Nocera int error; 93ca96ea86SBastien Nocera 94ca96ea86SBastien Nocera error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data, 95ca96ea86SBastien Nocera GOODIX_CONTACT_SIZE + 1); 96ca96ea86SBastien Nocera if (error) { 97ca96ea86SBastien Nocera dev_err(&ts->client->dev, "I2C transfer error: %d\n", error); 98ca96ea86SBastien Nocera return error; 99ca96ea86SBastien Nocera } 100ca96ea86SBastien Nocera 101ca96ea86SBastien Nocera touch_num = data[0] & 0x0f; 102ca96ea86SBastien Nocera if (touch_num > GOODIX_MAX_CONTACTS) 103ca96ea86SBastien Nocera return -EPROTO; 104ca96ea86SBastien Nocera 105ca96ea86SBastien Nocera if (touch_num > 1) { 106ca96ea86SBastien Nocera data += 1 + GOODIX_CONTACT_SIZE; 107ca96ea86SBastien Nocera error = goodix_i2c_read(ts->client, 108ca96ea86SBastien Nocera GOODIX_READ_COOR_ADDR + 109ca96ea86SBastien Nocera 1 + GOODIX_CONTACT_SIZE, 110ca96ea86SBastien Nocera data, 111ca96ea86SBastien Nocera GOODIX_CONTACT_SIZE * (touch_num - 1)); 112ca96ea86SBastien Nocera if (error) 113ca96ea86SBastien Nocera return error; 114ca96ea86SBastien Nocera } 115ca96ea86SBastien Nocera 116ca96ea86SBastien Nocera return touch_num; 117ca96ea86SBastien Nocera } 118ca96ea86SBastien Nocera 119ca96ea86SBastien Nocera static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) 120ca96ea86SBastien Nocera { 121ca96ea86SBastien Nocera int id = coor_data[0] & 0x0F; 122ca96ea86SBastien Nocera int input_x = get_unaligned_le16(&coor_data[1]); 123ca96ea86SBastien Nocera int input_y = get_unaligned_le16(&coor_data[3]); 124ca96ea86SBastien Nocera int input_w = get_unaligned_le16(&coor_data[5]); 125ca96ea86SBastien Nocera 126ca96ea86SBastien Nocera input_mt_slot(ts->input_dev, id); 127ca96ea86SBastien Nocera input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); 128ca96ea86SBastien Nocera input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x); 129ca96ea86SBastien Nocera input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y); 130ca96ea86SBastien Nocera input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); 131ca96ea86SBastien Nocera input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); 132ca96ea86SBastien Nocera } 133ca96ea86SBastien Nocera 134ca96ea86SBastien Nocera /** 135ca96ea86SBastien Nocera * goodix_process_events - Process incoming events 136ca96ea86SBastien Nocera * 137ca96ea86SBastien Nocera * @ts: our goodix_ts_data pointer 138ca96ea86SBastien Nocera * 139ca96ea86SBastien Nocera * Called when the IRQ is triggered. Read the current device state, and push 140ca96ea86SBastien Nocera * the input events to the user space. 141ca96ea86SBastien Nocera */ 142ca96ea86SBastien Nocera static void goodix_process_events(struct goodix_ts_data *ts) 143ca96ea86SBastien Nocera { 144ca96ea86SBastien Nocera u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; 145ca96ea86SBastien Nocera int touch_num; 146ca96ea86SBastien Nocera int i; 147ca96ea86SBastien Nocera 148ca96ea86SBastien Nocera touch_num = goodix_ts_read_input_report(ts, point_data); 149ca96ea86SBastien Nocera if (touch_num < 0) 150ca96ea86SBastien Nocera return; 151ca96ea86SBastien Nocera 152ca96ea86SBastien Nocera for (i = 0; i < touch_num; i++) 153ca96ea86SBastien Nocera goodix_ts_report_touch(ts, 154ca96ea86SBastien Nocera &point_data[1 + GOODIX_CONTACT_SIZE * i]); 155ca96ea86SBastien Nocera 156ca96ea86SBastien Nocera input_mt_sync_frame(ts->input_dev); 157ca96ea86SBastien Nocera input_sync(ts->input_dev); 158ca96ea86SBastien Nocera } 159ca96ea86SBastien Nocera 160ca96ea86SBastien Nocera /** 161ca96ea86SBastien Nocera * goodix_ts_irq_handler - The IRQ handler 162ca96ea86SBastien Nocera * 163ca96ea86SBastien Nocera * @irq: interrupt number. 164ca96ea86SBastien Nocera * @dev_id: private data pointer. 165ca96ea86SBastien Nocera */ 166ca96ea86SBastien Nocera static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id) 167ca96ea86SBastien Nocera { 168ca96ea86SBastien Nocera static const u8 end_cmd[] = { 169ca96ea86SBastien Nocera GOODIX_READ_COOR_ADDR >> 8, 170ca96ea86SBastien Nocera GOODIX_READ_COOR_ADDR & 0xff, 171ca96ea86SBastien Nocera 0 172ca96ea86SBastien Nocera }; 173ca96ea86SBastien Nocera struct goodix_ts_data *ts = dev_id; 174ca96ea86SBastien Nocera 175ca96ea86SBastien Nocera goodix_process_events(ts); 176ca96ea86SBastien Nocera 177ca96ea86SBastien Nocera if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0) 178ca96ea86SBastien Nocera dev_err(&ts->client->dev, "I2C write end_cmd error\n"); 179ca96ea86SBastien Nocera 180ca96ea86SBastien Nocera return IRQ_HANDLED; 181ca96ea86SBastien Nocera } 182ca96ea86SBastien Nocera 183ca96ea86SBastien Nocera /** 184ca96ea86SBastien Nocera * goodix_read_config - Read the embedded configuration of the panel 185ca96ea86SBastien Nocera * 186ca96ea86SBastien Nocera * @ts: our goodix_ts_data pointer 187ca96ea86SBastien Nocera * 188ca96ea86SBastien Nocera * Must be called during probe 189ca96ea86SBastien Nocera */ 190ca96ea86SBastien Nocera static void goodix_read_config(struct goodix_ts_data *ts) 191ca96ea86SBastien Nocera { 192ca96ea86SBastien Nocera u8 config[GOODIX_CONFIG_MAX_LENGTH]; 193ca96ea86SBastien Nocera int error; 194ca96ea86SBastien Nocera 195ca96ea86SBastien Nocera error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA, 196ca96ea86SBastien Nocera config, 197ca96ea86SBastien Nocera GOODIX_CONFIG_MAX_LENGTH); 198ca96ea86SBastien Nocera if (error) { 199ca96ea86SBastien Nocera dev_warn(&ts->client->dev, 200ca96ea86SBastien Nocera "Error reading config (%d), using defaults\n", 201ca96ea86SBastien Nocera error); 202ca96ea86SBastien Nocera ts->abs_x_max = GOODIX_MAX_WIDTH; 203ca96ea86SBastien Nocera ts->abs_y_max = GOODIX_MAX_HEIGHT; 204ca96ea86SBastien Nocera ts->int_trigger_type = GOODIX_INT_TRIGGER; 205ca96ea86SBastien Nocera return; 206ca96ea86SBastien Nocera } 207ca96ea86SBastien Nocera 208ca96ea86SBastien Nocera ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]); 209ca96ea86SBastien Nocera ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]); 210ca96ea86SBastien Nocera ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; 211ca96ea86SBastien Nocera if (!ts->abs_x_max || !ts->abs_y_max) { 212ca96ea86SBastien Nocera dev_err(&ts->client->dev, 213ca96ea86SBastien Nocera "Invalid config, using defaults\n"); 214ca96ea86SBastien Nocera ts->abs_x_max = GOODIX_MAX_WIDTH; 215ca96ea86SBastien Nocera ts->abs_y_max = GOODIX_MAX_HEIGHT; 216ca96ea86SBastien Nocera } 217ca96ea86SBastien Nocera } 218ca96ea86SBastien Nocera 219ca96ea86SBastien Nocera 220ca96ea86SBastien Nocera /** 221ca96ea86SBastien Nocera * goodix_read_version - Read goodix touchscreen version 222ca96ea86SBastien Nocera * 223ca96ea86SBastien Nocera * @client: the i2c client 224ca96ea86SBastien Nocera * @version: output buffer containing the version on success 225ca96ea86SBastien Nocera */ 226ca96ea86SBastien Nocera static int goodix_read_version(struct i2c_client *client, u16 *version) 227ca96ea86SBastien Nocera { 228ca96ea86SBastien Nocera int error; 229ca96ea86SBastien Nocera u8 buf[6]; 230ca96ea86SBastien Nocera 231ca96ea86SBastien Nocera error = goodix_i2c_read(client, GOODIX_REG_VERSION, buf, sizeof(buf)); 232ca96ea86SBastien Nocera if (error) { 233ca96ea86SBastien Nocera dev_err(&client->dev, "read version failed: %d\n", error); 234ca96ea86SBastien Nocera return error; 235ca96ea86SBastien Nocera } 236ca96ea86SBastien Nocera 237ca96ea86SBastien Nocera if (version) 238ca96ea86SBastien Nocera *version = get_unaligned_le16(&buf[4]); 239ca96ea86SBastien Nocera 240ca96ea86SBastien Nocera dev_info(&client->dev, "IC VERSION: %6ph\n", buf); 241ca96ea86SBastien Nocera 242ca96ea86SBastien Nocera return 0; 243ca96ea86SBastien Nocera } 244ca96ea86SBastien Nocera 245ca96ea86SBastien Nocera /** 246ca96ea86SBastien Nocera * goodix_i2c_test - I2C test function to check if the device answers. 247ca96ea86SBastien Nocera * 248ca96ea86SBastien Nocera * @client: the i2c client 249ca96ea86SBastien Nocera */ 250ca96ea86SBastien Nocera static int goodix_i2c_test(struct i2c_client *client) 251ca96ea86SBastien Nocera { 252ca96ea86SBastien Nocera int retry = 0; 253ca96ea86SBastien Nocera int error; 254ca96ea86SBastien Nocera u8 test; 255ca96ea86SBastien Nocera 256ca96ea86SBastien Nocera while (retry++ < 2) { 257ca96ea86SBastien Nocera error = goodix_i2c_read(client, GOODIX_REG_CONFIG_DATA, 258ca96ea86SBastien Nocera &test, 1); 259ca96ea86SBastien Nocera if (!error) 260ca96ea86SBastien Nocera return 0; 261ca96ea86SBastien Nocera 262ca96ea86SBastien Nocera dev_err(&client->dev, "i2c test failed attempt %d: %d\n", 263ca96ea86SBastien Nocera retry, error); 264ca96ea86SBastien Nocera msleep(20); 265ca96ea86SBastien Nocera } 266ca96ea86SBastien Nocera 267ca96ea86SBastien Nocera return error; 268ca96ea86SBastien Nocera } 269ca96ea86SBastien Nocera 270ca96ea86SBastien Nocera /** 271ca96ea86SBastien Nocera * goodix_request_input_dev - Allocate, populate and register the input device 272ca96ea86SBastien Nocera * 273ca96ea86SBastien Nocera * @ts: our goodix_ts_data pointer 274ca96ea86SBastien Nocera * 275ca96ea86SBastien Nocera * Must be called during probe 276ca96ea86SBastien Nocera */ 277ca96ea86SBastien Nocera static int goodix_request_input_dev(struct goodix_ts_data *ts) 278ca96ea86SBastien Nocera { 279ca96ea86SBastien Nocera int error; 280ca96ea86SBastien Nocera 281ca96ea86SBastien Nocera ts->input_dev = devm_input_allocate_device(&ts->client->dev); 282ca96ea86SBastien Nocera if (!ts->input_dev) { 283ca96ea86SBastien Nocera dev_err(&ts->client->dev, "Failed to allocate input device."); 284ca96ea86SBastien Nocera return -ENOMEM; 285ca96ea86SBastien Nocera } 286ca96ea86SBastien Nocera 287ca96ea86SBastien Nocera ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | 288ca96ea86SBastien Nocera BIT_MASK(EV_KEY) | 289ca96ea86SBastien Nocera BIT_MASK(EV_ABS); 290ca96ea86SBastien Nocera 291ca96ea86SBastien Nocera input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, 292ca96ea86SBastien Nocera ts->abs_x_max, 0, 0); 293ca96ea86SBastien Nocera input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, 294ca96ea86SBastien Nocera ts->abs_y_max, 0, 0); 295ca96ea86SBastien Nocera input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); 296ca96ea86SBastien Nocera input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); 297ca96ea86SBastien Nocera 298ca96ea86SBastien Nocera input_mt_init_slots(ts->input_dev, GOODIX_MAX_CONTACTS, 299ca96ea86SBastien Nocera INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 300ca96ea86SBastien Nocera 301ca96ea86SBastien Nocera ts->input_dev->name = "Goodix Capacitive TouchScreen"; 302ca96ea86SBastien Nocera ts->input_dev->phys = "input/ts"; 303ca96ea86SBastien Nocera ts->input_dev->id.bustype = BUS_I2C; 304ca96ea86SBastien Nocera ts->input_dev->id.vendor = 0x0416; 305ca96ea86SBastien Nocera ts->input_dev->id.product = 0x1001; 306ca96ea86SBastien Nocera ts->input_dev->id.version = 10427; 307ca96ea86SBastien Nocera 308ca96ea86SBastien Nocera error = input_register_device(ts->input_dev); 309ca96ea86SBastien Nocera if (error) { 310ca96ea86SBastien Nocera dev_err(&ts->client->dev, 311ca96ea86SBastien Nocera "Failed to register input device: %d", error); 312ca96ea86SBastien Nocera return error; 313ca96ea86SBastien Nocera } 314ca96ea86SBastien Nocera 315ca96ea86SBastien Nocera return 0; 316ca96ea86SBastien Nocera } 317ca96ea86SBastien Nocera 318ca96ea86SBastien Nocera static int goodix_ts_probe(struct i2c_client *client, 319ca96ea86SBastien Nocera const struct i2c_device_id *id) 320ca96ea86SBastien Nocera { 321ca96ea86SBastien Nocera struct goodix_ts_data *ts; 322ca96ea86SBastien Nocera unsigned long irq_flags; 323ca96ea86SBastien Nocera int error; 324ca96ea86SBastien Nocera u16 version_info; 325ca96ea86SBastien Nocera 326ca96ea86SBastien Nocera dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr); 327ca96ea86SBastien Nocera 328ca96ea86SBastien Nocera if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 329ca96ea86SBastien Nocera dev_err(&client->dev, "I2C check functionality failed.\n"); 330ca96ea86SBastien Nocera return -ENXIO; 331ca96ea86SBastien Nocera } 332ca96ea86SBastien Nocera 333ca96ea86SBastien Nocera ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); 334ca96ea86SBastien Nocera if (!ts) 335ca96ea86SBastien Nocera return -ENOMEM; 336ca96ea86SBastien Nocera 337ca96ea86SBastien Nocera ts->client = client; 338ca96ea86SBastien Nocera i2c_set_clientdata(client, ts); 339ca96ea86SBastien Nocera 340ca96ea86SBastien Nocera error = goodix_i2c_test(client); 341ca96ea86SBastien Nocera if (error) { 342ca96ea86SBastien Nocera dev_err(&client->dev, "I2C communication failure: %d\n", error); 343ca96ea86SBastien Nocera return error; 344ca96ea86SBastien Nocera } 345ca96ea86SBastien Nocera 346ca96ea86SBastien Nocera error = goodix_read_version(client, &version_info); 347ca96ea86SBastien Nocera if (error) { 348ca96ea86SBastien Nocera dev_err(&client->dev, "Read version failed.\n"); 349ca96ea86SBastien Nocera return error; 350ca96ea86SBastien Nocera } 351ca96ea86SBastien Nocera 352ca96ea86SBastien Nocera goodix_read_config(ts); 353ca96ea86SBastien Nocera 354ca96ea86SBastien Nocera error = goodix_request_input_dev(ts); 355ca96ea86SBastien Nocera if (error) 356ca96ea86SBastien Nocera return error; 357ca96ea86SBastien Nocera 358ca96ea86SBastien Nocera irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; 359ca96ea86SBastien Nocera error = devm_request_threaded_irq(&ts->client->dev, client->irq, 360ca96ea86SBastien Nocera NULL, goodix_ts_irq_handler, 361ca96ea86SBastien Nocera irq_flags, client->name, ts); 362ca96ea86SBastien Nocera if (error) { 363ca96ea86SBastien Nocera dev_err(&client->dev, "request IRQ failed: %d\n", error); 364ca96ea86SBastien Nocera return error; 365ca96ea86SBastien Nocera } 366ca96ea86SBastien Nocera 367ca96ea86SBastien Nocera return 0; 368ca96ea86SBastien Nocera } 369ca96ea86SBastien Nocera 370ca96ea86SBastien Nocera static const struct i2c_device_id goodix_ts_id[] = { 371ca96ea86SBastien Nocera { "GDIX1001:00", 0 }, 372ca96ea86SBastien Nocera { } 373ca96ea86SBastien Nocera }; 374ca96ea86SBastien Nocera 375ca96ea86SBastien Nocera static const struct acpi_device_id goodix_acpi_match[] = { 376ca96ea86SBastien Nocera { "GDIX1001", 0 }, 377ca96ea86SBastien Nocera { } 378ca96ea86SBastien Nocera }; 379ca96ea86SBastien Nocera MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); 380ca96ea86SBastien Nocera 381ca96ea86SBastien Nocera static struct i2c_driver goodix_ts_driver = { 382ca96ea86SBastien Nocera .probe = goodix_ts_probe, 383ca96ea86SBastien Nocera .id_table = goodix_ts_id, 384ca96ea86SBastien Nocera .driver = { 385ca96ea86SBastien Nocera .name = "Goodix-TS", 386ca96ea86SBastien Nocera .owner = THIS_MODULE, 387ca96ea86SBastien Nocera .acpi_match_table = goodix_acpi_match, 388ca96ea86SBastien Nocera }, 389ca96ea86SBastien Nocera }; 390ca96ea86SBastien Nocera module_i2c_driver(goodix_ts_driver); 391ca96ea86SBastien Nocera 392ca96ea86SBastien Nocera MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); 393ca96ea86SBastien Nocera MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>"); 394ca96ea86SBastien Nocera MODULE_DESCRIPTION("Goodix touchscreen driver"); 395ca96ea86SBastien Nocera MODULE_LICENSE("GPL v2"); 396