1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2ca96ea86SBastien Nocera /*
3ca96ea86SBastien Nocera  *  Driver for Goodix Touchscreens
4ca96ea86SBastien Nocera  *
5ca96ea86SBastien Nocera  *  Copyright (c) 2014 Red Hat Inc.
6ad48cf5eSKarsten Merker  *  Copyright (c) 2015 K. Merker <merker@debian.org>
7ca96ea86SBastien Nocera  *
8ca96ea86SBastien Nocera  *  This code is based on gt9xx.c authored by andrew@goodix.com:
9ca96ea86SBastien Nocera  *
10ca96ea86SBastien Nocera  *  2010 - 2012 Goodix Technology.
11ca96ea86SBastien Nocera  */
12ca96ea86SBastien Nocera 
13ca96ea86SBastien Nocera 
14ca96ea86SBastien Nocera #include <linux/kernel.h>
158b5a359cSBastien Nocera #include <linux/dmi.h>
1668caf858SIrina Tirdea #include <linux/firmware.h>
17ec6e1b40SIrina Tirdea #include <linux/gpio/consumer.h>
18ca96ea86SBastien Nocera #include <linux/i2c.h>
19ca96ea86SBastien Nocera #include <linux/input.h>
20ca96ea86SBastien Nocera #include <linux/input/mt.h>
21fafef982SMarcin Niestroj #include <linux/input/touchscreen.h>
22ca96ea86SBastien Nocera #include <linux/module.h>
23ca96ea86SBastien Nocera #include <linux/delay.h>
24ca96ea86SBastien Nocera #include <linux/irq.h>
25ca96ea86SBastien Nocera #include <linux/interrupt.h>
26ae97fb58SJagan Teki #include <linux/regulator/consumer.h>
27ca96ea86SBastien Nocera #include <linux/slab.h>
28771d8f1bSAleksei Mamlin #include <linux/acpi.h>
29771d8f1bSAleksei Mamlin #include <linux/of.h>
30ca96ea86SBastien Nocera #include <asm/unaligned.h>
31ca96ea86SBastien Nocera 
3225309004SMarcin Niestroj struct goodix_ts_data;
3325309004SMarcin Niestroj 
3449db3997SHans de Goede enum goodix_irq_pin_access_method {
3549db3997SHans de Goede 	IRQ_PIN_ACCESS_NONE,
3649db3997SHans de Goede 	IRQ_PIN_ACCESS_GPIO,
37a7d4b171SHans de Goede 	IRQ_PIN_ACCESS_ACPI_GPIO,
38c5fca485SHans de Goede 	IRQ_PIN_ACCESS_ACPI_METHOD,
3949db3997SHans de Goede };
4049db3997SHans de Goede 
4125309004SMarcin Niestroj struct goodix_chip_data {
4225309004SMarcin Niestroj 	u16 config_addr;
4325309004SMarcin Niestroj 	int config_len;
4425309004SMarcin Niestroj 	int (*check_config)(struct goodix_ts_data *, const struct firmware *);
4525309004SMarcin Niestroj };
4625309004SMarcin Niestroj 
47ca96ea86SBastien Nocera struct goodix_ts_data {
48ca96ea86SBastien Nocera 	struct i2c_client *client;
49ca96ea86SBastien Nocera 	struct input_dev *input_dev;
5025309004SMarcin Niestroj 	const struct goodix_chip_data *chip;
51fafef982SMarcin Niestroj 	struct touchscreen_properties prop;
52ca96ea86SBastien Nocera 	unsigned int max_touch_num;
53ca96ea86SBastien Nocera 	unsigned int int_trigger_type;
54ae97fb58SJagan Teki 	struct regulator *avdd28;
55ae97fb58SJagan Teki 	struct regulator *vddio;
56ec6e1b40SIrina Tirdea 	struct gpio_desc *gpiod_int;
57ec6e1b40SIrina Tirdea 	struct gpio_desc *gpiod_rst;
58a7d4b171SHans de Goede 	int gpio_count;
59a7d4b171SHans de Goede 	int gpio_int_idx;
6068caf858SIrina Tirdea 	u16 id;
6168caf858SIrina Tirdea 	u16 version;
6268caf858SIrina Tirdea 	const char *cfg_name;
631921daceSHans de Goede 	bool reset_controller_at_probe;
64e070a97bSHans de Goede 	bool load_cfg_from_disk;
6568caf858SIrina Tirdea 	struct completion firmware_loading_complete;
665ab09d6aSIrina Tirdea 	unsigned long irq_flags;
6749db3997SHans de Goede 	enum goodix_irq_pin_access_method irq_pin_access_method;
68bd3b8480SYauhen Kharuzhy 	unsigned int contact_size;
69ca96ea86SBastien Nocera };
70ca96ea86SBastien Nocera 
71ec6e1b40SIrina Tirdea #define GOODIX_GPIO_INT_NAME		"irq"
72ec6e1b40SIrina Tirdea #define GOODIX_GPIO_RST_NAME		"reset"
73ec6e1b40SIrina Tirdea 
74ca96ea86SBastien Nocera #define GOODIX_MAX_HEIGHT		4096
75ca96ea86SBastien Nocera #define GOODIX_MAX_WIDTH		4096
76ca96ea86SBastien Nocera #define GOODIX_INT_TRIGGER		1
77ca96ea86SBastien Nocera #define GOODIX_CONTACT_SIZE		8
78bd3b8480SYauhen Kharuzhy #define GOODIX_MAX_CONTACT_SIZE		9
79ca96ea86SBastien Nocera #define GOODIX_MAX_CONTACTS		10
80ca96ea86SBastien Nocera 
81ca96ea86SBastien Nocera #define GOODIX_CONFIG_MAX_LENGTH	240
82a779fbc6SIrina Tirdea #define GOODIX_CONFIG_911_LENGTH	186
83a779fbc6SIrina Tirdea #define GOODIX_CONFIG_967_LENGTH	228
84ca96ea86SBastien Nocera 
85ca96ea86SBastien Nocera /* Register defines */
865ab09d6aSIrina Tirdea #define GOODIX_REG_COMMAND		0x8040
875ab09d6aSIrina Tirdea #define GOODIX_CMD_SCREEN_OFF		0x05
885ab09d6aSIrina Tirdea 
89ca96ea86SBastien Nocera #define GOODIX_READ_COOR_ADDR		0x814E
9025309004SMarcin Niestroj #define GOODIX_GT1X_REG_CONFIG_DATA	0x8050
9125309004SMarcin Niestroj #define GOODIX_GT9X_REG_CONFIG_DATA	0x8047
92e70b0307SIrina Tirdea #define GOODIX_REG_ID			0x8140
93ca96ea86SBastien Nocera 
949b5db7aaSPaul Cercueil #define GOODIX_BUFFER_STATUS_READY	BIT(7)
959b5db7aaSPaul Cercueil #define GOODIX_BUFFER_STATUS_TIMEOUT	20
969b5db7aaSPaul Cercueil 
97ca96ea86SBastien Nocera #define RESOLUTION_LOC		1
98a7ac7c95SAleksei Mamlin #define MAX_CONTACTS_LOC	5
99ca96ea86SBastien Nocera #define TRIGGER_LOC		6
100ca96ea86SBastien Nocera 
10125309004SMarcin Niestroj static int goodix_check_cfg_8(struct goodix_ts_data *ts,
10225309004SMarcin Niestroj 			const struct firmware *cfg);
10325309004SMarcin Niestroj static int goodix_check_cfg_16(struct goodix_ts_data *ts,
10425309004SMarcin Niestroj 			const struct firmware *cfg);
10525309004SMarcin Niestroj 
10625309004SMarcin Niestroj static const struct goodix_chip_data gt1x_chip_data = {
10725309004SMarcin Niestroj 	.config_addr		= GOODIX_GT1X_REG_CONFIG_DATA,
10825309004SMarcin Niestroj 	.config_len		= GOODIX_CONFIG_MAX_LENGTH,
10925309004SMarcin Niestroj 	.check_config		= goodix_check_cfg_16,
11025309004SMarcin Niestroj };
11125309004SMarcin Niestroj 
11225309004SMarcin Niestroj static const struct goodix_chip_data gt911_chip_data = {
11325309004SMarcin Niestroj 	.config_addr		= GOODIX_GT9X_REG_CONFIG_DATA,
11425309004SMarcin Niestroj 	.config_len		= GOODIX_CONFIG_911_LENGTH,
11525309004SMarcin Niestroj 	.check_config		= goodix_check_cfg_8,
11625309004SMarcin Niestroj };
11725309004SMarcin Niestroj 
11825309004SMarcin Niestroj static const struct goodix_chip_data gt967_chip_data = {
11925309004SMarcin Niestroj 	.config_addr		= GOODIX_GT9X_REG_CONFIG_DATA,
12025309004SMarcin Niestroj 	.config_len		= GOODIX_CONFIG_967_LENGTH,
12125309004SMarcin Niestroj 	.check_config		= goodix_check_cfg_8,
12225309004SMarcin Niestroj };
12325309004SMarcin Niestroj 
12425309004SMarcin Niestroj static const struct goodix_chip_data gt9x_chip_data = {
12525309004SMarcin Niestroj 	.config_addr		= GOODIX_GT9X_REG_CONFIG_DATA,
12625309004SMarcin Niestroj 	.config_len		= GOODIX_CONFIG_MAX_LENGTH,
12725309004SMarcin Niestroj 	.check_config		= goodix_check_cfg_8,
12825309004SMarcin Niestroj };
12925309004SMarcin Niestroj 
130ca96ea86SBastien Nocera static const unsigned long goodix_irq_flags[] = {
131ca96ea86SBastien Nocera 	IRQ_TYPE_EDGE_RISING,
132ca96ea86SBastien Nocera 	IRQ_TYPE_EDGE_FALLING,
133ca96ea86SBastien Nocera 	IRQ_TYPE_LEVEL_LOW,
134ca96ea86SBastien Nocera 	IRQ_TYPE_LEVEL_HIGH,
135ca96ea86SBastien Nocera };
136ca96ea86SBastien Nocera 
1378b5a359cSBastien Nocera /*
1388b5a359cSBastien Nocera  * Those tablets have their coordinates origin at the bottom right
1398b5a359cSBastien Nocera  * of the tablet, as if rotated 180 degrees
1408b5a359cSBastien Nocera  */
1418b5a359cSBastien Nocera static const struct dmi_system_id rotated_screen[] = {
1428b5a359cSBastien Nocera #if defined(CONFIG_DMI) && defined(CONFIG_X86)
1438b5a359cSBastien Nocera 	{
144df5b5e55SHans de Goede 		.ident = "Teclast X89",
145df5b5e55SHans de Goede 		.matches = {
146df5b5e55SHans de Goede 			/* tPAD is too generic, also match on bios date */
147df5b5e55SHans de Goede 			DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
148df5b5e55SHans de Goede 			DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
149df5b5e55SHans de Goede 			DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"),
150df5b5e55SHans de Goede 		},
151df5b5e55SHans de Goede 	},
152df5b5e55SHans de Goede 	{
1538b5a359cSBastien Nocera 		.ident = "WinBook TW100",
1548b5a359cSBastien Nocera 		.matches = {
1558b5a359cSBastien Nocera 			DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
1568b5a359cSBastien Nocera 			DMI_MATCH(DMI_PRODUCT_NAME, "TW100")
1578b5a359cSBastien Nocera 		}
1588b5a359cSBastien Nocera 	},
1598b5a359cSBastien Nocera 	{
1608b5a359cSBastien Nocera 		.ident = "WinBook TW700",
1618b5a359cSBastien Nocera 		.matches = {
1628b5a359cSBastien Nocera 			DMI_MATCH(DMI_SYS_VENDOR, "WinBook"),
1638b5a359cSBastien Nocera 			DMI_MATCH(DMI_PRODUCT_NAME, "TW700")
1648b5a359cSBastien Nocera 		},
1658b5a359cSBastien Nocera 	},
1668b5a359cSBastien Nocera #endif
1678b5a359cSBastien Nocera 	{}
1688b5a359cSBastien Nocera };
1698b5a359cSBastien Nocera 
170bd3b8480SYauhen Kharuzhy static const struct dmi_system_id nine_bytes_report[] = {
171bd3b8480SYauhen Kharuzhy #if defined(CONFIG_DMI) && defined(CONFIG_X86)
172bd3b8480SYauhen Kharuzhy 	{
173bd3b8480SYauhen Kharuzhy 		.ident = "Lenovo YogaBook",
174bd3b8480SYauhen Kharuzhy 		/* YB1-X91L/F and YB1-X90L/F */
175bd3b8480SYauhen Kharuzhy 		.matches = {
176bd3b8480SYauhen Kharuzhy 			DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9")
177bd3b8480SYauhen Kharuzhy 		}
178bd3b8480SYauhen Kharuzhy 	},
179bd3b8480SYauhen Kharuzhy #endif
180bd3b8480SYauhen Kharuzhy 	{}
181bd3b8480SYauhen Kharuzhy };
182bd3b8480SYauhen Kharuzhy 
1831dd5ddc1SSergei A. Trusov /*
1841dd5ddc1SSergei A. Trusov  * Those tablets have their x coordinate inverted
1851dd5ddc1SSergei A. Trusov  */
1861dd5ddc1SSergei A. Trusov static const struct dmi_system_id inverted_x_screen[] = {
1871dd5ddc1SSergei A. Trusov #if defined(CONFIG_DMI) && defined(CONFIG_X86)
1881dd5ddc1SSergei A. Trusov 	{
1891dd5ddc1SSergei A. Trusov 		.ident = "Cube I15-TC",
1901dd5ddc1SSergei A. Trusov 		.matches = {
1911dd5ddc1SSergei A. Trusov 			DMI_MATCH(DMI_SYS_VENDOR, "Cube"),
1921dd5ddc1SSergei A. Trusov 			DMI_MATCH(DMI_PRODUCT_NAME, "I15-TC")
1931dd5ddc1SSergei A. Trusov 		},
1941dd5ddc1SSergei A. Trusov 	},
1951dd5ddc1SSergei A. Trusov #endif
1961dd5ddc1SSergei A. Trusov 	{}
1971dd5ddc1SSergei A. Trusov };
1981dd5ddc1SSergei A. Trusov 
199ca96ea86SBastien Nocera /**
200ca96ea86SBastien Nocera  * goodix_i2c_read - read data from a register of the i2c slave device.
201ca96ea86SBastien Nocera  *
202ca96ea86SBastien Nocera  * @client: i2c device.
203ca96ea86SBastien Nocera  * @reg: the register to read from.
204ca96ea86SBastien Nocera  * @buf: raw write data buffer.
205ca96ea86SBastien Nocera  * @len: length of the buffer to write
206ca96ea86SBastien Nocera  */
207ca96ea86SBastien Nocera static int goodix_i2c_read(struct i2c_client *client,
208ca96ea86SBastien Nocera 			   u16 reg, u8 *buf, int len)
209ca96ea86SBastien Nocera {
210ca96ea86SBastien Nocera 	struct i2c_msg msgs[2];
211fafef982SMarcin Niestroj 	__be16 wbuf = cpu_to_be16(reg);
212ca96ea86SBastien Nocera 	int ret;
213ca96ea86SBastien Nocera 
214ca96ea86SBastien Nocera 	msgs[0].flags = 0;
215ca96ea86SBastien Nocera 	msgs[0].addr  = client->addr;
216ca96ea86SBastien Nocera 	msgs[0].len   = 2;
217ca96ea86SBastien Nocera 	msgs[0].buf   = (u8 *)&wbuf;
218ca96ea86SBastien Nocera 
219ca96ea86SBastien Nocera 	msgs[1].flags = I2C_M_RD;
220ca96ea86SBastien Nocera 	msgs[1].addr  = client->addr;
221ca96ea86SBastien Nocera 	msgs[1].len   = len;
222ca96ea86SBastien Nocera 	msgs[1].buf   = buf;
223ca96ea86SBastien Nocera 
224ca96ea86SBastien Nocera 	ret = i2c_transfer(client->adapter, msgs, 2);
225ca96ea86SBastien Nocera 	return ret < 0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
226ca96ea86SBastien Nocera }
227ca96ea86SBastien Nocera 
22868caf858SIrina Tirdea /**
22968caf858SIrina Tirdea  * goodix_i2c_write - write data to a register of the i2c slave device.
23068caf858SIrina Tirdea  *
23168caf858SIrina Tirdea  * @client: i2c device.
23268caf858SIrina Tirdea  * @reg: the register to write to.
23368caf858SIrina Tirdea  * @buf: raw data buffer to write.
23468caf858SIrina Tirdea  * @len: length of the buffer to write
23568caf858SIrina Tirdea  */
23668caf858SIrina Tirdea static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 *buf,
23768caf858SIrina Tirdea 			    unsigned len)
23868caf858SIrina Tirdea {
23968caf858SIrina Tirdea 	u8 *addr_buf;
24068caf858SIrina Tirdea 	struct i2c_msg msg;
24168caf858SIrina Tirdea 	int ret;
24268caf858SIrina Tirdea 
24368caf858SIrina Tirdea 	addr_buf = kmalloc(len + 2, GFP_KERNEL);
24468caf858SIrina Tirdea 	if (!addr_buf)
24568caf858SIrina Tirdea 		return -ENOMEM;
24668caf858SIrina Tirdea 
24768caf858SIrina Tirdea 	addr_buf[0] = reg >> 8;
24868caf858SIrina Tirdea 	addr_buf[1] = reg & 0xFF;
24968caf858SIrina Tirdea 	memcpy(&addr_buf[2], buf, len);
25068caf858SIrina Tirdea 
25168caf858SIrina Tirdea 	msg.flags = 0;
25268caf858SIrina Tirdea 	msg.addr = client->addr;
25368caf858SIrina Tirdea 	msg.buf = addr_buf;
25468caf858SIrina Tirdea 	msg.len = len + 2;
25568caf858SIrina Tirdea 
25668caf858SIrina Tirdea 	ret = i2c_transfer(client->adapter, &msg, 1);
25768caf858SIrina Tirdea 	kfree(addr_buf);
25868caf858SIrina Tirdea 	return ret < 0 ? ret : (ret != 1 ? -EIO : 0);
25968caf858SIrina Tirdea }
26068caf858SIrina Tirdea 
2615ab09d6aSIrina Tirdea static int goodix_i2c_write_u8(struct i2c_client *client, u16 reg, u8 value)
2625ab09d6aSIrina Tirdea {
2635ab09d6aSIrina Tirdea 	return goodix_i2c_write(client, reg, &value, sizeof(value));
2645ab09d6aSIrina Tirdea }
2655ab09d6aSIrina Tirdea 
26625309004SMarcin Niestroj static const struct goodix_chip_data *goodix_get_chip_data(u16 id)
267a779fbc6SIrina Tirdea {
268a779fbc6SIrina Tirdea 	switch (id) {
26925309004SMarcin Niestroj 	case 1151:
270a5f50c50SJagan Teki 	case 5663:
27184ef1b33SGuido Günther 	case 5688:
27225309004SMarcin Niestroj 		return &gt1x_chip_data;
27325309004SMarcin Niestroj 
274a779fbc6SIrina Tirdea 	case 911:
275a779fbc6SIrina Tirdea 	case 9271:
276a779fbc6SIrina Tirdea 	case 9110:
277a779fbc6SIrina Tirdea 	case 927:
278a779fbc6SIrina Tirdea 	case 928:
27925309004SMarcin Niestroj 		return &gt911_chip_data;
280a779fbc6SIrina Tirdea 
281a779fbc6SIrina Tirdea 	case 912:
282a779fbc6SIrina Tirdea 	case 967:
28325309004SMarcin Niestroj 		return &gt967_chip_data;
284a779fbc6SIrina Tirdea 
285a779fbc6SIrina Tirdea 	default:
28625309004SMarcin Niestroj 		return &gt9x_chip_data;
287a779fbc6SIrina Tirdea 	}
288a779fbc6SIrina Tirdea }
289a779fbc6SIrina Tirdea 
290ca96ea86SBastien Nocera static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
291ca96ea86SBastien Nocera {
2929b5db7aaSPaul Cercueil 	unsigned long max_timeout;
293ca96ea86SBastien Nocera 	int touch_num;
294ca96ea86SBastien Nocera 	int error;
295ca96ea86SBastien Nocera 
2969b5db7aaSPaul Cercueil 	/*
2979b5db7aaSPaul Cercueil 	 * The 'buffer status' bit, which indicates that the data is valid, is
2989b5db7aaSPaul Cercueil 	 * not set as soon as the interrupt is raised, but slightly after.
2999b5db7aaSPaul Cercueil 	 * This takes around 10 ms to happen, so we poll for 20 ms.
3009b5db7aaSPaul Cercueil 	 */
3019b5db7aaSPaul Cercueil 	max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
3029b5db7aaSPaul Cercueil 	do {
3039b5db7aaSPaul Cercueil 		error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
304bd3b8480SYauhen Kharuzhy 					data, ts->contact_size + 1);
305ca96ea86SBastien Nocera 		if (error) {
3069b5db7aaSPaul Cercueil 			dev_err(&ts->client->dev, "I2C transfer error: %d\n",
3079b5db7aaSPaul Cercueil 					error);
308ca96ea86SBastien Nocera 			return error;
309ca96ea86SBastien Nocera 		}
310ca96ea86SBastien Nocera 
3119b5db7aaSPaul Cercueil 		if (data[0] & GOODIX_BUFFER_STATUS_READY) {
312ca96ea86SBastien Nocera 			touch_num = data[0] & 0x0f;
313a7ac7c95SAleksei Mamlin 			if (touch_num > ts->max_touch_num)
314ca96ea86SBastien Nocera 				return -EPROTO;
315ca96ea86SBastien Nocera 
316ca96ea86SBastien Nocera 			if (touch_num > 1) {
317bd3b8480SYauhen Kharuzhy 				data += 1 + ts->contact_size;
318ca96ea86SBastien Nocera 				error = goodix_i2c_read(ts->client,
319ca96ea86SBastien Nocera 						GOODIX_READ_COOR_ADDR +
320bd3b8480SYauhen Kharuzhy 							1 + ts->contact_size,
321ca96ea86SBastien Nocera 						data,
322bd3b8480SYauhen Kharuzhy 						ts->contact_size *
3239b5db7aaSPaul Cercueil 							(touch_num - 1));
324ca96ea86SBastien Nocera 				if (error)
325ca96ea86SBastien Nocera 					return error;
326ca96ea86SBastien Nocera 			}
327ca96ea86SBastien Nocera 
328ca96ea86SBastien Nocera 			return touch_num;
329ca96ea86SBastien Nocera 		}
330ca96ea86SBastien Nocera 
3319b5db7aaSPaul Cercueil 		usleep_range(1000, 2000); /* Poll every 1 - 2 ms */
3329b5db7aaSPaul Cercueil 	} while (time_before(jiffies, max_timeout));
3339b5db7aaSPaul Cercueil 
3349b5db7aaSPaul Cercueil 	/*
3359b5db7aaSPaul Cercueil 	 * The Goodix panel will send spurious interrupts after a
3369b5db7aaSPaul Cercueil 	 * 'finger up' event, which will always cause a timeout.
3379b5db7aaSPaul Cercueil 	 */
3389b5db7aaSPaul Cercueil 	return 0;
3399b5db7aaSPaul Cercueil }
3409b5db7aaSPaul Cercueil 
341bd3b8480SYauhen Kharuzhy static void goodix_ts_report_touch_8b(struct goodix_ts_data *ts, u8 *coor_data)
342ca96ea86SBastien Nocera {
343ca96ea86SBastien Nocera 	int id = coor_data[0] & 0x0F;
344ca96ea86SBastien Nocera 	int input_x = get_unaligned_le16(&coor_data[1]);
345ca96ea86SBastien Nocera 	int input_y = get_unaligned_le16(&coor_data[3]);
346ca96ea86SBastien Nocera 	int input_w = get_unaligned_le16(&coor_data[5]);
347ca96ea86SBastien Nocera 
348ca96ea86SBastien Nocera 	input_mt_slot(ts->input_dev, id);
349ca96ea86SBastien Nocera 	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
350fafef982SMarcin Niestroj 	touchscreen_report_pos(ts->input_dev, &ts->prop,
351fafef982SMarcin Niestroj 			       input_x, input_y, true);
352ca96ea86SBastien Nocera 	input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
353ca96ea86SBastien Nocera 	input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
354ca96ea86SBastien Nocera }
355ca96ea86SBastien Nocera 
356bd3b8480SYauhen Kharuzhy static void goodix_ts_report_touch_9b(struct goodix_ts_data *ts, u8 *coor_data)
357bd3b8480SYauhen Kharuzhy {
358bd3b8480SYauhen Kharuzhy 	int id = coor_data[1] & 0x0F;
359bd3b8480SYauhen Kharuzhy 	int input_x = get_unaligned_le16(&coor_data[3]);
360bd3b8480SYauhen Kharuzhy 	int input_y = get_unaligned_le16(&coor_data[5]);
361bd3b8480SYauhen Kharuzhy 	int input_w = get_unaligned_le16(&coor_data[7]);
362bd3b8480SYauhen Kharuzhy 
363bd3b8480SYauhen Kharuzhy 	input_mt_slot(ts->input_dev, id);
364bd3b8480SYauhen Kharuzhy 	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
365bd3b8480SYauhen Kharuzhy 	touchscreen_report_pos(ts->input_dev, &ts->prop,
366bd3b8480SYauhen Kharuzhy 			       input_x, input_y, true);
367bd3b8480SYauhen Kharuzhy 	input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w);
368bd3b8480SYauhen Kharuzhy 	input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w);
369bd3b8480SYauhen Kharuzhy }
370bd3b8480SYauhen Kharuzhy 
371ca96ea86SBastien Nocera /**
372ca96ea86SBastien Nocera  * goodix_process_events - Process incoming events
373ca96ea86SBastien Nocera  *
374ca96ea86SBastien Nocera  * @ts: our goodix_ts_data pointer
375ca96ea86SBastien Nocera  *
376ca96ea86SBastien Nocera  * Called when the IRQ is triggered. Read the current device state, and push
377ca96ea86SBastien Nocera  * the input events to the user space.
378ca96ea86SBastien Nocera  */
379ca96ea86SBastien Nocera static void goodix_process_events(struct goodix_ts_data *ts)
380ca96ea86SBastien Nocera {
381bd3b8480SYauhen Kharuzhy 	u8  point_data[1 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS];
382ca96ea86SBastien Nocera 	int touch_num;
383ca96ea86SBastien Nocera 	int i;
384ca96ea86SBastien Nocera 
385ca96ea86SBastien Nocera 	touch_num = goodix_ts_read_input_report(ts, point_data);
386ca96ea86SBastien Nocera 	if (touch_num < 0)
387ca96ea86SBastien Nocera 		return;
388ca96ea86SBastien Nocera 
3894a54feeaSSergei A. Trusov 	/*
3904a54feeaSSergei A. Trusov 	 * Bit 4 of the first byte reports the status of the capacitive
3914a54feeaSSergei A. Trusov 	 * Windows/Home button.
3924a54feeaSSergei A. Trusov 	 */
3934a54feeaSSergei A. Trusov 	input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4));
3944a54feeaSSergei A. Trusov 
395ca96ea86SBastien Nocera 	for (i = 0; i < touch_num; i++)
396bd3b8480SYauhen Kharuzhy 		if (ts->contact_size == 9)
397bd3b8480SYauhen Kharuzhy 			goodix_ts_report_touch_9b(ts,
398bd3b8480SYauhen Kharuzhy 				&point_data[1 + ts->contact_size * i]);
399bd3b8480SYauhen Kharuzhy 		else
400bd3b8480SYauhen Kharuzhy 			goodix_ts_report_touch_8b(ts,
401bd3b8480SYauhen Kharuzhy 				&point_data[1 + ts->contact_size * i]);
402ca96ea86SBastien Nocera 
403ca96ea86SBastien Nocera 	input_mt_sync_frame(ts->input_dev);
404ca96ea86SBastien Nocera 	input_sync(ts->input_dev);
405ca96ea86SBastien Nocera }
406ca96ea86SBastien Nocera 
407ca96ea86SBastien Nocera /**
408ca96ea86SBastien Nocera  * goodix_ts_irq_handler - The IRQ handler
409ca96ea86SBastien Nocera  *
410ca96ea86SBastien Nocera  * @irq: interrupt number.
411ca96ea86SBastien Nocera  * @dev_id: private data pointer.
412ca96ea86SBastien Nocera  */
413ca96ea86SBastien Nocera static irqreturn_t goodix_ts_irq_handler(int irq, void *dev_id)
414ca96ea86SBastien Nocera {
415ca96ea86SBastien Nocera 	struct goodix_ts_data *ts = dev_id;
416ca96ea86SBastien Nocera 
417ca96ea86SBastien Nocera 	goodix_process_events(ts);
418ca96ea86SBastien Nocera 
4195d655b35SIrina Tirdea 	if (goodix_i2c_write_u8(ts->client, GOODIX_READ_COOR_ADDR, 0) < 0)
420ca96ea86SBastien Nocera 		dev_err(&ts->client->dev, "I2C write end_cmd error\n");
421ca96ea86SBastien Nocera 
422ca96ea86SBastien Nocera 	return IRQ_HANDLED;
423ca96ea86SBastien Nocera }
424ca96ea86SBastien Nocera 
4255ab09d6aSIrina Tirdea static void goodix_free_irq(struct goodix_ts_data *ts)
4265ab09d6aSIrina Tirdea {
4275ab09d6aSIrina Tirdea 	devm_free_irq(&ts->client->dev, ts->client->irq, ts);
4285ab09d6aSIrina Tirdea }
4295ab09d6aSIrina Tirdea 
4305ab09d6aSIrina Tirdea static int goodix_request_irq(struct goodix_ts_data *ts)
4315ab09d6aSIrina Tirdea {
4325ab09d6aSIrina Tirdea 	return devm_request_threaded_irq(&ts->client->dev, ts->client->irq,
4335ab09d6aSIrina Tirdea 					 NULL, goodix_ts_irq_handler,
4345ab09d6aSIrina Tirdea 					 ts->irq_flags, ts->client->name, ts);
4355ab09d6aSIrina Tirdea }
4365ab09d6aSIrina Tirdea 
43725309004SMarcin Niestroj static int goodix_check_cfg_8(struct goodix_ts_data *ts,
43868caf858SIrina Tirdea 			const struct firmware *cfg)
43968caf858SIrina Tirdea {
44025309004SMarcin Niestroj 	int i, raw_cfg_len = cfg->size - 2;
44168caf858SIrina Tirdea 	u8 check_sum = 0;
44268caf858SIrina Tirdea 
44368caf858SIrina Tirdea 	for (i = 0; i < raw_cfg_len; i++)
44468caf858SIrina Tirdea 		check_sum += cfg->data[i];
44568caf858SIrina Tirdea 	check_sum = (~check_sum) + 1;
44668caf858SIrina Tirdea 	if (check_sum != cfg->data[raw_cfg_len]) {
44768caf858SIrina Tirdea 		dev_err(&ts->client->dev,
44868caf858SIrina Tirdea 			"The checksum of the config fw is not correct");
44968caf858SIrina Tirdea 		return -EINVAL;
45068caf858SIrina Tirdea 	}
45168caf858SIrina Tirdea 
45268caf858SIrina Tirdea 	if (cfg->data[raw_cfg_len + 1] != 1) {
45368caf858SIrina Tirdea 		dev_err(&ts->client->dev,
45468caf858SIrina Tirdea 			"Config fw must have Config_Fresh register set");
45568caf858SIrina Tirdea 		return -EINVAL;
45668caf858SIrina Tirdea 	}
45768caf858SIrina Tirdea 
45868caf858SIrina Tirdea 	return 0;
45968caf858SIrina Tirdea }
46068caf858SIrina Tirdea 
46125309004SMarcin Niestroj static int goodix_check_cfg_16(struct goodix_ts_data *ts,
46225309004SMarcin Niestroj 			const struct firmware *cfg)
46325309004SMarcin Niestroj {
46425309004SMarcin Niestroj 	int i, raw_cfg_len = cfg->size - 3;
46525309004SMarcin Niestroj 	u16 check_sum = 0;
46625309004SMarcin Niestroj 
46725309004SMarcin Niestroj 	for (i = 0; i < raw_cfg_len; i += 2)
46825309004SMarcin Niestroj 		check_sum += get_unaligned_be16(&cfg->data[i]);
46925309004SMarcin Niestroj 	check_sum = (~check_sum) + 1;
47025309004SMarcin Niestroj 	if (check_sum != get_unaligned_be16(&cfg->data[raw_cfg_len])) {
47125309004SMarcin Niestroj 		dev_err(&ts->client->dev,
47225309004SMarcin Niestroj 			"The checksum of the config fw is not correct");
47325309004SMarcin Niestroj 		return -EINVAL;
47425309004SMarcin Niestroj 	}
47525309004SMarcin Niestroj 
47625309004SMarcin Niestroj 	if (cfg->data[raw_cfg_len + 2] != 1) {
47725309004SMarcin Niestroj 		dev_err(&ts->client->dev,
47825309004SMarcin Niestroj 			"Config fw must have Config_Fresh register set");
47925309004SMarcin Niestroj 		return -EINVAL;
48025309004SMarcin Niestroj 	}
48125309004SMarcin Niestroj 
48225309004SMarcin Niestroj 	return 0;
48325309004SMarcin Niestroj }
48425309004SMarcin Niestroj 
48525309004SMarcin Niestroj /**
48625309004SMarcin Niestroj  * goodix_check_cfg - Checks if config fw is valid
48725309004SMarcin Niestroj  *
48825309004SMarcin Niestroj  * @ts: goodix_ts_data pointer
48925309004SMarcin Niestroj  * @cfg: firmware config data
49025309004SMarcin Niestroj  */
49125309004SMarcin Niestroj static int goodix_check_cfg(struct goodix_ts_data *ts,
49225309004SMarcin Niestroj 			    const struct firmware *cfg)
49325309004SMarcin Niestroj {
49425309004SMarcin Niestroj 	if (cfg->size > GOODIX_CONFIG_MAX_LENGTH) {
49525309004SMarcin Niestroj 		dev_err(&ts->client->dev,
49625309004SMarcin Niestroj 			"The length of the config fw is not correct");
49725309004SMarcin Niestroj 		return -EINVAL;
49825309004SMarcin Niestroj 	}
49925309004SMarcin Niestroj 
50025309004SMarcin Niestroj 	return ts->chip->check_config(ts, cfg);
50125309004SMarcin Niestroj }
50225309004SMarcin Niestroj 
50368caf858SIrina Tirdea /**
50468caf858SIrina Tirdea  * goodix_send_cfg - Write fw config to device
50568caf858SIrina Tirdea  *
50668caf858SIrina Tirdea  * @ts: goodix_ts_data pointer
50768caf858SIrina Tirdea  * @cfg: config firmware to write to device
50868caf858SIrina Tirdea  */
50968caf858SIrina Tirdea static int goodix_send_cfg(struct goodix_ts_data *ts,
51068caf858SIrina Tirdea 			   const struct firmware *cfg)
51168caf858SIrina Tirdea {
51268caf858SIrina Tirdea 	int error;
51368caf858SIrina Tirdea 
51468caf858SIrina Tirdea 	error = goodix_check_cfg(ts, cfg);
51568caf858SIrina Tirdea 	if (error)
51668caf858SIrina Tirdea 		return error;
51768caf858SIrina Tirdea 
51825309004SMarcin Niestroj 	error = goodix_i2c_write(ts->client, ts->chip->config_addr, cfg->data,
51968caf858SIrina Tirdea 				 cfg->size);
52068caf858SIrina Tirdea 	if (error) {
52168caf858SIrina Tirdea 		dev_err(&ts->client->dev, "Failed to write config data: %d",
52268caf858SIrina Tirdea 			error);
52368caf858SIrina Tirdea 		return error;
52468caf858SIrina Tirdea 	}
52568caf858SIrina Tirdea 	dev_dbg(&ts->client->dev, "Config sent successfully.");
52668caf858SIrina Tirdea 
52768caf858SIrina Tirdea 	/* Let the firmware reconfigure itself, so sleep for 10ms */
52868caf858SIrina Tirdea 	usleep_range(10000, 11000);
52968caf858SIrina Tirdea 
53068caf858SIrina Tirdea 	return 0;
53168caf858SIrina Tirdea }
53268caf858SIrina Tirdea 
53349db3997SHans de Goede static int goodix_irq_direction_output(struct goodix_ts_data *ts,
53449db3997SHans de Goede 				       int value)
53549db3997SHans de Goede {
536c5fca485SHans de Goede 	struct device *dev = &ts->client->dev;
537c5fca485SHans de Goede 	acpi_status status;
538c5fca485SHans de Goede 
53949db3997SHans de Goede 	switch (ts->irq_pin_access_method) {
54049db3997SHans de Goede 	case IRQ_PIN_ACCESS_NONE:
54149db3997SHans de Goede 		dev_err(&ts->client->dev,
54249db3997SHans de Goede 			"%s called without an irq_pin_access_method set\n",
54349db3997SHans de Goede 			__func__);
54449db3997SHans de Goede 		return -EINVAL;
54549db3997SHans de Goede 	case IRQ_PIN_ACCESS_GPIO:
54649db3997SHans de Goede 		return gpiod_direction_output(ts->gpiod_int, value);
547a7d4b171SHans de Goede 	case IRQ_PIN_ACCESS_ACPI_GPIO:
548a7d4b171SHans de Goede 		/*
549a7d4b171SHans de Goede 		 * The IRQ pin triggers on a falling edge, so its gets marked
550a7d4b171SHans de Goede 		 * as active-low, use output_raw to avoid the value inversion.
551a7d4b171SHans de Goede 		 */
552a7d4b171SHans de Goede 		return gpiod_direction_output_raw(ts->gpiod_int, value);
553c5fca485SHans de Goede 	case IRQ_PIN_ACCESS_ACPI_METHOD:
554c5fca485SHans de Goede 		status = acpi_execute_simple_method(ACPI_HANDLE(dev),
555c5fca485SHans de Goede 						    "INTO", value);
556c5fca485SHans de Goede 		return ACPI_SUCCESS(status) ? 0 : -EIO;
55749db3997SHans de Goede 	}
55849db3997SHans de Goede 
55949db3997SHans de Goede 	return -EINVAL; /* Never reached */
56049db3997SHans de Goede }
56149db3997SHans de Goede 
56249db3997SHans de Goede static int goodix_irq_direction_input(struct goodix_ts_data *ts)
56349db3997SHans de Goede {
564c5fca485SHans de Goede 	struct device *dev = &ts->client->dev;
565c5fca485SHans de Goede 	acpi_status status;
566c5fca485SHans de Goede 
56749db3997SHans de Goede 	switch (ts->irq_pin_access_method) {
56849db3997SHans de Goede 	case IRQ_PIN_ACCESS_NONE:
56949db3997SHans de Goede 		dev_err(&ts->client->dev,
57049db3997SHans de Goede 			"%s called without an irq_pin_access_method set\n",
57149db3997SHans de Goede 			__func__);
57249db3997SHans de Goede 		return -EINVAL;
57349db3997SHans de Goede 	case IRQ_PIN_ACCESS_GPIO:
574a7d4b171SHans de Goede 	case IRQ_PIN_ACCESS_ACPI_GPIO:
57549db3997SHans de Goede 		return gpiod_direction_input(ts->gpiod_int);
576c5fca485SHans de Goede 	case IRQ_PIN_ACCESS_ACPI_METHOD:
577c5fca485SHans de Goede 		status = acpi_evaluate_object(ACPI_HANDLE(dev), "INTI",
578c5fca485SHans de Goede 					      NULL, NULL);
579c5fca485SHans de Goede 		return ACPI_SUCCESS(status) ? 0 : -EIO;
58049db3997SHans de Goede 	}
58149db3997SHans de Goede 
58249db3997SHans de Goede 	return -EINVAL; /* Never reached */
58349db3997SHans de Goede }
58449db3997SHans de Goede 
585ec6e1b40SIrina Tirdea static int goodix_int_sync(struct goodix_ts_data *ts)
586ec6e1b40SIrina Tirdea {
587ec6e1b40SIrina Tirdea 	int error;
588ec6e1b40SIrina Tirdea 
58949db3997SHans de Goede 	error = goodix_irq_direction_output(ts, 0);
590ec6e1b40SIrina Tirdea 	if (error)
591ec6e1b40SIrina Tirdea 		return error;
592ec6e1b40SIrina Tirdea 
593ec6e1b40SIrina Tirdea 	msleep(50);				/* T5: 50ms */
594ec6e1b40SIrina Tirdea 
59549db3997SHans de Goede 	error = goodix_irq_direction_input(ts);
596ec6e1b40SIrina Tirdea 	if (error)
597ec6e1b40SIrina Tirdea 		return error;
598ec6e1b40SIrina Tirdea 
599ec6e1b40SIrina Tirdea 	return 0;
600ec6e1b40SIrina Tirdea }
601ec6e1b40SIrina Tirdea 
602ec6e1b40SIrina Tirdea /**
603ec6e1b40SIrina Tirdea  * goodix_reset - Reset device during power on
604ec6e1b40SIrina Tirdea  *
605ec6e1b40SIrina Tirdea  * @ts: goodix_ts_data pointer
606ec6e1b40SIrina Tirdea  */
607ec6e1b40SIrina Tirdea static int goodix_reset(struct goodix_ts_data *ts)
608ec6e1b40SIrina Tirdea {
609ec6e1b40SIrina Tirdea 	int error;
610ec6e1b40SIrina Tirdea 
611ec6e1b40SIrina Tirdea 	/* begin select I2C slave addr */
612ec6e1b40SIrina Tirdea 	error = gpiod_direction_output(ts->gpiod_rst, 0);
613ec6e1b40SIrina Tirdea 	if (error)
614ec6e1b40SIrina Tirdea 		return error;
615ec6e1b40SIrina Tirdea 
616ec6e1b40SIrina Tirdea 	msleep(20);				/* T2: > 10ms */
617ec6e1b40SIrina Tirdea 
618ec6e1b40SIrina Tirdea 	/* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
61949db3997SHans de Goede 	error = goodix_irq_direction_output(ts, ts->client->addr == 0x14);
620ec6e1b40SIrina Tirdea 	if (error)
621ec6e1b40SIrina Tirdea 		return error;
622ec6e1b40SIrina Tirdea 
623ec6e1b40SIrina Tirdea 	usleep_range(100, 2000);		/* T3: > 100us */
624ec6e1b40SIrina Tirdea 
625ec6e1b40SIrina Tirdea 	error = gpiod_direction_output(ts->gpiod_rst, 1);
626ec6e1b40SIrina Tirdea 	if (error)
627ec6e1b40SIrina Tirdea 		return error;
628ec6e1b40SIrina Tirdea 
629ec6e1b40SIrina Tirdea 	usleep_range(6000, 10000);		/* T4: > 5ms */
630ec6e1b40SIrina Tirdea 
631ec6e1b40SIrina Tirdea 	/* end select I2C slave addr */
632ec6e1b40SIrina Tirdea 	error = gpiod_direction_input(ts->gpiod_rst);
633ec6e1b40SIrina Tirdea 	if (error)
634ec6e1b40SIrina Tirdea 		return error;
635ec6e1b40SIrina Tirdea 
636ec6e1b40SIrina Tirdea 	error = goodix_int_sync(ts);
637ec6e1b40SIrina Tirdea 	if (error)
638ec6e1b40SIrina Tirdea 		return error;
639ec6e1b40SIrina Tirdea 
640ec6e1b40SIrina Tirdea 	return 0;
641ec6e1b40SIrina Tirdea }
642ec6e1b40SIrina Tirdea 
643a7d4b171SHans de Goede #if defined CONFIG_X86 && defined CONFIG_ACPI
64467abd9eeSHans de Goede #include <asm/cpu_device_id.h>
64567abd9eeSHans de Goede #include <asm/intel-family.h>
64667abd9eeSHans de Goede 
64767abd9eeSHans de Goede static const struct x86_cpu_id baytrail_cpu_ids[] = {
64867abd9eeSHans de Goede 	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT, X86_FEATURE_ANY, },
64967abd9eeSHans de Goede 	{}
65067abd9eeSHans de Goede };
65167abd9eeSHans de Goede 
65267abd9eeSHans de Goede static inline bool is_byt(void)
65367abd9eeSHans de Goede {
65467abd9eeSHans de Goede 	const struct x86_cpu_id *id = x86_match_cpu(baytrail_cpu_ids);
65567abd9eeSHans de Goede 
65667abd9eeSHans de Goede 	return !!id;
65767abd9eeSHans de Goede }
65867abd9eeSHans de Goede 
659a7d4b171SHans de Goede static const struct acpi_gpio_params first_gpio = { 0, 0, false };
660a7d4b171SHans de Goede static const struct acpi_gpio_params second_gpio = { 1, 0, false };
661a7d4b171SHans de Goede 
662a7d4b171SHans de Goede static const struct acpi_gpio_mapping acpi_goodix_int_first_gpios[] = {
663a7d4b171SHans de Goede 	{ GOODIX_GPIO_INT_NAME "-gpios", &first_gpio, 1 },
664a7d4b171SHans de Goede 	{ GOODIX_GPIO_RST_NAME "-gpios", &second_gpio, 1 },
665a7d4b171SHans de Goede 	{ },
666a7d4b171SHans de Goede };
667a7d4b171SHans de Goede 
668a7d4b171SHans de Goede static const struct acpi_gpio_mapping acpi_goodix_int_last_gpios[] = {
669a7d4b171SHans de Goede 	{ GOODIX_GPIO_RST_NAME "-gpios", &first_gpio, 1 },
670a7d4b171SHans de Goede 	{ GOODIX_GPIO_INT_NAME "-gpios", &second_gpio, 1 },
671a7d4b171SHans de Goede 	{ },
672a7d4b171SHans de Goede };
673a7d4b171SHans de Goede 
674c5fca485SHans de Goede static const struct acpi_gpio_mapping acpi_goodix_reset_only_gpios[] = {
675c5fca485SHans de Goede 	{ GOODIX_GPIO_RST_NAME "-gpios", &first_gpio, 1 },
676c5fca485SHans de Goede 	{ },
677c5fca485SHans de Goede };
678c5fca485SHans de Goede 
679a7d4b171SHans de Goede static int goodix_resource(struct acpi_resource *ares, void *data)
680a7d4b171SHans de Goede {
681a7d4b171SHans de Goede 	struct goodix_ts_data *ts = data;
682a7d4b171SHans de Goede 	struct device *dev = &ts->client->dev;
683a7d4b171SHans de Goede 	struct acpi_resource_gpio *gpio;
684a7d4b171SHans de Goede 
685a7d4b171SHans de Goede 	switch (ares->type) {
686a7d4b171SHans de Goede 	case ACPI_RESOURCE_TYPE_GPIO:
687a7d4b171SHans de Goede 		gpio = &ares->data.gpio;
688a7d4b171SHans de Goede 		if (gpio->connection_type == ACPI_RESOURCE_GPIO_TYPE_INT) {
689a7d4b171SHans de Goede 			if (ts->gpio_int_idx == -1) {
690a7d4b171SHans de Goede 				ts->gpio_int_idx = ts->gpio_count;
691a7d4b171SHans de Goede 			} else {
692a7d4b171SHans de Goede 				dev_err(dev, "More then one GpioInt resource, ignoring ACPI GPIO resources\n");
693a7d4b171SHans de Goede 				ts->gpio_int_idx = -2;
694a7d4b171SHans de Goede 			}
695a7d4b171SHans de Goede 		}
696a7d4b171SHans de Goede 		ts->gpio_count++;
697a7d4b171SHans de Goede 		break;
698a7d4b171SHans de Goede 	default:
699a7d4b171SHans de Goede 		break;
700a7d4b171SHans de Goede 	}
701a7d4b171SHans de Goede 
702a7d4b171SHans de Goede 	return 0;
703a7d4b171SHans de Goede }
704a7d4b171SHans de Goede 
705a7d4b171SHans de Goede /*
706a7d4b171SHans de Goede  * This function gets called in case we fail to get the irq GPIO directly
707a7d4b171SHans de Goede  * because the ACPI tables lack GPIO-name to APCI _CRS index mappings
708a7d4b171SHans de Goede  * (no _DSD UUID daffd814-6eba-4d8c-8a91-bc9bbf4aa301 data).
709a7d4b171SHans de Goede  * In that case we add our own mapping and then goodix_get_gpio_config()
710a7d4b171SHans de Goede  * retries to get the GPIOs based on the added mapping.
711a7d4b171SHans de Goede  */
712a7d4b171SHans de Goede static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
713a7d4b171SHans de Goede {
714a7d4b171SHans de Goede 	const struct acpi_gpio_mapping *gpio_mapping = NULL;
715a7d4b171SHans de Goede 	struct device *dev = &ts->client->dev;
716a7d4b171SHans de Goede 	LIST_HEAD(resources);
717a7d4b171SHans de Goede 	int ret;
718a7d4b171SHans de Goede 
719a7d4b171SHans de Goede 	ts->gpio_count = 0;
720a7d4b171SHans de Goede 	ts->gpio_int_idx = -1;
721a7d4b171SHans de Goede 	ret = acpi_dev_get_resources(ACPI_COMPANION(dev), &resources,
722a7d4b171SHans de Goede 				     goodix_resource, ts);
723a7d4b171SHans de Goede 	if (ret < 0) {
724a7d4b171SHans de Goede 		dev_err(dev, "Error getting ACPI resources: %d\n", ret);
725a7d4b171SHans de Goede 		return ret;
726a7d4b171SHans de Goede 	}
727a7d4b171SHans de Goede 
728a7d4b171SHans de Goede 	acpi_dev_free_resource_list(&resources);
729a7d4b171SHans de Goede 
730a7d4b171SHans de Goede 	if (ts->gpio_count == 2 && ts->gpio_int_idx == 0) {
731a7d4b171SHans de Goede 		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
732a7d4b171SHans de Goede 		gpio_mapping = acpi_goodix_int_first_gpios;
733a7d4b171SHans de Goede 	} else if (ts->gpio_count == 2 && ts->gpio_int_idx == 1) {
734a7d4b171SHans de Goede 		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
735a7d4b171SHans de Goede 		gpio_mapping = acpi_goodix_int_last_gpios;
736c5fca485SHans de Goede 	} else if (ts->gpio_count == 1 && ts->gpio_int_idx == -1 &&
737c5fca485SHans de Goede 		   acpi_has_method(ACPI_HANDLE(dev), "INTI") &&
738c5fca485SHans de Goede 		   acpi_has_method(ACPI_HANDLE(dev), "INTO")) {
739c5fca485SHans de Goede 		dev_info(dev, "Using ACPI INTI and INTO methods for IRQ pin access\n");
740c5fca485SHans de Goede 		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_METHOD;
741c5fca485SHans de Goede 		gpio_mapping = acpi_goodix_reset_only_gpios;
74267abd9eeSHans de Goede 	} else if (is_byt() && ts->gpio_count == 2 && ts->gpio_int_idx == -1) {
74367abd9eeSHans de Goede 		dev_info(dev, "No ACPI GpioInt resource, assuming that the GPIO order is reset, int\n");
74467abd9eeSHans de Goede 		ts->irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO;
74567abd9eeSHans de Goede 		gpio_mapping = acpi_goodix_int_last_gpios;
746a7d4b171SHans de Goede 	} else {
747a7d4b171SHans de Goede 		dev_warn(dev, "Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d\n",
748a7d4b171SHans de Goede 			 ts->gpio_count, ts->gpio_int_idx);
749a7d4b171SHans de Goede 		return -EINVAL;
750a7d4b171SHans de Goede 	}
751a7d4b171SHans de Goede 
752a7d4b171SHans de Goede 	return devm_acpi_dev_add_driver_gpios(dev, gpio_mapping);
753a7d4b171SHans de Goede }
754a7d4b171SHans de Goede #else
755a7d4b171SHans de Goede static int goodix_add_acpi_gpio_mappings(struct goodix_ts_data *ts)
756a7d4b171SHans de Goede {
757a7d4b171SHans de Goede 	return -EINVAL;
758a7d4b171SHans de Goede }
759a7d4b171SHans de Goede #endif /* CONFIG_X86 && CONFIG_ACPI */
760a7d4b171SHans de Goede 
761ec6e1b40SIrina Tirdea /**
762ec6e1b40SIrina Tirdea  * goodix_get_gpio_config - Get GPIO config from ACPI/DT
763ec6e1b40SIrina Tirdea  *
764ec6e1b40SIrina Tirdea  * @ts: goodix_ts_data pointer
765ec6e1b40SIrina Tirdea  */
766ec6e1b40SIrina Tirdea static int goodix_get_gpio_config(struct goodix_ts_data *ts)
767ec6e1b40SIrina Tirdea {
768ec6e1b40SIrina Tirdea 	int error;
769ec6e1b40SIrina Tirdea 	struct device *dev;
770ec6e1b40SIrina Tirdea 	struct gpio_desc *gpiod;
771a7d4b171SHans de Goede 	bool added_acpi_mappings = false;
772ec6e1b40SIrina Tirdea 
773ec6e1b40SIrina Tirdea 	if (!ts->client)
774ec6e1b40SIrina Tirdea 		return -EINVAL;
775ec6e1b40SIrina Tirdea 	dev = &ts->client->dev;
776ec6e1b40SIrina Tirdea 
777ae97fb58SJagan Teki 	ts->avdd28 = devm_regulator_get(dev, "AVDD28");
778ae97fb58SJagan Teki 	if (IS_ERR(ts->avdd28)) {
779ae97fb58SJagan Teki 		error = PTR_ERR(ts->avdd28);
780ae97fb58SJagan Teki 		if (error != -EPROBE_DEFER)
781ae97fb58SJagan Teki 			dev_err(dev,
782ae97fb58SJagan Teki 				"Failed to get AVDD28 regulator: %d\n", error);
783ae97fb58SJagan Teki 		return error;
784ae97fb58SJagan Teki 	}
785ae97fb58SJagan Teki 
786ae97fb58SJagan Teki 	ts->vddio = devm_regulator_get(dev, "VDDIO");
787ae97fb58SJagan Teki 	if (IS_ERR(ts->vddio)) {
788ae97fb58SJagan Teki 		error = PTR_ERR(ts->vddio);
789ae97fb58SJagan Teki 		if (error != -EPROBE_DEFER)
790ae97fb58SJagan Teki 			dev_err(dev,
791ae97fb58SJagan Teki 				"Failed to get VDDIO regulator: %d\n", error);
792ae97fb58SJagan Teki 		return error;
793ae97fb58SJagan Teki 	}
794ae97fb58SJagan Teki 
795a7d4b171SHans de Goede retry_get_irq_gpio:
796ec6e1b40SIrina Tirdea 	/* Get the interrupt GPIO pin number */
797ec6e1b40SIrina Tirdea 	gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_INT_NAME, GPIOD_IN);
798ec6e1b40SIrina Tirdea 	if (IS_ERR(gpiod)) {
799ec6e1b40SIrina Tirdea 		error = PTR_ERR(gpiod);
800ec6e1b40SIrina Tirdea 		if (error != -EPROBE_DEFER)
801ec6e1b40SIrina Tirdea 			dev_dbg(dev, "Failed to get %s GPIO: %d\n",
802ec6e1b40SIrina Tirdea 				GOODIX_GPIO_INT_NAME, error);
803ec6e1b40SIrina Tirdea 		return error;
804ec6e1b40SIrina Tirdea 	}
805a7d4b171SHans de Goede 	if (!gpiod && has_acpi_companion(dev) && !added_acpi_mappings) {
806a7d4b171SHans de Goede 		added_acpi_mappings = true;
807a7d4b171SHans de Goede 		if (goodix_add_acpi_gpio_mappings(ts) == 0)
808a7d4b171SHans de Goede 			goto retry_get_irq_gpio;
809a7d4b171SHans de Goede 	}
810ec6e1b40SIrina Tirdea 
811ec6e1b40SIrina Tirdea 	ts->gpiod_int = gpiod;
812ec6e1b40SIrina Tirdea 
813ec6e1b40SIrina Tirdea 	/* Get the reset line GPIO pin number */
814ec6e1b40SIrina Tirdea 	gpiod = devm_gpiod_get_optional(dev, GOODIX_GPIO_RST_NAME, GPIOD_IN);
815ec6e1b40SIrina Tirdea 	if (IS_ERR(gpiod)) {
816ec6e1b40SIrina Tirdea 		error = PTR_ERR(gpiod);
817ec6e1b40SIrina Tirdea 		if (error != -EPROBE_DEFER)
818ec6e1b40SIrina Tirdea 			dev_dbg(dev, "Failed to get %s GPIO: %d\n",
819ec6e1b40SIrina Tirdea 				GOODIX_GPIO_RST_NAME, error);
820ec6e1b40SIrina Tirdea 		return error;
821ec6e1b40SIrina Tirdea 	}
822ec6e1b40SIrina Tirdea 
823ec6e1b40SIrina Tirdea 	ts->gpiod_rst = gpiod;
824ec6e1b40SIrina Tirdea 
825a7d4b171SHans de Goede 	switch (ts->irq_pin_access_method) {
826a7d4b171SHans de Goede 	case IRQ_PIN_ACCESS_ACPI_GPIO:
827a7d4b171SHans de Goede 		/*
828a7d4b171SHans de Goede 		 * We end up here if goodix_add_acpi_gpio_mappings() has
829a7d4b171SHans de Goede 		 * called devm_acpi_dev_add_driver_gpios() because the ACPI
830a7d4b171SHans de Goede 		 * tables did not contain name to index mappings.
831a7d4b171SHans de Goede 		 * Check that we successfully got both GPIOs after we've
832a7d4b171SHans de Goede 		 * added our own acpi_gpio_mapping and if we did not get both
833a7d4b171SHans de Goede 		 * GPIOs reset irq_pin_access_method to IRQ_PIN_ACCESS_NONE.
834a7d4b171SHans de Goede 		 */
835a7d4b171SHans de Goede 		if (!ts->gpiod_int || !ts->gpiod_rst)
836a7d4b171SHans de Goede 			ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE;
837a7d4b171SHans de Goede 		break;
838c5fca485SHans de Goede 	case IRQ_PIN_ACCESS_ACPI_METHOD:
839c5fca485SHans de Goede 		if (!ts->gpiod_rst)
840c5fca485SHans de Goede 			ts->irq_pin_access_method = IRQ_PIN_ACCESS_NONE;
841c5fca485SHans de Goede 		break;
842a7d4b171SHans de Goede 	default:
843e070a97bSHans de Goede 		if (ts->gpiod_int && ts->gpiod_rst) {
8441921daceSHans de Goede 			ts->reset_controller_at_probe = true;
845e070a97bSHans de Goede 			ts->load_cfg_from_disk = true;
84649db3997SHans de Goede 			ts->irq_pin_access_method = IRQ_PIN_ACCESS_GPIO;
847e070a97bSHans de Goede 		}
848a7d4b171SHans de Goede 	}
84949db3997SHans de Goede 
850ec6e1b40SIrina Tirdea 	return 0;
851ec6e1b40SIrina Tirdea }
852ec6e1b40SIrina Tirdea 
853ca96ea86SBastien Nocera /**
854ca96ea86SBastien Nocera  * goodix_read_config - Read the embedded configuration of the panel
855ca96ea86SBastien Nocera  *
856ca96ea86SBastien Nocera  * @ts: our goodix_ts_data pointer
857ca96ea86SBastien Nocera  *
858ca96ea86SBastien Nocera  * Must be called during probe
859ca96ea86SBastien Nocera  */
860ca96ea86SBastien Nocera static void goodix_read_config(struct goodix_ts_data *ts)
861ca96ea86SBastien Nocera {
862ca96ea86SBastien Nocera 	u8 config[GOODIX_CONFIG_MAX_LENGTH];
863fafef982SMarcin Niestroj 	int x_max, y_max;
864ca96ea86SBastien Nocera 	int error;
865ca96ea86SBastien Nocera 
86625309004SMarcin Niestroj 	error = goodix_i2c_read(ts->client, ts->chip->config_addr,
86725309004SMarcin Niestroj 				config, ts->chip->config_len);
868ca96ea86SBastien Nocera 	if (error) {
869fafef982SMarcin Niestroj 		dev_warn(&ts->client->dev, "Error reading config: %d\n",
870ca96ea86SBastien Nocera 			 error);
871ca96ea86SBastien Nocera 		ts->int_trigger_type = GOODIX_INT_TRIGGER;
872a7ac7c95SAleksei Mamlin 		ts->max_touch_num = GOODIX_MAX_CONTACTS;
873ca96ea86SBastien Nocera 		return;
874ca96ea86SBastien Nocera 	}
875ca96ea86SBastien Nocera 
876a7ac7c95SAleksei Mamlin 	ts->int_trigger_type = config[TRIGGER_LOC] & 0x03;
877a7ac7c95SAleksei Mamlin 	ts->max_touch_num = config[MAX_CONTACTS_LOC] & 0x0f;
8788b5a359cSBastien Nocera 
879fafef982SMarcin Niestroj 	x_max = get_unaligned_le16(&config[RESOLUTION_LOC]);
880fafef982SMarcin Niestroj 	y_max = get_unaligned_le16(&config[RESOLUTION_LOC + 2]);
881fafef982SMarcin Niestroj 	if (x_max && y_max) {
882fafef982SMarcin Niestroj 		input_abs_set_max(ts->input_dev, ABS_MT_POSITION_X, x_max - 1);
883fafef982SMarcin Niestroj 		input_abs_set_max(ts->input_dev, ABS_MT_POSITION_Y, y_max - 1);
884ca96ea86SBastien Nocera 	}
88557c80e8eSKarsten Merker }
886ca96ea86SBastien Nocera 
887ca96ea86SBastien Nocera /**
888ca96ea86SBastien Nocera  * goodix_read_version - Read goodix touchscreen version
889ca96ea86SBastien Nocera  *
89068caf858SIrina Tirdea  * @ts: our goodix_ts_data pointer
891ca96ea86SBastien Nocera  */
89268caf858SIrina Tirdea static int goodix_read_version(struct goodix_ts_data *ts)
893ca96ea86SBastien Nocera {
894ca96ea86SBastien Nocera 	int error;
895ca96ea86SBastien Nocera 	u8 buf[6];
896e70b0307SIrina Tirdea 	char id_str[5];
897ca96ea86SBastien Nocera 
89868caf858SIrina Tirdea 	error = goodix_i2c_read(ts->client, GOODIX_REG_ID, buf, sizeof(buf));
899ca96ea86SBastien Nocera 	if (error) {
90068caf858SIrina Tirdea 		dev_err(&ts->client->dev, "read version failed: %d\n", error);
901ca96ea86SBastien Nocera 		return error;
902ca96ea86SBastien Nocera 	}
903ca96ea86SBastien Nocera 
904e70b0307SIrina Tirdea 	memcpy(id_str, buf, 4);
905e70b0307SIrina Tirdea 	id_str[4] = 0;
90668caf858SIrina Tirdea 	if (kstrtou16(id_str, 10, &ts->id))
90768caf858SIrina Tirdea 		ts->id = 0x1001;
908e70b0307SIrina Tirdea 
90968caf858SIrina Tirdea 	ts->version = get_unaligned_le16(&buf[4]);
910ca96ea86SBastien Nocera 
91168caf858SIrina Tirdea 	dev_info(&ts->client->dev, "ID %d, version: %04x\n", ts->id,
91268caf858SIrina Tirdea 		 ts->version);
913ca96ea86SBastien Nocera 
914ca96ea86SBastien Nocera 	return 0;
915ca96ea86SBastien Nocera }
916ca96ea86SBastien Nocera 
917ca96ea86SBastien Nocera /**
918ca96ea86SBastien Nocera  * goodix_i2c_test - I2C test function to check if the device answers.
919ca96ea86SBastien Nocera  *
920ca96ea86SBastien Nocera  * @client: the i2c client
921ca96ea86SBastien Nocera  */
922ca96ea86SBastien Nocera static int goodix_i2c_test(struct i2c_client *client)
923ca96ea86SBastien Nocera {
924ca96ea86SBastien Nocera 	int retry = 0;
925ca96ea86SBastien Nocera 	int error;
926ca96ea86SBastien Nocera 	u8 test;
927ca96ea86SBastien Nocera 
928ca96ea86SBastien Nocera 	while (retry++ < 2) {
92925309004SMarcin Niestroj 		error = goodix_i2c_read(client, GOODIX_REG_ID,
930ca96ea86SBastien Nocera 					&test, 1);
931ca96ea86SBastien Nocera 		if (!error)
932ca96ea86SBastien Nocera 			return 0;
933ca96ea86SBastien Nocera 
934ca96ea86SBastien Nocera 		dev_err(&client->dev, "i2c test failed attempt %d: %d\n",
935ca96ea86SBastien Nocera 			retry, error);
936ca96ea86SBastien Nocera 		msleep(20);
937ca96ea86SBastien Nocera 	}
938ca96ea86SBastien Nocera 
939ca96ea86SBastien Nocera 	return error;
940ca96ea86SBastien Nocera }
941ca96ea86SBastien Nocera 
942ca96ea86SBastien Nocera /**
94368caf858SIrina Tirdea  * goodix_configure_dev - Finish device initialization
94468caf858SIrina Tirdea  *
94568caf858SIrina Tirdea  * @ts: our goodix_ts_data pointer
94668caf858SIrina Tirdea  *
94768caf858SIrina Tirdea  * Must be called from probe to finish initialization of the device.
94868caf858SIrina Tirdea  * Contains the common initialization code for both devices that
94968caf858SIrina Tirdea  * declare gpio pins and devices that do not. It is either called
95068caf858SIrina Tirdea  * directly from probe or from request_firmware_wait callback.
95168caf858SIrina Tirdea  */
95268caf858SIrina Tirdea static int goodix_configure_dev(struct goodix_ts_data *ts)
95368caf858SIrina Tirdea {
95468caf858SIrina Tirdea 	int error;
95568caf858SIrina Tirdea 
956fafef982SMarcin Niestroj 	ts->int_trigger_type = GOODIX_INT_TRIGGER;
957fafef982SMarcin Niestroj 	ts->max_touch_num = GOODIX_MAX_CONTACTS;
958ad48cf5eSKarsten Merker 
959fafef982SMarcin Niestroj 	ts->input_dev = devm_input_allocate_device(&ts->client->dev);
960fafef982SMarcin Niestroj 	if (!ts->input_dev) {
961fafef982SMarcin Niestroj 		dev_err(&ts->client->dev, "Failed to allocate input device.");
962fafef982SMarcin Niestroj 		return -ENOMEM;
963fafef982SMarcin Niestroj 	}
964fafef982SMarcin Niestroj 
965fafef982SMarcin Niestroj 	ts->input_dev->name = "Goodix Capacitive TouchScreen";
966fafef982SMarcin Niestroj 	ts->input_dev->phys = "input/ts";
967fafef982SMarcin Niestroj 	ts->input_dev->id.bustype = BUS_I2C;
968fafef982SMarcin Niestroj 	ts->input_dev->id.vendor = 0x0416;
969fafef982SMarcin Niestroj 	ts->input_dev->id.product = ts->id;
970fafef982SMarcin Niestroj 	ts->input_dev->id.version = ts->version;
971fafef982SMarcin Niestroj 
972fafef982SMarcin Niestroj 	/* Capacitive Windows/Home button on some devices */
973fafef982SMarcin Niestroj 	input_set_capability(ts->input_dev, EV_KEY, KEY_LEFTMETA);
974fafef982SMarcin Niestroj 
975fafef982SMarcin Niestroj 	input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_X);
976fafef982SMarcin Niestroj 	input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_Y);
977fafef982SMarcin Niestroj 	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
978fafef982SMarcin Niestroj 	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
979fafef982SMarcin Niestroj 
980fafef982SMarcin Niestroj 	/* Read configuration and apply touchscreen parameters */
98168caf858SIrina Tirdea 	goodix_read_config(ts);
98268caf858SIrina Tirdea 
983fafef982SMarcin Niestroj 	/* Try overriding touchscreen parameters via device properties */
984fafef982SMarcin Niestroj 	touchscreen_parse_properties(ts->input_dev, true, &ts->prop);
985fafef982SMarcin Niestroj 
986fafef982SMarcin Niestroj 	if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) {
987c1c00aa5SGuido Günther 		dev_err(&ts->client->dev,
988c1c00aa5SGuido Günther 			"Invalid config (%d, %d, %d), using defaults\n",
989c1c00aa5SGuido Günther 			ts->prop.max_x, ts->prop.max_y, ts->max_touch_num);
990fafef982SMarcin Niestroj 		ts->prop.max_x = GOODIX_MAX_WIDTH - 1;
991fafef982SMarcin Niestroj 		ts->prop.max_y = GOODIX_MAX_HEIGHT - 1;
992fafef982SMarcin Niestroj 		ts->max_touch_num = GOODIX_MAX_CONTACTS;
993fafef982SMarcin Niestroj 		input_abs_set_max(ts->input_dev,
994fafef982SMarcin Niestroj 				  ABS_MT_POSITION_X, ts->prop.max_x);
995fafef982SMarcin Niestroj 		input_abs_set_max(ts->input_dev,
996fafef982SMarcin Niestroj 				  ABS_MT_POSITION_Y, ts->prop.max_y);
997fafef982SMarcin Niestroj 	}
998fafef982SMarcin Niestroj 
999fafef982SMarcin Niestroj 	if (dmi_check_system(rotated_screen)) {
1000fafef982SMarcin Niestroj 		ts->prop.invert_x = true;
1001fafef982SMarcin Niestroj 		ts->prop.invert_y = true;
1002fafef982SMarcin Niestroj 		dev_dbg(&ts->client->dev,
1003fafef982SMarcin Niestroj 			"Applying '180 degrees rotated screen' quirk\n");
1004fafef982SMarcin Niestroj 	}
1005fafef982SMarcin Niestroj 
1006bd3b8480SYauhen Kharuzhy 	if (dmi_check_system(nine_bytes_report)) {
1007bd3b8480SYauhen Kharuzhy 		ts->contact_size = 9;
1008bd3b8480SYauhen Kharuzhy 
1009bd3b8480SYauhen Kharuzhy 		dev_dbg(&ts->client->dev,
1010bd3b8480SYauhen Kharuzhy 			"Non-standard 9-bytes report format quirk\n");
1011bd3b8480SYauhen Kharuzhy 	}
1012bd3b8480SYauhen Kharuzhy 
10131dd5ddc1SSergei A. Trusov 	if (dmi_check_system(inverted_x_screen)) {
10141dd5ddc1SSergei A. Trusov 		ts->prop.invert_x = true;
10151dd5ddc1SSergei A. Trusov 		dev_dbg(&ts->client->dev,
10161dd5ddc1SSergei A. Trusov 			"Applying 'inverted x screen' quirk\n");
10171dd5ddc1SSergei A. Trusov 	}
10181dd5ddc1SSergei A. Trusov 
1019fafef982SMarcin Niestroj 	error = input_mt_init_slots(ts->input_dev, ts->max_touch_num,
1020fafef982SMarcin Niestroj 				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
1021fafef982SMarcin Niestroj 	if (error) {
1022fafef982SMarcin Niestroj 		dev_err(&ts->client->dev,
1023fafef982SMarcin Niestroj 			"Failed to initialize MT slots: %d", error);
102468caf858SIrina Tirdea 		return error;
1025fafef982SMarcin Niestroj 	}
1026fafef982SMarcin Niestroj 
1027fafef982SMarcin Niestroj 	error = input_register_device(ts->input_dev);
1028fafef982SMarcin Niestroj 	if (error) {
1029fafef982SMarcin Niestroj 		dev_err(&ts->client->dev,
1030fafef982SMarcin Niestroj 			"Failed to register input device: %d", error);
1031fafef982SMarcin Niestroj 		return error;
1032fafef982SMarcin Niestroj 	}
103368caf858SIrina Tirdea 
10345ab09d6aSIrina Tirdea 	ts->irq_flags = goodix_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT;
10355ab09d6aSIrina Tirdea 	error = goodix_request_irq(ts);
103668caf858SIrina Tirdea 	if (error) {
103768caf858SIrina Tirdea 		dev_err(&ts->client->dev, "request IRQ failed: %d\n", error);
103868caf858SIrina Tirdea 		return error;
103968caf858SIrina Tirdea 	}
104068caf858SIrina Tirdea 
104168caf858SIrina Tirdea 	return 0;
104268caf858SIrina Tirdea }
104368caf858SIrina Tirdea 
104468caf858SIrina Tirdea /**
104568caf858SIrina Tirdea  * goodix_config_cb - Callback to finish device init
104668caf858SIrina Tirdea  *
104768caf858SIrina Tirdea  * @ts: our goodix_ts_data pointer
104868caf858SIrina Tirdea  *
104968caf858SIrina Tirdea  * request_firmware_wait callback that finishes
105068caf858SIrina Tirdea  * initialization of the device.
105168caf858SIrina Tirdea  */
105268caf858SIrina Tirdea static void goodix_config_cb(const struct firmware *cfg, void *ctx)
105368caf858SIrina Tirdea {
105468caf858SIrina Tirdea 	struct goodix_ts_data *ts = ctx;
105568caf858SIrina Tirdea 	int error;
105668caf858SIrina Tirdea 
105768caf858SIrina Tirdea 	if (cfg) {
105868caf858SIrina Tirdea 		/* send device configuration to the firmware */
105968caf858SIrina Tirdea 		error = goodix_send_cfg(ts, cfg);
106068caf858SIrina Tirdea 		if (error)
106168caf858SIrina Tirdea 			goto err_release_cfg;
106268caf858SIrina Tirdea 	}
106368caf858SIrina Tirdea 
106468caf858SIrina Tirdea 	goodix_configure_dev(ts);
106568caf858SIrina Tirdea 
106668caf858SIrina Tirdea err_release_cfg:
106768caf858SIrina Tirdea 	release_firmware(cfg);
106868caf858SIrina Tirdea 	complete_all(&ts->firmware_loading_complete);
106968caf858SIrina Tirdea }
107068caf858SIrina Tirdea 
1071ae97fb58SJagan Teki static void goodix_disable_regulators(void *arg)
1072ae97fb58SJagan Teki {
1073ae97fb58SJagan Teki 	struct goodix_ts_data *ts = arg;
1074ae97fb58SJagan Teki 
1075ae97fb58SJagan Teki 	regulator_disable(ts->vddio);
1076ae97fb58SJagan Teki 	regulator_disable(ts->avdd28);
1077ae97fb58SJagan Teki }
1078ae97fb58SJagan Teki 
1079ca96ea86SBastien Nocera static int goodix_ts_probe(struct i2c_client *client,
1080ca96ea86SBastien Nocera 			   const struct i2c_device_id *id)
1081ca96ea86SBastien Nocera {
1082ca96ea86SBastien Nocera 	struct goodix_ts_data *ts;
1083ca96ea86SBastien Nocera 	int error;
1084ca96ea86SBastien Nocera 
1085ca96ea86SBastien Nocera 	dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr);
1086ca96ea86SBastien Nocera 
1087ca96ea86SBastien Nocera 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1088ca96ea86SBastien Nocera 		dev_err(&client->dev, "I2C check functionality failed.\n");
1089ca96ea86SBastien Nocera 		return -ENXIO;
1090ca96ea86SBastien Nocera 	}
1091ca96ea86SBastien Nocera 
1092ca96ea86SBastien Nocera 	ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL);
1093ca96ea86SBastien Nocera 	if (!ts)
1094ca96ea86SBastien Nocera 		return -ENOMEM;
1095ca96ea86SBastien Nocera 
1096ca96ea86SBastien Nocera 	ts->client = client;
1097ca96ea86SBastien Nocera 	i2c_set_clientdata(client, ts);
109868caf858SIrina Tirdea 	init_completion(&ts->firmware_loading_complete);
1099bd3b8480SYauhen Kharuzhy 	ts->contact_size = GOODIX_CONTACT_SIZE;
1100ca96ea86SBastien Nocera 
1101ec6e1b40SIrina Tirdea 	error = goodix_get_gpio_config(ts);
1102ec6e1b40SIrina Tirdea 	if (error)
1103ec6e1b40SIrina Tirdea 		return error;
1104ec6e1b40SIrina Tirdea 
1105ae97fb58SJagan Teki 	/* power up the controller */
1106ae97fb58SJagan Teki 	error = regulator_enable(ts->avdd28);
1107ae97fb58SJagan Teki 	if (error) {
1108ae97fb58SJagan Teki 		dev_err(&client->dev,
1109ae97fb58SJagan Teki 			"Failed to enable AVDD28 regulator: %d\n",
1110ae97fb58SJagan Teki 			error);
1111ae97fb58SJagan Teki 		return error;
1112ae97fb58SJagan Teki 	}
1113ae97fb58SJagan Teki 
1114ae97fb58SJagan Teki 	error = regulator_enable(ts->vddio);
1115ae97fb58SJagan Teki 	if (error) {
1116ae97fb58SJagan Teki 		dev_err(&client->dev,
1117ae97fb58SJagan Teki 			"Failed to enable VDDIO regulator: %d\n",
1118ae97fb58SJagan Teki 			error);
1119ae97fb58SJagan Teki 		regulator_disable(ts->avdd28);
1120ae97fb58SJagan Teki 		return error;
1121ae97fb58SJagan Teki 	}
1122ae97fb58SJagan Teki 
1123ae97fb58SJagan Teki 	error = devm_add_action_or_reset(&client->dev,
1124ae97fb58SJagan Teki 					 goodix_disable_regulators, ts);
1125ae97fb58SJagan Teki 	if (error)
1126ae97fb58SJagan Teki 		return error;
1127ae97fb58SJagan Teki 
11281921daceSHans de Goede 	if (ts->reset_controller_at_probe) {
1129ec6e1b40SIrina Tirdea 		/* reset the controller */
1130ec6e1b40SIrina Tirdea 		error = goodix_reset(ts);
1131ec6e1b40SIrina Tirdea 		if (error) {
1132ec6e1b40SIrina Tirdea 			dev_err(&client->dev, "Controller reset failed.\n");
1133ec6e1b40SIrina Tirdea 			return error;
1134ec6e1b40SIrina Tirdea 		}
1135ec6e1b40SIrina Tirdea 	}
1136ec6e1b40SIrina Tirdea 
1137ca96ea86SBastien Nocera 	error = goodix_i2c_test(client);
1138ca96ea86SBastien Nocera 	if (error) {
1139ca96ea86SBastien Nocera 		dev_err(&client->dev, "I2C communication failure: %d\n", error);
1140ca96ea86SBastien Nocera 		return error;
1141ca96ea86SBastien Nocera 	}
1142ca96ea86SBastien Nocera 
114368caf858SIrina Tirdea 	error = goodix_read_version(ts);
1144ca96ea86SBastien Nocera 	if (error) {
1145ca96ea86SBastien Nocera 		dev_err(&client->dev, "Read version failed.\n");
1146ca96ea86SBastien Nocera 		return error;
1147ca96ea86SBastien Nocera 	}
1148ca96ea86SBastien Nocera 
114925309004SMarcin Niestroj 	ts->chip = goodix_get_chip_data(ts->id);
1150a779fbc6SIrina Tirdea 
1151e070a97bSHans de Goede 	if (ts->load_cfg_from_disk) {
115268caf858SIrina Tirdea 		/* update device config */
115368caf858SIrina Tirdea 		ts->cfg_name = devm_kasprintf(&client->dev, GFP_KERNEL,
115468caf858SIrina Tirdea 					      "goodix_%d_cfg.bin", ts->id);
115568caf858SIrina Tirdea 		if (!ts->cfg_name)
115668caf858SIrina Tirdea 			return -ENOMEM;
1157ca96ea86SBastien Nocera 
115868caf858SIrina Tirdea 		error = request_firmware_nowait(THIS_MODULE, true, ts->cfg_name,
115968caf858SIrina Tirdea 						&client->dev, GFP_KERNEL, ts,
116068caf858SIrina Tirdea 						goodix_config_cb);
1161ca96ea86SBastien Nocera 		if (error) {
116268caf858SIrina Tirdea 			dev_err(&client->dev,
116368caf858SIrina Tirdea 				"Failed to invoke firmware loader: %d\n",
116468caf858SIrina Tirdea 				error);
1165ca96ea86SBastien Nocera 			return error;
1166ca96ea86SBastien Nocera 		}
1167ca96ea86SBastien Nocera 
1168ca96ea86SBastien Nocera 		return 0;
116968caf858SIrina Tirdea 	} else {
117068caf858SIrina Tirdea 		error = goodix_configure_dev(ts);
117168caf858SIrina Tirdea 		if (error)
117268caf858SIrina Tirdea 			return error;
117368caf858SIrina Tirdea 	}
117468caf858SIrina Tirdea 
117568caf858SIrina Tirdea 	return 0;
117668caf858SIrina Tirdea }
117768caf858SIrina Tirdea 
117868caf858SIrina Tirdea static int goodix_ts_remove(struct i2c_client *client)
117968caf858SIrina Tirdea {
118068caf858SIrina Tirdea 	struct goodix_ts_data *ts = i2c_get_clientdata(client);
118168caf858SIrina Tirdea 
1182e070a97bSHans de Goede 	if (ts->load_cfg_from_disk)
118368caf858SIrina Tirdea 		wait_for_completion(&ts->firmware_loading_complete);
118468caf858SIrina Tirdea 
118568caf858SIrina Tirdea 	return 0;
1186ca96ea86SBastien Nocera }
1187ca96ea86SBastien Nocera 
11885ab09d6aSIrina Tirdea static int __maybe_unused goodix_suspend(struct device *dev)
11895ab09d6aSIrina Tirdea {
11905ab09d6aSIrina Tirdea 	struct i2c_client *client = to_i2c_client(dev);
11915ab09d6aSIrina Tirdea 	struct goodix_ts_data *ts = i2c_get_clientdata(client);
11925ab09d6aSIrina Tirdea 	int error;
11935ab09d6aSIrina Tirdea 
1194e070a97bSHans de Goede 	if (ts->load_cfg_from_disk)
1195e070a97bSHans de Goede 		wait_for_completion(&ts->firmware_loading_complete);
1196e070a97bSHans de Goede 
11975ab09d6aSIrina Tirdea 	/* We need gpio pins to suspend/resume */
119849db3997SHans de Goede 	if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
1199faec44b6SHans de Goede 		disable_irq(client->irq);
12005ab09d6aSIrina Tirdea 		return 0;
1201faec44b6SHans de Goede 	}
12025ab09d6aSIrina Tirdea 
12035ab09d6aSIrina Tirdea 	/* Free IRQ as IRQ pin is used as output in the suspend sequence */
12045ab09d6aSIrina Tirdea 	goodix_free_irq(ts);
12055ab09d6aSIrina Tirdea 
12065ab09d6aSIrina Tirdea 	/* Output LOW on the INT pin for 5 ms */
120749db3997SHans de Goede 	error = goodix_irq_direction_output(ts, 0);
12085ab09d6aSIrina Tirdea 	if (error) {
12095ab09d6aSIrina Tirdea 		goodix_request_irq(ts);
12105ab09d6aSIrina Tirdea 		return error;
12115ab09d6aSIrina Tirdea 	}
12125ab09d6aSIrina Tirdea 
12135ab09d6aSIrina Tirdea 	usleep_range(5000, 6000);
12145ab09d6aSIrina Tirdea 
12155ab09d6aSIrina Tirdea 	error = goodix_i2c_write_u8(ts->client, GOODIX_REG_COMMAND,
12165ab09d6aSIrina Tirdea 				    GOODIX_CMD_SCREEN_OFF);
12175ab09d6aSIrina Tirdea 	if (error) {
12185ab09d6aSIrina Tirdea 		dev_err(&ts->client->dev, "Screen off command failed\n");
121949db3997SHans de Goede 		goodix_irq_direction_input(ts);
12205ab09d6aSIrina Tirdea 		goodix_request_irq(ts);
12215ab09d6aSIrina Tirdea 		return -EAGAIN;
12225ab09d6aSIrina Tirdea 	}
12235ab09d6aSIrina Tirdea 
12245ab09d6aSIrina Tirdea 	/*
12255ab09d6aSIrina Tirdea 	 * The datasheet specifies that the interval between sending screen-off
12265ab09d6aSIrina Tirdea 	 * command and wake-up should be longer than 58 ms. To avoid waking up
12275ab09d6aSIrina Tirdea 	 * sooner, delay 58ms here.
12285ab09d6aSIrina Tirdea 	 */
12295ab09d6aSIrina Tirdea 	msleep(58);
12305ab09d6aSIrina Tirdea 	return 0;
12315ab09d6aSIrina Tirdea }
12325ab09d6aSIrina Tirdea 
12335ab09d6aSIrina Tirdea static int __maybe_unused goodix_resume(struct device *dev)
12345ab09d6aSIrina Tirdea {
12355ab09d6aSIrina Tirdea 	struct i2c_client *client = to_i2c_client(dev);
12365ab09d6aSIrina Tirdea 	struct goodix_ts_data *ts = i2c_get_clientdata(client);
12375ab09d6aSIrina Tirdea 	int error;
12385ab09d6aSIrina Tirdea 
123949db3997SHans de Goede 	if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
1240faec44b6SHans de Goede 		enable_irq(client->irq);
12415ab09d6aSIrina Tirdea 		return 0;
1242faec44b6SHans de Goede 	}
12435ab09d6aSIrina Tirdea 
12445ab09d6aSIrina Tirdea 	/*
12455ab09d6aSIrina Tirdea 	 * Exit sleep mode by outputting HIGH level to INT pin
12465ab09d6aSIrina Tirdea 	 * for 2ms~5ms.
12475ab09d6aSIrina Tirdea 	 */
124849db3997SHans de Goede 	error = goodix_irq_direction_output(ts, 1);
12495ab09d6aSIrina Tirdea 	if (error)
12505ab09d6aSIrina Tirdea 		return error;
12515ab09d6aSIrina Tirdea 
12525ab09d6aSIrina Tirdea 	usleep_range(2000, 5000);
12535ab09d6aSIrina Tirdea 
12545ab09d6aSIrina Tirdea 	error = goodix_int_sync(ts);
12555ab09d6aSIrina Tirdea 	if (error)
12565ab09d6aSIrina Tirdea 		return error;
12575ab09d6aSIrina Tirdea 
12585ab09d6aSIrina Tirdea 	error = goodix_request_irq(ts);
12595ab09d6aSIrina Tirdea 	if (error)
12605ab09d6aSIrina Tirdea 		return error;
12615ab09d6aSIrina Tirdea 
12625ab09d6aSIrina Tirdea 	return 0;
12635ab09d6aSIrina Tirdea }
12645ab09d6aSIrina Tirdea 
12655ab09d6aSIrina Tirdea static SIMPLE_DEV_PM_OPS(goodix_pm_ops, goodix_suspend, goodix_resume);
12665ab09d6aSIrina Tirdea 
1267ca96ea86SBastien Nocera static const struct i2c_device_id goodix_ts_id[] = {
1268ca96ea86SBastien Nocera 	{ "GDIX1001:00", 0 },
1269ca96ea86SBastien Nocera 	{ }
1270ca96ea86SBastien Nocera };
12712e9e910eSJavier Martinez Canillas MODULE_DEVICE_TABLE(i2c, goodix_ts_id);
1272ca96ea86SBastien Nocera 
1273771d8f1bSAleksei Mamlin #ifdef CONFIG_ACPI
1274ca96ea86SBastien Nocera static const struct acpi_device_id goodix_acpi_match[] = {
1275ca96ea86SBastien Nocera 	{ "GDIX1001", 0 },
12765ca4d1aeSEthan Lee 	{ "GDIX1002", 0 },
1277ca96ea86SBastien Nocera 	{ }
1278ca96ea86SBastien Nocera };
1279ca96ea86SBastien Nocera MODULE_DEVICE_TABLE(acpi, goodix_acpi_match);
1280771d8f1bSAleksei Mamlin #endif
1281771d8f1bSAleksei Mamlin 
1282771d8f1bSAleksei Mamlin #ifdef CONFIG_OF
1283771d8f1bSAleksei Mamlin static const struct of_device_id goodix_of_match[] = {
128425309004SMarcin Niestroj 	{ .compatible = "goodix,gt1151" },
1285a5f50c50SJagan Teki 	{ .compatible = "goodix,gt5663" },
128684ef1b33SGuido Günther 	{ .compatible = "goodix,gt5688" },
1287771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt911" },
1288771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt9110" },
1289771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt912" },
1290771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt927" },
1291771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt9271" },
1292771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt928" },
1293771d8f1bSAleksei Mamlin 	{ .compatible = "goodix,gt967" },
1294771d8f1bSAleksei Mamlin 	{ }
1295771d8f1bSAleksei Mamlin };
1296771d8f1bSAleksei Mamlin MODULE_DEVICE_TABLE(of, goodix_of_match);
1297771d8f1bSAleksei Mamlin #endif
1298ca96ea86SBastien Nocera 
1299ca96ea86SBastien Nocera static struct i2c_driver goodix_ts_driver = {
1300ca96ea86SBastien Nocera 	.probe = goodix_ts_probe,
130168caf858SIrina Tirdea 	.remove = goodix_ts_remove,
1302ca96ea86SBastien Nocera 	.id_table = goodix_ts_id,
1303ca96ea86SBastien Nocera 	.driver = {
1304ca96ea86SBastien Nocera 		.name = "Goodix-TS",
1305771d8f1bSAleksei Mamlin 		.acpi_match_table = ACPI_PTR(goodix_acpi_match),
1306771d8f1bSAleksei Mamlin 		.of_match_table = of_match_ptr(goodix_of_match),
13075ab09d6aSIrina Tirdea 		.pm = &goodix_pm_ops,
1308ca96ea86SBastien Nocera 	},
1309ca96ea86SBastien Nocera };
1310ca96ea86SBastien Nocera module_i2c_driver(goodix_ts_driver);
1311ca96ea86SBastien Nocera 
1312ca96ea86SBastien Nocera MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
1313ca96ea86SBastien Nocera MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
1314ca96ea86SBastien Nocera MODULE_DESCRIPTION("Goodix touchscreen driver");
1315ca96ea86SBastien Nocera MODULE_LICENSE("GPL v2");
1316