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>
188b5a359cSBastien Nocera #include <linux/dmi.h>
1968caf858SIrina Tirdea #include <linux/firmware.h>
20ec6e1b40SIrina Tirdea #include <linux/gpio/consumer.h>
21ca96ea86SBastien Nocera #include <linux/i2c.h>
22ca96ea86SBastien Nocera #include <linux/input.h>
23ca96ea86SBastien Nocera #include <linux/input/mt.h>
24ca96ea86SBastien Nocera #include <linux/module.h>
25ca96ea86SBastien Nocera #include <linux/delay.h>
26ca96ea86SBastien Nocera #include <linux/irq.h>
27ca96ea86SBastien Nocera #include <linux/interrupt.h>
28ca96ea86SBastien Nocera #include <linux/slab.h>
29771d8f1bSAleksei Mamlin #include <linux/acpi.h>
30771d8f1bSAleksei Mamlin #include <linux/of.h>
31ca96ea86SBastien Nocera #include <asm/unaligned.h>
32ca96ea86SBastien Nocera 
33ca96ea86SBastien Nocera struct goodix_ts_data {
34ca96ea86SBastien Nocera 	struct i2c_client *client;
35ca96ea86SBastien Nocera 	struct input_dev *input_dev;
36ca96ea86SBastien Nocera 	int abs_x_max;
37ca96ea86SBastien Nocera 	int abs_y_max;
38ca96ea86SBastien Nocera 	unsigned int max_touch_num;
39ca96ea86SBastien Nocera 	unsigned int int_trigger_type;
408b5a359cSBastien Nocera 	bool rotated_screen;
41a779fbc6SIrina Tirdea 	int cfg_len;
42ec6e1b40SIrina Tirdea 	struct gpio_desc *gpiod_int;
43ec6e1b40SIrina Tirdea 	struct gpio_desc *gpiod_rst;
4468caf858SIrina Tirdea 	u16 id;
4568caf858SIrina Tirdea 	u16 version;
4668caf858SIrina Tirdea 	const char *cfg_name;
4768caf858SIrina Tirdea 	struct completion firmware_loading_complete;
48ca96ea86SBastien Nocera };
49ca96ea86SBastien Nocera 
50ec6e1b40SIrina Tirdea #define GOODIX_GPIO_INT_NAME		"irq"
51ec6e1b40SIrina Tirdea #define GOODIX_GPIO_RST_NAME		"reset"
52ec6e1b40SIrina Tirdea 
53ca96ea86SBastien Nocera #define GOODIX_MAX_HEIGHT		4096
54ca96ea86SBastien Nocera #define GOODIX_MAX_WIDTH		4096
55ca96ea86SBastien Nocera #define GOODIX_INT_TRIGGER		1
56ca96ea86SBastien Nocera #define GOODIX_CONTACT_SIZE		8
57ca96ea86SBastien Nocera #define GOODIX_MAX_CONTACTS		10
58ca96ea86SBastien Nocera 
59ca96ea86SBastien Nocera #define GOODIX_CONFIG_MAX_LENGTH	240
60a779fbc6SIrina Tirdea #define GOODIX_CONFIG_911_LENGTH	186
61a779fbc6SIrina Tirdea #define GOODIX_CONFIG_967_LENGTH	228
62ca96ea86SBastien Nocera 
63ca96ea86SBastien Nocera /* Register defines */
64ca96ea86SBastien Nocera #define GOODIX_READ_COOR_ADDR		0x814E
65ca96ea86SBastien Nocera #define GOODIX_REG_CONFIG_DATA		0x8047
66e70b0307SIrina Tirdea #define GOODIX_REG_ID			0x8140
67ca96ea86SBastien Nocera 
68ca96ea86SBastien Nocera #define RESOLUTION_LOC		1
69a7ac7c95SAleksei Mamlin #define MAX_CONTACTS_LOC	5
70ca96ea86SBastien Nocera #define TRIGGER_LOC		6
71ca96ea86SBastien Nocera 
72ca96ea86SBastien Nocera static const unsigned long goodix_irq_flags[] = {
73ca96ea86SBastien Nocera 	IRQ_TYPE_EDGE_RISING,
74ca96ea86SBastien Nocera 	IRQ_TYPE_EDGE_FALLING,
75ca96ea86SBastien Nocera 	IRQ_TYPE_LEVEL_LOW,
76ca96ea86SBastien Nocera 	IRQ_TYPE_LEVEL_HIGH,
77ca96ea86SBastien Nocera };
78ca96ea86SBastien Nocera 
798b5a359cSBastien Nocera /*
808b5a359cSBastien Nocera  * Those tablets have their coordinates origin at the bottom right
818b5a359cSBastien Nocera  * of the tablet, as if rotated 180 degrees
828b5a359cSBastien Nocera  */
838b5a359cSBastien Nocera static const struct dmi_system_id rotated_screen[] = {
848b5a359cSBastien Nocera #if defined(CONFIG_DMI) && defined(CONFIG_X86)
858b5a359cSBastien Nocera 	{
868b5a359cSBastien Nocera 		.ident = "WinBook TW100",
878b5a359cSBastien Nocera 		.matches = {
888b5a359cSBastien Nocera 			DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
898b5a359cSBastien Nocera 			DMI_MATCH(DMI_PRODUCT_NAME, "TW100")
908b5a359cSBastien Nocera 		}
918b5a359cSBastien Nocera 	},
928b5a359cSBastien Nocera 	{
938b5a359cSBastien Nocera 		.ident = "WinBook TW700",
948b5a359cSBastien Nocera 		.matches = {
958b5a359cSBastien Nocera 			DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
968b5a359cSBastien Nocera 			DMI_MATCH(DMI_PRODUCT_NAME, "TW700")
978b5a359cSBastien Nocera 		},
988b5a359cSBastien Nocera 	},
998b5a359cSBastien Nocera #endif
1008b5a359cSBastien Nocera 	{}
1018b5a359cSBastien Nocera };
1028b5a359cSBastien Nocera 
103ca96ea86SBastien Nocera /**
104ca96ea86SBastien Nocera  * goodix_i2c_read - read data from a register of the i2c slave device.
105ca96ea86SBastien Nocera  *
106ca96ea86SBastien Nocera  * @client: i2c device.
107ca96ea86SBastien Nocera  * @reg: the register to read from.
108ca96ea86SBastien Nocera  * @buf: raw write data buffer.
109ca96ea86SBastien Nocera  * @len: length of the buffer to write
110ca96ea86SBastien Nocera  */
111ca96ea86SBastien Nocera static int goodix_i2c_read(struct i2c_client *client,
112ca96ea86SBastien Nocera 			   u16 reg, u8 *buf, int len)
113ca96ea86SBastien Nocera {
114ca96ea86SBastien Nocera 	struct i2c_msg msgs[2];
115ca96ea86SBastien Nocera 	u16 wbuf = cpu_to_be16(reg);
116ca96ea86SBastien Nocera 	int ret;
117ca96ea86SBastien Nocera 
118ca96ea86SBastien Nocera 	msgs[0].flags = 0;
119ca96ea86SBastien Nocera 	msgs[0].addr  = client->addr;
120ca96ea86SBastien Nocera 	msgs[0].len   = 2;
121ca96ea86SBastien Nocera 	msgs[0].buf   = (u8 *)&wbuf;
122ca96ea86SBastien Nocera 
123ca96ea86SBastien Nocera 	msgs[1].flags = I2C_M_RD;
124ca96ea86SBastien Nocera 	msgs[1].addr  = client->addr;
125ca96ea86SBastien Nocera 	msgs[1].len   = len;
126ca96ea86SBastien Nocera 	msgs[1].buf   = buf;
127ca96ea86SBastien Nocera 
128ca96ea86SBastien Nocera 	ret = i2c_transfer(client->adapter, msgs, 2);
129ca96ea86SBastien Nocera 	return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
130ca96ea86SBastien Nocera }
131ca96ea86SBastien Nocera 
13268caf858SIrina Tirdea /**
13368caf858SIrina Tirdea  * goodix_i2c_write - write data to a register of the i2c slave device.
13468caf858SIrina Tirdea  *
13568caf858SIrina Tirdea  * @client: i2c device.
13668caf858SIrina Tirdea  * @reg: the register to write to.
13768caf858SIrina Tirdea  * @buf: raw data buffer to write.
13868caf858SIrina Tirdea  * @len: length of the buffer to write
13968caf858SIrina Tirdea  */
14068caf858SIrina Tirdea static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf,
14168caf858SIrina Tirdea 			    unsigned len)
14268caf858SIrina Tirdea {
14368caf858SIrina Tirdea 	u8 *addr_buf;
14468caf858SIrina Tirdea 	struct i2c_msg msg;
14568caf858SIrina Tirdea 	int ret;
14668caf858SIrina Tirdea 
14768caf858SIrina Tirdea 	addr_buf = kmalloc(len + 2, GFP_KERNEL);
14868caf858SIrina Tirdea 	if (!addr_buf)
14968caf858SIrina Tirdea 		return -ENOMEM;
15068caf858SIrina Tirdea 
15168caf858SIrina Tirdea 	addr_buf[0] = reg >> 8;
15268caf858SIrina Tirdea 	addr_buf[1] = reg & 0xFF;
15368caf858SIrina Tirdea 	memcpy(&addr_buf[2], buf, len);
15468caf858SIrina Tirdea 
15568caf858SIrina Tirdea 	msg.flags = 0;
15668caf858SIrina Tirdea 	msg.addr = client->addr;
15768caf858SIrina Tirdea 	msg.buf = addr_buf;
15868caf858SIrina Tirdea 	msg.len = len + 2;
15968caf858SIrina Tirdea 
16068caf858SIrina Tirdea 	ret = i2c_transfer(client->adapter, &msg, 1);
16168caf858SIrina Tirdea 	kfree(addr_buf);
16268caf858SIrina Tirdea 	return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
16368caf858SIrina Tirdea }
16468caf858SIrina Tirdea 
165a779fbc6SIrina Tirdea static int goodix_get_cfg_len(u16 id)
166a779fbc6SIrina Tirdea {
167a779fbc6SIrina Tirdea 	switch (id) {
168a779fbc6SIrina Tirdea 	case 911:
169a779fbc6SIrina Tirdea 	case 9271:
170a779fbc6SIrina Tirdea 	case 9110:
171a779fbc6SIrina Tirdea 	case 927:
172a779fbc6SIrina Tirdea 	case 928:
173a779fbc6SIrina Tirdea 		return GOODIX_CONFIG_911_LENGTH;
174a779fbc6SIrina Tirdea 
175a779fbc6SIrina Tirdea 	case 912:
176a779fbc6SIrina Tirdea 	case 967:
177a779fbc6SIrina Tirdea 		return GOODIX_CONFIG_967_LENGTH;
178a779fbc6SIrina Tirdea 
179a779fbc6SIrina Tirdea 	default:
180a779fbc6SIrina Tirdea 		return GOODIX_CONFIG_MAX_LENGTH;
181a779fbc6SIrina Tirdea 	}
182a779fbc6SIrina Tirdea }
183a779fbc6SIrina Tirdea 
184ca96ea86SBastien Nocera static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
185ca96ea86SBastien Nocera {
186ca96ea86SBastien Nocera 	int touch_num;
187ca96ea86SBastien Nocera 	int error;
188ca96ea86SBastien Nocera 
189ca96ea86SBastien Nocera 	error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data,
190ca96ea86SBastien Nocera 				GOODIX_CONTACT_SIZE + 1);
191ca96ea86SBastien Nocera 	if (error) {
192ca96ea86SBastien Nocera 		dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
193ca96ea86SBastien Nocera 		return error;
194ca96ea86SBastien Nocera 	}
195ca96ea86SBastien Nocera 
1965f6f117cSPaul Cercueil 	if (!(data[0] & 0x80))
1975f6f117cSPaul Cercueil 		return -EAGAIN;
1985f6f117cSPaul Cercueil 
199ca96ea86SBastien Nocera 	touch_num = data[0] & 0x0f;
200a7ac7c95SAleksei Mamlin 	if (touch_num > ts->max_touch_num)
201ca96ea86SBastien Nocera 		return -EPROTO;
202ca96ea86SBastien Nocera 
203ca96ea86SBastien Nocera 	if (touch_num > 1) {
204ca96ea86SBastien Nocera 		data += 1 + GOODIX_CONTACT_SIZE;
205ca96ea86SBastien Nocera 		error = goodix_i2c_read(ts->client,
206ca96ea86SBastien Nocera 					GOODIX_READ_COOR_ADDR +
207ca96ea86SBastien Nocera 						1 + GOODIX_CONTACT_SIZE,
208ca96ea86SBastien Nocera 					data,
209ca96ea86SBastien Nocera 					GOODIX_CONTACT_SIZE * (touch_num - 1));
210ca96ea86SBastien Nocera 		if (error)
211ca96ea86SBastien Nocera 			return error;
212ca96ea86SBastien Nocera 	}
213ca96ea86SBastien Nocera 
214ca96ea86SBastien Nocera 	return touch_num;
215ca96ea86SBastien Nocera }
216ca96ea86SBastien Nocera 
217ca96ea86SBastien Nocera static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
218ca96ea86SBastien Nocera {
219ca96ea86SBastien Nocera 	int id = coor_data[0] & 0x0F;
220ca96ea86SBastien Nocera 	int input_x = get_unaligned_le16(&coor_data[1]);
221ca96ea86SBastien Nocera 	int input_y = get_unaligned_le16(&coor_data[3]);
222ca96ea86SBastien Nocera 	int input_w = get_unaligned_le16(&coor_data[5]);
223ca96ea86SBastien Nocera 
2248b5a359cSBastien Nocera 	if (ts->rotated_screen) {
2258b5a359cSBastien Nocera 		input_x = ts->abs_x_max - input_x;
2268b5a359cSBastien Nocera 		input_y = ts->abs_y_max - input_y;
2278b5a359cSBastien Nocera 	}
2288b5a359cSBastien Nocera 
229ca96ea86SBastien Nocera 	input_mt_slot(ts->input_dev, id);
230ca96ea86SBastien Nocera 	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
231ca96ea86SBastien Nocera 	input_report_abs(ts->input_dev, ABS_MT_POSITION_X, input_x);
232ca96ea86SBastien Nocera 	input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, input_y);
233ca96ea86SBastien Nocera 	input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
234ca96ea86SBastien Nocera 	input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
235ca96ea86SBastien Nocera }
236ca96ea86SBastien Nocera 
237ca96ea86SBastien Nocera /**
238ca96ea86SBastien Nocera  * goodix_process_events - Process incoming events
239ca96ea86SBastien Nocera  *
240ca96ea86SBastien Nocera  * @ts: our goodix_ts_data pointer
241ca96ea86SBastien Nocera  *
242ca96ea86SBastien Nocera  * Called when the IRQ is triggered. Read the current device state, and push
243ca96ea86SBastien Nocera  * the input events to the user space.
244ca96ea86SBastien Nocera  */
245ca96ea86SBastien Nocera static void goodix_process_events(struct goodix_ts_data *ts)
246ca96ea86SBastien Nocera {
2470e0432f0SIrina Tirdea 	u8  point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
248ca96ea86SBastien Nocera 	int touch_num;
249ca96ea86SBastien Nocera 	int i;
250ca96ea86SBastien Nocera 
251ca96ea86SBastien Nocera 	touch_num = goodix_ts_read_input_report(ts, point_data);
252ca96ea86SBastien Nocera 	if (touch_num < 0)
253ca96ea86SBastien Nocera 		return;
254ca96ea86SBastien Nocera 
255ca96ea86SBastien Nocera 	for (i = 0; i < touch_num; i++)
256ca96ea86SBastien Nocera 		goodix_ts_report_touch(ts,
257ca96ea86SBastien Nocera 				&point_data[1 + GOODIX_CONTACT_SIZE * i]);
258ca96ea86SBastien Nocera 
259ca96ea86SBastien Nocera 	input_mt_sync_frame(ts->input_dev);
260ca96ea86SBastien Nocera 	input_sync(ts->input_dev);
261ca96ea86SBastien Nocera }
262ca96ea86SBastien Nocera 
263ca96ea86SBastien Nocera /**
264ca96ea86SBastien Nocera  * goodix_ts_irq_handler - The IRQ handler
265ca96ea86SBastien Nocera  *
266ca96ea86SBastien Nocera  * @irq: interrupt number.
267ca96ea86SBastien Nocera  * @dev_id: private data pointer.
268ca96ea86SBastien Nocera  */
269ca96ea86SBastien Nocera static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
270ca96ea86SBastien Nocera {
271ca96ea86SBastien Nocera 	static const u8 end_cmd[] = {
272ca96ea86SBastien Nocera 		GOODIX_READ_COOR_ADDR >> 8,
273ca96ea86SBastien Nocera 		GOODIX_READ_COOR_ADDR & 0xff,
274ca96ea86SBastien Nocera 		0
275ca96ea86SBastien Nocera 	};
276ca96ea86SBastien Nocera 	struct goodix_ts_data *ts = dev_id;
277ca96ea86SBastien Nocera 
278ca96ea86SBastien Nocera 	goodix_process_events(ts);
279ca96ea86SBastien Nocera 
280ca96ea86SBastien Nocera 	if (i2c_master_send(ts->client, end_cmd, sizeof(end_cmd)) < 0)
281ca96ea86SBastien Nocera 		dev_err(&ts->client->dev, "I2C write end_cmd error\n");
282ca96ea86SBastien Nocera 
283ca96ea86SBastien Nocera 	return IRQ_HANDLED;
284ca96ea86SBastien Nocera }
285ca96ea86SBastien Nocera 
28668caf858SIrina Tirdea /**
28768caf858SIrina Tirdea  * goodix_check_cfg - Checks if config fw is valid
28868caf858SIrina Tirdea  *
28968caf858SIrina Tirdea  * @ts: goodix_ts_data pointer
29068caf858SIrina Tirdea  * @cfg: firmware config data
29168caf858SIrina Tirdea  */
29268caf858SIrina Tirdea static int goodix_check_cfg(struct goodix_ts_data *ts,
29368caf858SIrina Tirdea 			    const struct firmware *cfg)
29468caf858SIrina Tirdea {
29568caf858SIrina Tirdea 	int i, raw_cfg_len;
29668caf858SIrina Tirdea 	u8 check_sum = 0;
29768caf858SIrina Tirdea 
29868caf858SIrina Tirdea 	if (cfg->size > GOODIX_CONFIG_MAX_LENGTH) {
29968caf858SIrina Tirdea 		dev_err(&ts->client->dev,
30068caf858SIrina Tirdea 			"The length of the config fw is not correct");
30168caf858SIrina Tirdea 		return -EINVAL;
30268caf858SIrina Tirdea 	}
30368caf858SIrina Tirdea 
30468caf858SIrina Tirdea 	raw_cfg_len = cfg->size - 2;
30568caf858SIrina Tirdea 	for (i = 0; i < raw_cfg_len; i++)
30668caf858SIrina Tirdea 		check_sum += cfg->data[i];
30768caf858SIrina Tirdea 	check_sum = (~check_sum) + 1;
30868caf858SIrina Tirdea 	if (check_sum != cfg->data[raw_cfg_len]) {
30968caf858SIrina Tirdea 		dev_err(&ts->client->dev,
31068caf858SIrina Tirdea 			"The checksum of the config fw is not correct");
31168caf858SIrina Tirdea 		return -EINVAL;
31268caf858SIrina Tirdea 	}
31368caf858SIrina Tirdea 
31468caf858SIrina Tirdea 	if (cfg->data[raw_cfg_len + 1] != 1) {
31568caf858SIrina Tirdea 		dev_err(&ts->client->dev,
31668caf858SIrina Tirdea 			"Config fw must have Config_Fresh register set");
31768caf858SIrina Tirdea 		return -EINVAL;
31868caf858SIrina Tirdea 	}
31968caf858SIrina Tirdea 
32068caf858SIrina Tirdea 	return 0;
32168caf858SIrina Tirdea }
32268caf858SIrina Tirdea 
32368caf858SIrina Tirdea /**
32468caf858SIrina Tirdea  * goodix_send_cfg - Write fw config to device
32568caf858SIrina Tirdea  *
32668caf858SIrina Tirdea  * @ts: goodix_ts_data pointer
32768caf858SIrina Tirdea  * @cfg: config firmware to write to device
32868caf858SIrina Tirdea  */
32968caf858SIrina Tirdea static int goodix_send_cfg(struct goodix_ts_data *ts,
33068caf858SIrina Tirdea 			   const struct firmware *cfg)
33168caf858SIrina Tirdea {
33268caf858SIrina Tirdea 	int error;
33368caf858SIrina Tirdea 
33468caf858SIrina Tirdea 	error = goodix_check_cfg(ts, cfg);
33568caf858SIrina Tirdea 	if (error)
33668caf858SIrina Tirdea 		return error;
33768caf858SIrina Tirdea 
33868caf858SIrina Tirdea 	error = goodix_i2c_write(ts->client, GOODIX_REG_CONFIG_DATA, cfg->data,
33968caf858SIrina Tirdea 				 cfg->size);
34068caf858SIrina Tirdea 	if (error) {
34168caf858SIrina Tirdea 		dev_err(&ts->client->dev, "Failed to write config data: %d",
34268caf858SIrina Tirdea 			error);
34368caf858SIrina Tirdea 		return error;
34468caf858SIrina Tirdea 	}
34568caf858SIrina Tirdea 	dev_dbg(&ts->client->dev, "Config sent successfully.");
34668caf858SIrina Tirdea 
34768caf858SIrina Tirdea 	/* Let the firmware reconfigure itself, so sleep for 10ms */
34868caf858SIrina Tirdea 	usleep_range(10000, 11000);
34968caf858SIrina Tirdea 
35068caf858SIrina Tirdea 	return 0;
35168caf858SIrina Tirdea }
35268caf858SIrina Tirdea 
353ec6e1b40SIrina Tirdea static int goodix_int_sync(struct goodix_ts_data *ts)
354ec6e1b40SIrina Tirdea {
355ec6e1b40SIrina Tirdea 	int error;
356ec6e1b40SIrina Tirdea 
357ec6e1b40SIrina Tirdea 	error = gpiod_direction_output(ts->gpiod_int, 0);
358ec6e1b40SIrina Tirdea 	if (error)
359ec6e1b40SIrina Tirdea 		return error;
360ec6e1b40SIrina Tirdea 
361ec6e1b40SIrina Tirdea 	msleep(50);				/* T5: 50ms */
362ec6e1b40SIrina Tirdea 
363ec6e1b40SIrina Tirdea 	error = gpiod_direction_input(ts->gpiod_int);
364ec6e1b40SIrina Tirdea 	if (error)
365ec6e1b40SIrina Tirdea 		return error;
366ec6e1b40SIrina Tirdea 
367ec6e1b40SIrina Tirdea 	return 0;
368ec6e1b40SIrina Tirdea }
369ec6e1b40SIrina Tirdea 
370ec6e1b40SIrina Tirdea /**
371ec6e1b40SIrina Tirdea  * goodix_reset - Reset device during power on
372ec6e1b40SIrina Tirdea  *
373ec6e1b40SIrina Tirdea  * @ts: goodix_ts_data pointer
374ec6e1b40SIrina Tirdea  */
375ec6e1b40SIrina Tirdea static int goodix_reset(struct goodix_ts_data *ts)
376ec6e1b40SIrina Tirdea {
377ec6e1b40SIrina Tirdea 	int error;
378ec6e1b40SIrina Tirdea 
379ec6e1b40SIrina Tirdea 	/* begin select I2C slave addr */
380ec6e1b40SIrina Tirdea 	error = gpiod_direction_output(ts->gpiod_rst, 0);
381ec6e1b40SIrina Tirdea 	if (error)
382ec6e1b40SIrina Tirdea 		return error;
383ec6e1b40SIrina Tirdea 
384ec6e1b40SIrina Tirdea 	msleep(20);				/* T2: > 10ms */
385ec6e1b40SIrina Tirdea 
386ec6e1b40SIrina Tirdea 	/* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
387ec6e1b40SIrina Tirdea 	error = gpiod_direction_output(ts->gpiod_int, ts->client->addr == 0x14);
388ec6e1b40SIrina Tirdea 	if (error)
389ec6e1b40SIrina Tirdea 		return error;
390ec6e1b40SIrina Tirdea 
391ec6e1b40SIrina Tirdea 	usleep_range(100, 2000);		/* T3: > 100us */
392ec6e1b40SIrina Tirdea 
393ec6e1b40SIrina Tirdea 	error = gpiod_direction_output(ts->gpiod_rst, 1);
394ec6e1b40SIrina Tirdea 	if (error)
395ec6e1b40SIrina Tirdea 		return error;
396ec6e1b40SIrina Tirdea 
397ec6e1b40SIrina Tirdea 	usleep_range(6000, 10000);		/* T4: > 5ms */
398ec6e1b40SIrina Tirdea 
399ec6e1b40SIrina Tirdea 	/* end select I2C slave addr */
400ec6e1b40SIrina Tirdea 	error = gpiod_direction_input(ts->gpiod_rst);
401ec6e1b40SIrina Tirdea 	if (error)
402ec6e1b40SIrina Tirdea 		return error;
403ec6e1b40SIrina Tirdea 
404ec6e1b40SIrina Tirdea 	error = goodix_int_sync(ts);
405ec6e1b40SIrina Tirdea 	if (error)
406ec6e1b40SIrina Tirdea 		return error;
407ec6e1b40SIrina Tirdea 
408ec6e1b40SIrina Tirdea 	return 0;
409ec6e1b40SIrina Tirdea }
410ec6e1b40SIrina Tirdea 
411ec6e1b40SIrina Tirdea /**
412ec6e1b40SIrina Tirdea  * goodix_get_gpio_config - Get GPIO config from ACPI/DT
413ec6e1b40SIrina Tirdea  *
414ec6e1b40SIrina Tirdea  * @ts: goodix_ts_data pointer
415ec6e1b40SIrina Tirdea  */
416ec6e1b40SIrina Tirdea static int goodix_get_gpio_config(struct goodix_ts_data *ts)
417ec6e1b40SIrina Tirdea {
418ec6e1b40SIrina Tirdea 	int error;
419ec6e1b40SIrina Tirdea 	struct device *dev;
420ec6e1b40SIrina Tirdea 	struct gpio_desc *gpiod;
421ec6e1b40SIrina Tirdea 
422ec6e1b40SIrina Tirdea 	if (!ts->client)
423ec6e1b40SIrina Tirdea 		return -EINVAL;
424ec6e1b40SIrina Tirdea 	dev = &ts->client->dev;
425ec6e1b40SIrina Tirdea 
426ec6e1b40SIrina Tirdea 	/* Get the interrupt GPIO pin number */
427ec6e1b40SIrina Tirdea 	gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN);
428ec6e1b40SIrina Tirdea 	if (IS_ERR(gpiod)) {
429ec6e1b40SIrina Tirdea 		error = PTR_ERR(gpiod);
430ec6e1b40SIrina Tirdea 		if (error != -EPROBE_DEFER)
431ec6e1b40SIrina Tirdea 			dev_dbg(dev, "Failed to get %s GPIO: %d\n",
432ec6e1b40SIrina Tirdea 				GOODIX_GPIO_INT_NAME, error);
433ec6e1b40SIrina Tirdea 		return error;
434ec6e1b40SIrina Tirdea 	}
435ec6e1b40SIrina Tirdea 
436ec6e1b40SIrina Tirdea 	ts->gpiod_int = gpiod;
437ec6e1b40SIrina Tirdea 
438ec6e1b40SIrina Tirdea 	/* Get the reset line GPIO pin number */
439ec6e1b40SIrina Tirdea 	gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, GPIOD_IN);
440ec6e1b40SIrina Tirdea 	if (IS_ERR(gpiod)) {
441ec6e1b40SIrina Tirdea 		error = PTR_ERR(gpiod);
442ec6e1b40SIrina Tirdea 		if (error != -EPROBE_DEFER)
443ec6e1b40SIrina Tirdea 			dev_dbg(dev, "Failed to get %s GPIO: %d\n",
444ec6e1b40SIrina Tirdea 				GOODIX_GPIO_RST_NAME, error);
445ec6e1b40SIrina Tirdea 		return error;
446ec6e1b40SIrina Tirdea 	}
447ec6e1b40SIrina Tirdea 
448ec6e1b40SIrina Tirdea 	ts->gpiod_rst = gpiod;
449ec6e1b40SIrina Tirdea 
450ec6e1b40SIrina Tirdea 	return 0;
451ec6e1b40SIrina Tirdea }
452ec6e1b40SIrina Tirdea 
453ca96ea86SBastien Nocera /**
454ca96ea86SBastien Nocera  * goodix_read_config - Read the embedded configuration of the panel
455ca96ea86SBastien Nocera  *
456ca96ea86SBastien Nocera  * @ts: our goodix_ts_data pointer
457ca96ea86SBastien Nocera  *
458ca96ea86SBastien Nocera  * Must be called during probe
459ca96ea86SBastien Nocera  */
460ca96ea86SBastien Nocera static void goodix_read_config(struct goodix_ts_data *ts)
461ca96ea86SBastien Nocera {
462ca96ea86SBastien Nocera 	u8 config[GOODIX_CONFIG_MAX_LENGTH];
463ca96ea86SBastien Nocera 	int error;
464ca96ea86SBastien Nocera 
465ca96ea86SBastien Nocera 	error = goodix_i2c_read(ts->client, GOODIX_REG_CONFIG_DATA,
466a779fbc6SIrina Tirdea 				config, ts->cfg_len);
467ca96ea86SBastien Nocera 	if (error) {
468ca96ea86SBastien Nocera 		dev_warn(&ts->client->dev,
469ca96ea86SBastien Nocera 			 "Error reading config (%d), using defaults\n",
470ca96ea86SBastien Nocera 			 error);
471ca96ea86SBastien Nocera 		ts->abs_x_max = GOODIX_MAX_WIDTH;
472ca96ea86SBastien Nocera 		ts->abs_y_max = GOODIX_MAX_HEIGHT;
473ca96ea86SBastien Nocera 		ts->int_trigger_type = GOODIX_INT_TRIGGER;
474a7ac7c95SAleksei Mamlin 		ts->max_touch_num = GOODIX_MAX_CONTACTS;
475ca96ea86SBastien Nocera 		return;
476ca96ea86SBastien Nocera 	}
477ca96ea86SBastien Nocera 
478ca96ea86SBastien Nocera 	ts->abs_x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
479ca96ea86SBastien Nocera 	ts->abs_y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
480a7ac7c95SAleksei Mamlin 	ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
481a7ac7c95SAleksei Mamlin 	ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f;
482a7ac7c95SAleksei Mamlin 	if (!ts->abs_x_max || !ts->abs_y_max || !ts->max_touch_num) {
483ca96ea86SBastien Nocera 		dev_err(&ts->client->dev,
484ca96ea86SBastien Nocera 			"Invalid config, using defaults\n");
485ca96ea86SBastien Nocera 		ts->abs_x_max = GOODIX_MAX_WIDTH;
486ca96ea86SBastien Nocera 		ts->abs_y_max = GOODIX_MAX_HEIGHT;
487a7ac7c95SAleksei Mamlin 		ts->max_touch_num = GOODIX_MAX_CONTACTS;
488ca96ea86SBastien Nocera 	}
4898b5a359cSBastien Nocera 
4908b5a359cSBastien Nocera 	ts->rotated_screen = dmi_check_system(rotated_screen);
4918b5a359cSBastien Nocera 	if (ts->rotated_screen)
4928b5a359cSBastien Nocera 		dev_dbg(&ts->client->dev,
4938b5a359cSBastien Nocera 			 "Applying '180 degrees rotated screen' quirk\n");
494ca96ea86SBastien Nocera }
495ca96ea86SBastien Nocera 
496ca96ea86SBastien Nocera /**
497ca96ea86SBastien Nocera  * goodix_read_version - Read goodix touchscreen version
498ca96ea86SBastien Nocera  *
49968caf858SIrina Tirdea  * @ts: our goodix_ts_data pointer
500ca96ea86SBastien Nocera  */
50168caf858SIrina Tirdea static int goodix_read_version(struct goodix_ts_data *ts)
502ca96ea86SBastien Nocera {
503ca96ea86SBastien Nocera 	int error;
504ca96ea86SBastien Nocera 	u8 buf[6];
505e70b0307SIrina Tirdea 	char id_str[5];
506ca96ea86SBastien Nocera 
50768caf858SIrina Tirdea 	error = goodix_i2c_read(ts->client, GOODIX_REG_ID, buf, sizeof(buf));
508ca96ea86SBastien Nocera 	if (error) {
50968caf858SIrina Tirdea 		dev_err(&ts->client->dev, "read version failed: %d\n", error);
510ca96ea86SBastien Nocera 		return error;
511ca96ea86SBastien Nocera 	}
512ca96ea86SBastien Nocera 
513e70b0307SIrina Tirdea 	memcpy(id_str, buf, 4);
514e70b0307SIrina Tirdea 	id_str[4] = 0;
51568caf858SIrina Tirdea 	if (kstrtou16(id_str, 10, &ts->id))
51668caf858SIrina Tirdea 		ts->id = 0x1001;
517e70b0307SIrina Tirdea 
51868caf858SIrina Tirdea 	ts->version = get_unaligned_le16(&buf[4]);
519ca96ea86SBastien Nocera 
52068caf858SIrina Tirdea 	dev_info(&ts->client->dev, "ID %d, version: %04x\n", ts->id,
52168caf858SIrina Tirdea 		 ts->version);
522ca96ea86SBastien Nocera 
523ca96ea86SBastien Nocera 	return 0;
524ca96ea86SBastien Nocera }
525ca96ea86SBastien Nocera 
526ca96ea86SBastien Nocera /**
527ca96ea86SBastien Nocera  * goodix_i2c_test - I2C test function to check if the device answers.
528ca96ea86SBastien Nocera  *
529ca96ea86SBastien Nocera  * @client: the i2c client
530ca96ea86SBastien Nocera  */
531ca96ea86SBastien Nocera static int goodix_i2c_test(struct i2c_client *client)
532ca96ea86SBastien Nocera {
533ca96ea86SBastien Nocera 	int retry = 0;
534ca96ea86SBastien Nocera 	int error;
535ca96ea86SBastien Nocera 	u8 test;
536ca96ea86SBastien Nocera 
537ca96ea86SBastien Nocera 	while (retry++ < 2) {
538ca96ea86SBastien Nocera 		error = goodix_i2c_read(client, GOODIX_REG_CONFIG_DATA,
539ca96ea86SBastien Nocera 					&test, 1);
540ca96ea86SBastien Nocera 		if (!error)
541ca96ea86SBastien Nocera 			return 0;
542ca96ea86SBastien Nocera 
543ca96ea86SBastien Nocera 		dev_err(&client->dev, "i2c test failed attempt %d: %d\n",
544ca96ea86SBastien Nocera 			retry, error);
545ca96ea86SBastien Nocera 		msleep(20);
546ca96ea86SBastien Nocera 	}
547ca96ea86SBastien Nocera 
548ca96ea86SBastien Nocera 	return error;
549ca96ea86SBastien Nocera }
550ca96ea86SBastien Nocera 
551ca96ea86SBastien Nocera /**
552ca96ea86SBastien Nocera  * goodix_request_input_dev - Allocate, populate and register the input device
553ca96ea86SBastien Nocera  *
554ca96ea86SBastien Nocera  * @ts: our goodix_ts_data pointer
555ca96ea86SBastien Nocera  *
556ca96ea86SBastien Nocera  * Must be called during probe
557ca96ea86SBastien Nocera  */
55868caf858SIrina Tirdea static int goodix_request_input_dev(struct goodix_ts_data *ts)
559ca96ea86SBastien Nocera {
560ca96ea86SBastien Nocera 	int error;
561ca96ea86SBastien Nocera 
562ca96ea86SBastien Nocera 	ts->input_dev = devm_input_allocate_device(&ts->client->dev);
563ca96ea86SBastien Nocera 	if (!ts->input_dev) {
564ca96ea86SBastien Nocera 		dev_err(&ts->client->dev, "Failed to allocate input device.");
565ca96ea86SBastien Nocera 		return -ENOMEM;
566ca96ea86SBastien Nocera 	}
567ca96ea86SBastien Nocera 
5680dfb35bdSIrina Tirdea 	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
5690dfb35bdSIrina Tirdea 			     0, ts->abs_x_max, 0, 0);
5700dfb35bdSIrina Tirdea 	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
5710dfb35bdSIrina Tirdea 			     0, ts->abs_y_max, 0, 0);
572ca96ea86SBastien Nocera 	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
573ca96ea86SBastien Nocera 	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
574ca96ea86SBastien Nocera 
575a7ac7c95SAleksei Mamlin 	input_mt_init_slots(ts->input_dev, ts->max_touch_num,
576ca96ea86SBastien Nocera 			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
577ca96ea86SBastien Nocera 
578ca96ea86SBastien Nocera 	ts->input_dev->name = "Goodix Capacitive TouchScreen";
579ca96ea86SBastien Nocera 	ts->input_dev->phys = "input/ts";
580ca96ea86SBastien Nocera 	ts->input_dev->id.bustype = BUS_I2C;
581ca96ea86SBastien Nocera 	ts->input_dev->id.vendor = 0x0416;
58268caf858SIrina Tirdea 	ts->input_dev->id.product = ts->id;
58368caf858SIrina Tirdea 	ts->input_dev->id.version = ts->version;
584ca96ea86SBastien Nocera 
585ca96ea86SBastien Nocera 	error = input_register_device(ts->input_dev);
586ca96ea86SBastien Nocera 	if (error) {
587ca96ea86SBastien Nocera 		dev_err(&ts->client->dev,
588ca96ea86SBastien Nocera 			"Failed to register input device: %d", error);
589ca96ea86SBastien Nocera 		return error;
590ca96ea86SBastien Nocera 	}
591ca96ea86SBastien Nocera 
592ca96ea86SBastien Nocera 	return 0;
593ca96ea86SBastien Nocera }
594ca96ea86SBastien Nocera 
59568caf858SIrina Tirdea /**
59668caf858SIrina Tirdea  * goodix_configure_dev - Finish device initialization
59768caf858SIrina Tirdea  *
59868caf858SIrina Tirdea  * @ts: our goodix_ts_data pointer
59968caf858SIrina Tirdea  *
60068caf858SIrina Tirdea  * Must be called from probe to finish initialization of the device.
60168caf858SIrina Tirdea  * Contains the common initialization code for both devices that
60268caf858SIrina Tirdea  * declare gpio pins and devices that do not. It is either called
60368caf858SIrina Tirdea  * directly from probe or from request_firmware_wait callback.
60468caf858SIrina Tirdea  */
60568caf858SIrina Tirdea static int goodix_configure_dev(struct goodix_ts_data *ts)
60668caf858SIrina Tirdea {
60768caf858SIrina Tirdea 	int error;
60868caf858SIrina Tirdea 	unsigned long irq_flags;
60968caf858SIrina Tirdea 
61068caf858SIrina Tirdea 	goodix_read_config(ts);
61168caf858SIrina Tirdea 
61268caf858SIrina Tirdea 	error = goodix_request_input_dev(ts);
61368caf858SIrina Tirdea 	if (error)
61468caf858SIrina Tirdea 		return error;
61568caf858SIrina Tirdea 
61668caf858SIrina Tirdea 	irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
61768caf858SIrina Tirdea 	error = devm_request_threaded_irq(&ts->client->dev, ts->client->irq,
61868caf858SIrina Tirdea 					  NULL, goodix_ts_irq_handler,
61968caf858SIrina Tirdea 					  irq_flags, ts->client->name, ts);
62068caf858SIrina Tirdea 	if (error) {
62168caf858SIrina Tirdea 		dev_err(&ts->client->dev, "request IRQ failed: %d\n", error);
62268caf858SIrina Tirdea 		return error;
62368caf858SIrina Tirdea 	}
62468caf858SIrina Tirdea 
62568caf858SIrina Tirdea 	return 0;
62668caf858SIrina Tirdea }
62768caf858SIrina Tirdea 
62868caf858SIrina Tirdea /**
62968caf858SIrina Tirdea  * goodix_config_cb - Callback to finish device init
63068caf858SIrina Tirdea  *
63168caf858SIrina Tirdea  * @ts: our goodix_ts_data pointer
63268caf858SIrina Tirdea  *
63368caf858SIrina Tirdea  * request_firmware_wait callback that finishes
63468caf858SIrina Tirdea  * initialization of the device.
63568caf858SIrina Tirdea  */
63668caf858SIrina Tirdea static void goodix_config_cb(const struct firmware *cfg, void *ctx)
63768caf858SIrina Tirdea {
63868caf858SIrina Tirdea 	struct goodix_ts_data *ts = ctx;
63968caf858SIrina Tirdea 	int error;
64068caf858SIrina Tirdea 
64168caf858SIrina Tirdea 	if (cfg) {
64268caf858SIrina Tirdea 		/* send device configuration to the firmware */
64368caf858SIrina Tirdea 		error = goodix_send_cfg(ts, cfg);
64468caf858SIrina Tirdea 		if (error)
64568caf858SIrina Tirdea 			goto err_release_cfg;
64668caf858SIrina Tirdea 	}
64768caf858SIrina Tirdea 
64868caf858SIrina Tirdea 	goodix_configure_dev(ts);
64968caf858SIrina Tirdea 
65068caf858SIrina Tirdea err_release_cfg:
65168caf858SIrina Tirdea 	release_firmware(cfg);
65268caf858SIrina Tirdea 	complete_all(&ts->firmware_loading_complete);
65368caf858SIrina Tirdea }
65468caf858SIrina Tirdea 
655ca96ea86SBastien Nocera static int goodix_ts_probe(struct i2c_client *client,
656ca96ea86SBastien Nocera 			   const struct i2c_device_id *id)
657ca96ea86SBastien Nocera {
658ca96ea86SBastien Nocera 	struct goodix_ts_data *ts;
659ca96ea86SBastien Nocera 	int error;
660ca96ea86SBastien Nocera 
661ca96ea86SBastien Nocera 	dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr);
662ca96ea86SBastien Nocera 
663ca96ea86SBastien Nocera 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
664ca96ea86SBastien Nocera 		dev_err(&client->dev, "I2C check functionality failed.\n");
665ca96ea86SBastien Nocera 		return -ENXIO;
666ca96ea86SBastien Nocera 	}
667ca96ea86SBastien Nocera 
668ca96ea86SBastien Nocera 	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
669ca96ea86SBastien Nocera 	if (!ts)
670ca96ea86SBastien Nocera 		return -ENOMEM;
671ca96ea86SBastien Nocera 
672ca96ea86SBastien Nocera 	ts->client = client;
673ca96ea86SBastien Nocera 	i2c_set_clientdata(client, ts);
67468caf858SIrina Tirdea 	init_completion(&ts->firmware_loading_complete);
675ca96ea86SBastien Nocera 
676ec6e1b40SIrina Tirdea 	error = goodix_get_gpio_config(ts);
677ec6e1b40SIrina Tirdea 	if (error)
678ec6e1b40SIrina Tirdea 		return error;
679ec6e1b40SIrina Tirdea 
680ec6e1b40SIrina Tirdea 	if (ts->gpiod_int && ts->gpiod_rst) {
681ec6e1b40SIrina Tirdea 		/* reset the controller */
682ec6e1b40SIrina Tirdea 		error = goodix_reset(ts);
683ec6e1b40SIrina Tirdea 		if (error) {
684ec6e1b40SIrina Tirdea 			dev_err(&client->dev, "Controller reset failed.\n");
685ec6e1b40SIrina Tirdea 			return error;
686ec6e1b40SIrina Tirdea 		}
687ec6e1b40SIrina Tirdea 	}
688ec6e1b40SIrina Tirdea 
689ca96ea86SBastien Nocera 	error = goodix_i2c_test(client);
690ca96ea86SBastien Nocera 	if (error) {
691ca96ea86SBastien Nocera 		dev_err(&client->dev, "I2C communication failure: %d\n", error);
692ca96ea86SBastien Nocera 		return error;
693ca96ea86SBastien Nocera 	}
694ca96ea86SBastien Nocera 
69568caf858SIrina Tirdea 	error = goodix_read_version(ts);
696ca96ea86SBastien Nocera 	if (error) {
697ca96ea86SBastien Nocera 		dev_err(&client->dev, "Read version failed.\n");
698ca96ea86SBastien Nocera 		return error;
699ca96ea86SBastien Nocera 	}
700ca96ea86SBastien Nocera 
70168caf858SIrina Tirdea 	ts->cfg_len = goodix_get_cfg_len(ts->id);
702a779fbc6SIrina Tirdea 
70368caf858SIrina Tirdea 	if (ts->gpiod_int && ts->gpiod_rst) {
70468caf858SIrina Tirdea 		/* update device config */
70568caf858SIrina Tirdea 		ts->cfg_name = devm_kasprintf(&client->dev, GFP_KERNEL,
70668caf858SIrina Tirdea 					      "goodix_%d_cfg.bin", ts->id);
70768caf858SIrina Tirdea 		if (!ts->cfg_name)
70868caf858SIrina Tirdea 			return -ENOMEM;
709ca96ea86SBastien Nocera 
71068caf858SIrina Tirdea 		error = request_firmware_nowait(THIS_MODULE, true, ts->cfg_name,
71168caf858SIrina Tirdea 						&client->dev, GFP_KERNEL, ts,
71268caf858SIrina Tirdea 						goodix_config_cb);
713ca96ea86SBastien Nocera 		if (error) {
71468caf858SIrina Tirdea 			dev_err(&client->dev,
71568caf858SIrina Tirdea 				"Failed to invoke firmware loader: %d\n",
71668caf858SIrina Tirdea 				error);
717ca96ea86SBastien Nocera 			return error;
718ca96ea86SBastien Nocera 		}
719ca96ea86SBastien Nocera 
720ca96ea86SBastien Nocera 		return 0;
72168caf858SIrina Tirdea 	} else {
72268caf858SIrina Tirdea 		error = goodix_configure_dev(ts);
72368caf858SIrina Tirdea 		if (error)
72468caf858SIrina Tirdea 			return error;
72568caf858SIrina Tirdea 	}
72668caf858SIrina Tirdea 
72768caf858SIrina Tirdea 	return 0;
72868caf858SIrina Tirdea }
72968caf858SIrina Tirdea 
73068caf858SIrina Tirdea static int goodix_ts_remove(struct i2c_client *client)
73168caf858SIrina Tirdea {
73268caf858SIrina Tirdea 	struct goodix_ts_data *ts = i2c_get_clientdata(client);
73368caf858SIrina Tirdea 
73468caf858SIrina Tirdea 	if (ts->gpiod_int && ts->gpiod_rst)
73568caf858SIrina Tirdea 		wait_for_completion(&ts->firmware_loading_complete);
73668caf858SIrina Tirdea 
73768caf858SIrina Tirdea 	return 0;
738ca96ea86SBastien Nocera }
739ca96ea86SBastien Nocera 
740ca96ea86SBastien Nocera static const struct i2c_device_id goodix_ts_id[] = {
741ca96ea86SBastien Nocera 	{ "GDIX1001:00", 0 },
742ca96ea86SBastien Nocera 	{ }
743ca96ea86SBastien Nocera };
7442e9e910eSJavier Martinez Canillas MODULE_DEVICE_TABLE(i2c, goodix_ts_id);
745ca96ea86SBastien Nocera 
746771d8f1bSAleksei Mamlin #ifdef CONFIG_ACPI
747ca96ea86SBastien Nocera static const struct acpi_device_id goodix_acpi_match[] = {
748ca96ea86SBastien Nocera 	{ "GDIX1001", 0 },
749ca96ea86SBastien Nocera 	{ }
750ca96ea86SBastien Nocera };
751ca96ea86SBastien Nocera MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
752771d8f1bSAleksei Mamlin #endif
753771d8f1bSAleksei Mamlin 
754771d8f1bSAleksei Mamlin #ifdef CONFIG_OF
755771d8f1bSAleksei Mamlin static const struct of_device_id goodix_of_match[] = {
756771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt911" },
757771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt9110" },
758771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt912" },
759771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt927" },
760771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt9271" },
761771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt928" },
762771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt967" },
763771d8f1bSAleksei Mamlin 	{ }
764771d8f1bSAleksei Mamlin };
765771d8f1bSAleksei Mamlin MODULE_DEVICE_TABLE(of, goodix_of_match);
766771d8f1bSAleksei Mamlin #endif
767ca96ea86SBastien Nocera 
768ca96ea86SBastien Nocera static struct i2c_driver goodix_ts_driver = {
769ca96ea86SBastien Nocera 	.probe = goodix_ts_probe,
77068caf858SIrina Tirdea 	.remove = goodix_ts_remove,
771ca96ea86SBastien Nocera 	.id_table = goodix_ts_id,
772ca96ea86SBastien Nocera 	.driver = {
773ca96ea86SBastien Nocera 		.name = "Goodix-TS",
774771d8f1bSAleksei Mamlin 		.acpi_match_table = ACPI_PTR(goodix_acpi_match),
775771d8f1bSAleksei Mamlin 		.of_match_table = of_match_ptr(goodix_of_match),
776ca96ea86SBastien Nocera 	},
777ca96ea86SBastien Nocera };
778ca96ea86SBastien Nocera module_i2c_driver(goodix_ts_driver);
779ca96ea86SBastien Nocera 
780ca96ea86SBastien Nocera MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
781ca96ea86SBastien Nocera MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
782ca96ea86SBastien Nocera MODULE_DESCRIPTION("Goodix touchscreen driver");
783ca96ea86SBastien Nocera MODULE_LICENSE("GPL v2");
784