1ac1dc6b2SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
266aee900SScott Liu /*
366aee900SScott Liu  * Elan Microelectronics touch panels with I2C interface
466aee900SScott Liu  *
566aee900SScott Liu  * Copyright (C) 2014 Elan Microelectronics Corporation.
666aee900SScott Liu  * Scott Liu <scott.liu@emc.com.tw>
766aee900SScott Liu  *
866aee900SScott Liu  * This code is partly based on hid-multitouch.c:
966aee900SScott Liu  *
1066aee900SScott Liu  *  Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
1166aee900SScott Liu  *  Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
1266aee900SScott Liu  *  Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
1366aee900SScott Liu  *
1466aee900SScott Liu  * This code is partly based on i2c-hid.c:
1566aee900SScott Liu  *
1666aee900SScott Liu  * Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
1766aee900SScott Liu  * Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
1866aee900SScott Liu  * Copyright (c) 2012 Red Hat, Inc
1966aee900SScott Liu  */
2066aee900SScott Liu 
2166aee900SScott Liu 
2266aee900SScott Liu #include <linux/module.h>
2366aee900SScott Liu #include <linux/input.h>
2466aee900SScott Liu #include <linux/interrupt.h>
254c83c071SDmitry Torokhov #include <linux/irq.h>
2666aee900SScott Liu #include <linux/platform_device.h>
2766aee900SScott Liu #include <linux/async.h>
2866aee900SScott Liu #include <linux/i2c.h>
2966aee900SScott Liu #include <linux/delay.h>
3066aee900SScott Liu #include <linux/uaccess.h>
3166aee900SScott Liu #include <linux/buffer_head.h>
3266aee900SScott Liu #include <linux/slab.h>
3366aee900SScott Liu #include <linux/firmware.h>
3466aee900SScott Liu #include <linux/input/mt.h>
3566aee900SScott Liu #include <linux/acpi.h>
3666aee900SScott Liu #include <linux/of.h>
37afe10358SDmitry Torokhov #include <linux/gpio/consumer.h>
38afe10358SDmitry Torokhov #include <linux/regulator/consumer.h>
3966aee900SScott Liu #include <asm/unaligned.h>
4066aee900SScott Liu 
4166aee900SScott Liu /* Device, Driver information */
4266aee900SScott Liu #define DEVICE_NAME	"elants_i2c"
4366aee900SScott Liu 
4466aee900SScott Liu /* Convert from rows or columns into resolution */
4566aee900SScott Liu #define ELAN_TS_RESOLUTION(n, m)   (((n) - 1) * (m))
4666aee900SScott Liu 
4766aee900SScott Liu /* FW header data */
4866aee900SScott Liu #define HEADER_SIZE		4
4966aee900SScott Liu #define FW_HDR_TYPE		0
5066aee900SScott Liu #define FW_HDR_COUNT		1
5166aee900SScott Liu #define FW_HDR_LENGTH		2
5266aee900SScott Liu 
5366aee900SScott Liu /* Buffer mode Queue Header information */
5466aee900SScott Liu #define QUEUE_HEADER_SINGLE	0x62
5566aee900SScott Liu #define QUEUE_HEADER_NORMAL	0X63
5666aee900SScott Liu #define QUEUE_HEADER_WAIT	0x64
5766aee900SScott Liu 
5866aee900SScott Liu /* Command header definition */
5966aee900SScott Liu #define CMD_HEADER_WRITE	0x54
6066aee900SScott Liu #define CMD_HEADER_READ		0x53
6166aee900SScott Liu #define CMD_HEADER_6B_READ	0x5B
6266aee900SScott Liu #define CMD_HEADER_RESP		0x52
6366aee900SScott Liu #define CMD_HEADER_6B_RESP	0x9B
6466aee900SScott Liu #define CMD_HEADER_HELLO	0x55
6566aee900SScott Liu #define CMD_HEADER_REK		0x66
6666aee900SScott Liu 
6766aee900SScott Liu /* FW position data */
6866aee900SScott Liu #define PACKET_SIZE		55
6966aee900SScott Liu #define MAX_CONTACT_NUM		10
7066aee900SScott Liu #define FW_POS_HEADER		0
7166aee900SScott Liu #define FW_POS_STATE		1
7266aee900SScott Liu #define FW_POS_TOTAL		2
7366aee900SScott Liu #define FW_POS_XY		3
7466aee900SScott Liu #define FW_POS_CHECKSUM		34
7566aee900SScott Liu #define FW_POS_WIDTH		35
7666aee900SScott Liu #define FW_POS_PRESSURE		45
7766aee900SScott Liu 
7866aee900SScott Liu #define HEADER_REPORT_10_FINGER	0x62
7966aee900SScott Liu 
8066aee900SScott Liu /* Header (4 bytes) plus 3 fill 10-finger packets */
8166aee900SScott Liu #define MAX_PACKET_SIZE		169
8266aee900SScott Liu 
8366aee900SScott Liu #define BOOT_TIME_DELAY_MS	50
8466aee900SScott Liu 
8566aee900SScott Liu /* FW read command, 0x53 0x?? 0x0, 0x01 */
8666aee900SScott Liu #define E_ELAN_INFO_FW_VER	0x00
8766aee900SScott Liu #define E_ELAN_INFO_BC_VER	0x10
8866aee900SScott Liu #define E_ELAN_INFO_TEST_VER	0xE0
8966aee900SScott Liu #define E_ELAN_INFO_FW_ID	0xF0
9066aee900SScott Liu #define E_INFO_OSR		0xD6
9166aee900SScott Liu #define E_INFO_PHY_SCAN		0xD7
9266aee900SScott Liu #define E_INFO_PHY_DRIVER	0xD8
9366aee900SScott Liu 
9466aee900SScott Liu #define MAX_RETRIES		3
9566aee900SScott Liu #define MAX_FW_UPDATE_RETRIES	30
9666aee900SScott Liu 
9766aee900SScott Liu #define ELAN_FW_PAGESIZE	132
9866aee900SScott Liu 
9966aee900SScott Liu /* calibration timeout definition */
10022c15e5eSJames Chen #define ELAN_CALI_TIMEOUT_MSEC	12000
10166aee900SScott Liu 
102afe10358SDmitry Torokhov #define ELAN_POWERON_DELAY_USEC	500
103afe10358SDmitry Torokhov #define ELAN_RESET_DELAY_MSEC	20
104afe10358SDmitry Torokhov 
10566aee900SScott Liu enum elants_state {
10666aee900SScott Liu 	ELAN_STATE_NORMAL,
10766aee900SScott Liu 	ELAN_WAIT_QUEUE_HEADER,
10866aee900SScott Liu 	ELAN_WAIT_RECALIBRATION,
10966aee900SScott Liu };
11066aee900SScott Liu 
11166aee900SScott Liu enum elants_iap_mode {
11266aee900SScott Liu 	ELAN_IAP_OPERATIONAL,
11366aee900SScott Liu 	ELAN_IAP_RECOVERY,
11466aee900SScott Liu };
11566aee900SScott Liu 
11666aee900SScott Liu /* struct elants_data - represents state of Elan touchscreen device */
11766aee900SScott Liu struct elants_data {
11866aee900SScott Liu 	struct i2c_client *client;
11966aee900SScott Liu 	struct input_dev *input;
12066aee900SScott Liu 
121afe10358SDmitry Torokhov 	struct regulator *vcc33;
122afe10358SDmitry Torokhov 	struct regulator *vccio;
123afe10358SDmitry Torokhov 	struct gpio_desc *reset_gpio;
124afe10358SDmitry Torokhov 
12566aee900SScott Liu 	u16 fw_version;
12666aee900SScott Liu 	u8 test_version;
12766aee900SScott Liu 	u8 solution_version;
12866aee900SScott Liu 	u8 bc_version;
12966aee900SScott Liu 	u8 iap_version;
13066aee900SScott Liu 	u16 hw_version;
13166aee900SScott Liu 	unsigned int x_res;	/* resolution in units/mm */
13266aee900SScott Liu 	unsigned int y_res;
13366aee900SScott Liu 	unsigned int x_max;
13466aee900SScott Liu 	unsigned int y_max;
13566aee900SScott Liu 
13666aee900SScott Liu 	enum elants_state state;
13766aee900SScott Liu 	enum elants_iap_mode iap_mode;
13866aee900SScott Liu 
13966aee900SScott Liu 	/* Guards against concurrent access to the device via sysfs */
14066aee900SScott Liu 	struct mutex sysfs_mutex;
14166aee900SScott Liu 
14266aee900SScott Liu 	u8 cmd_resp[HEADER_SIZE];
14366aee900SScott Liu 	struct completion cmd_done;
14466aee900SScott Liu 
14566aee900SScott Liu 	bool wake_irq_enabled;
146afe10358SDmitry Torokhov 	bool keep_power_in_suspend;
14700f73f97SStephen Boyd 
14800f73f97SStephen Boyd 	/* Must be last to be used for DMA operations */
14900f73f97SStephen Boyd 	u8 buf[MAX_PACKET_SIZE] ____cacheline_aligned;
15066aee900SScott Liu };
15166aee900SScott Liu 
15266aee900SScott Liu static int elants_i2c_send(struct i2c_client *client,
15366aee900SScott Liu 			   const void *data, size_t size)
15466aee900SScott Liu {
15566aee900SScott Liu 	int ret;
15666aee900SScott Liu 
15766aee900SScott Liu 	ret = i2c_master_send(client, data, size);
15866aee900SScott Liu 	if (ret == size)
15966aee900SScott Liu 		return 0;
16066aee900SScott Liu 
16166aee900SScott Liu 	if (ret >= 0)
16266aee900SScott Liu 		ret = -EIO;
16366aee900SScott Liu 
16466aee900SScott Liu 	dev_err(&client->dev, "%s failed (%*ph): %d\n",
16566aee900SScott Liu 		__func__, (int)size, data, ret);
16666aee900SScott Liu 
16766aee900SScott Liu 	return ret;
16866aee900SScott Liu }
16966aee900SScott Liu 
17066aee900SScott Liu static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)
17166aee900SScott Liu {
17266aee900SScott Liu 	int ret;
17366aee900SScott Liu 
17466aee900SScott Liu 	ret = i2c_master_recv(client, data, size);
17566aee900SScott Liu 	if (ret == size)
17666aee900SScott Liu 		return 0;
17766aee900SScott Liu 
17866aee900SScott Liu 	if (ret >= 0)
17966aee900SScott Liu 		ret = -EIO;
18066aee900SScott Liu 
18166aee900SScott Liu 	dev_err(&client->dev, "%s failed: %d\n", __func__, ret);
18266aee900SScott Liu 
18366aee900SScott Liu 	return ret;
18466aee900SScott Liu }
18566aee900SScott Liu 
18666aee900SScott Liu static int elants_i2c_execute_command(struct i2c_client *client,
18766aee900SScott Liu 				      const u8 *cmd, size_t cmd_size,
18866aee900SScott Liu 				      u8 *resp, size_t resp_size)
18966aee900SScott Liu {
19066aee900SScott Liu 	struct i2c_msg msgs[2];
19166aee900SScott Liu 	int ret;
19266aee900SScott Liu 	u8 expected_response;
19366aee900SScott Liu 
19466aee900SScott Liu 	switch (cmd[0]) {
19566aee900SScott Liu 	case CMD_HEADER_READ:
19666aee900SScott Liu 		expected_response = CMD_HEADER_RESP;
19766aee900SScott Liu 		break;
19866aee900SScott Liu 
19966aee900SScott Liu 	case CMD_HEADER_6B_READ:
20066aee900SScott Liu 		expected_response = CMD_HEADER_6B_RESP;
20166aee900SScott Liu 		break;
20266aee900SScott Liu 
20366aee900SScott Liu 	default:
20466aee900SScott Liu 		dev_err(&client->dev, "%s: invalid command %*ph\n",
20566aee900SScott Liu 			__func__, (int)cmd_size, cmd);
20666aee900SScott Liu 		return -EINVAL;
20766aee900SScott Liu 	}
20866aee900SScott Liu 
20966aee900SScott Liu 	msgs[0].addr = client->addr;
21066aee900SScott Liu 	msgs[0].flags = client->flags & I2C_M_TEN;
21166aee900SScott Liu 	msgs[0].len = cmd_size;
21266aee900SScott Liu 	msgs[0].buf = (u8 *)cmd;
21366aee900SScott Liu 
21466aee900SScott Liu 	msgs[1].addr = client->addr;
21566aee900SScott Liu 	msgs[1].flags = client->flags & I2C_M_TEN;
21666aee900SScott Liu 	msgs[1].flags |= I2C_M_RD;
21766aee900SScott Liu 	msgs[1].len = resp_size;
21866aee900SScott Liu 	msgs[1].buf = resp;
21966aee900SScott Liu 
22066aee900SScott Liu 	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
22166aee900SScott Liu 	if (ret < 0)
22266aee900SScott Liu 		return ret;
22366aee900SScott Liu 
22466aee900SScott Liu 	if (ret != ARRAY_SIZE(msgs) || resp[FW_HDR_TYPE] != expected_response)
22566aee900SScott Liu 		return -EIO;
22666aee900SScott Liu 
22766aee900SScott Liu 	return 0;
22866aee900SScott Liu }
22966aee900SScott Liu 
23066aee900SScott Liu static int elants_i2c_calibrate(struct elants_data *ts)
23166aee900SScott Liu {
23266aee900SScott Liu 	struct i2c_client *client = ts->client;
23366aee900SScott Liu 	int ret, error;
23466aee900SScott Liu 	static const u8 w_flashkey[] = { 0x54, 0xC0, 0xE1, 0x5A };
23566aee900SScott Liu 	static const u8 rek[] = { 0x54, 0x29, 0x00, 0x01 };
23666aee900SScott Liu 	static const u8 rek_resp[] = { CMD_HEADER_REK, 0x66, 0x66, 0x66 };
23766aee900SScott Liu 
23866aee900SScott Liu 	disable_irq(client->irq);
23966aee900SScott Liu 
24066aee900SScott Liu 	ts->state = ELAN_WAIT_RECALIBRATION;
24166aee900SScott Liu 	reinit_completion(&ts->cmd_done);
24266aee900SScott Liu 
24366aee900SScott Liu 	elants_i2c_send(client, w_flashkey, sizeof(w_flashkey));
24466aee900SScott Liu 	elants_i2c_send(client, rek, sizeof(rek));
24566aee900SScott Liu 
24666aee900SScott Liu 	enable_irq(client->irq);
24766aee900SScott Liu 
24866aee900SScott Liu 	ret = wait_for_completion_interruptible_timeout(&ts->cmd_done,
24966aee900SScott Liu 				msecs_to_jiffies(ELAN_CALI_TIMEOUT_MSEC));
25066aee900SScott Liu 
25166aee900SScott Liu 	ts->state = ELAN_STATE_NORMAL;
25266aee900SScott Liu 
25366aee900SScott Liu 	if (ret <= 0) {
25466aee900SScott Liu 		error = ret < 0 ? ret : -ETIMEDOUT;
25566aee900SScott Liu 		dev_err(&client->dev,
25666aee900SScott Liu 			"error while waiting for calibration to complete: %d\n",
25766aee900SScott Liu 			error);
25866aee900SScott Liu 		return error;
25966aee900SScott Liu 	}
26066aee900SScott Liu 
26166aee900SScott Liu 	if (memcmp(rek_resp, ts->cmd_resp, sizeof(rek_resp))) {
26266aee900SScott Liu 		dev_err(&client->dev,
26366aee900SScott Liu 			"unexpected calibration response: %*ph\n",
26466aee900SScott Liu 			(int)sizeof(ts->cmd_resp), ts->cmd_resp);
26566aee900SScott Liu 		return -EINVAL;
26666aee900SScott Liu 	}
26766aee900SScott Liu 
26866aee900SScott Liu 	return 0;
26966aee900SScott Liu }
27066aee900SScott Liu 
27166aee900SScott Liu static int elants_i2c_sw_reset(struct i2c_client *client)
27266aee900SScott Liu {
27366aee900SScott Liu 	const u8 soft_rst_cmd[] = { 0x77, 0x77, 0x77, 0x77 };
27466aee900SScott Liu 	int error;
27566aee900SScott Liu 
27666aee900SScott Liu 	error = elants_i2c_send(client, soft_rst_cmd,
27766aee900SScott Liu 				sizeof(soft_rst_cmd));
27866aee900SScott Liu 	if (error) {
27966aee900SScott Liu 		dev_err(&client->dev, "software reset failed: %d\n", error);
28066aee900SScott Liu 		return error;
28166aee900SScott Liu 	}
28266aee900SScott Liu 
28366aee900SScott Liu 	/*
28466aee900SScott Liu 	 * We should wait at least 10 msec (but no more than 40) before
28566aee900SScott Liu 	 * sending fastboot or IAP command to the device.
28666aee900SScott Liu 	 */
28766aee900SScott Liu 	msleep(30);
28866aee900SScott Liu 
28966aee900SScott Liu 	return 0;
29066aee900SScott Liu }
29166aee900SScott Liu 
29266aee900SScott Liu static u16 elants_i2c_parse_version(u8 *buf)
29366aee900SScott Liu {
29466aee900SScott Liu 	return get_unaligned_be32(buf) >> 4;
29566aee900SScott Liu }
29666aee900SScott Liu 
297bc1d57feSJohnny Chuang static int elants_i2c_query_hw_version(struct elants_data *ts)
29866aee900SScott Liu {
29966aee900SScott Liu 	struct i2c_client *client = ts->client;
30066aee900SScott Liu 	int error, retry_cnt;
30166aee900SScott Liu 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
30266aee900SScott Liu 	u8 resp[HEADER_SIZE];
30366aee900SScott Liu 
30466aee900SScott Liu 	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
30566aee900SScott Liu 		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
30666aee900SScott Liu 						   resp, sizeof(resp));
30766aee900SScott Liu 		if (!error) {
30866aee900SScott Liu 			ts->hw_version = elants_i2c_parse_version(resp);
30966aee900SScott Liu 			if (ts->hw_version != 0xffff)
31066aee900SScott Liu 				return 0;
31166aee900SScott Liu 		}
31266aee900SScott Liu 
31366aee900SScott Liu 		dev_dbg(&client->dev, "read fw id error=%d, buf=%*phC\n",
31466aee900SScott Liu 			error, (int)sizeof(resp), resp);
31566aee900SScott Liu 	}
31666aee900SScott Liu 
317bc1d57feSJohnny Chuang 	if (error) {
31866aee900SScott Liu 		dev_err(&client->dev,
319bc1d57feSJohnny Chuang 			"Failed to read fw id: %d\n", error);
320bc1d57feSJohnny Chuang 		return error;
321bc1d57feSJohnny Chuang 	}
322bc1d57feSJohnny Chuang 
323bc1d57feSJohnny Chuang 	dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
32466aee900SScott Liu 
32566aee900SScott Liu 	return -EINVAL;
32666aee900SScott Liu }
32766aee900SScott Liu 
32866aee900SScott Liu static int elants_i2c_query_fw_version(struct elants_data *ts)
32966aee900SScott Liu {
33066aee900SScott Liu 	struct i2c_client *client = ts->client;
33166aee900SScott Liu 	int error, retry_cnt;
33266aee900SScott Liu 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
33366aee900SScott Liu 	u8 resp[HEADER_SIZE];
33466aee900SScott Liu 
33566aee900SScott Liu 	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
33666aee900SScott Liu 		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
33766aee900SScott Liu 						   resp, sizeof(resp));
33866aee900SScott Liu 		if (!error) {
33966aee900SScott Liu 			ts->fw_version = elants_i2c_parse_version(resp);
34066aee900SScott Liu 			if (ts->fw_version != 0x0000 &&
34166aee900SScott Liu 			    ts->fw_version != 0xffff)
34266aee900SScott Liu 				return 0;
34366aee900SScott Liu 		}
34466aee900SScott Liu 
34566aee900SScott Liu 		dev_dbg(&client->dev, "read fw version error=%d, buf=%*phC\n",
34666aee900SScott Liu 			error, (int)sizeof(resp), resp);
34766aee900SScott Liu 	}
34866aee900SScott Liu 
34966aee900SScott Liu 	dev_err(&client->dev,
35066aee900SScott Liu 		"Failed to read fw version or fw version is invalid\n");
35166aee900SScott Liu 
35266aee900SScott Liu 	return -EINVAL;
35366aee900SScott Liu }
35466aee900SScott Liu 
35566aee900SScott Liu static int elants_i2c_query_test_version(struct elants_data *ts)
35666aee900SScott Liu {
35766aee900SScott Liu 	struct i2c_client *client = ts->client;
35866aee900SScott Liu 	int error, retry_cnt;
35966aee900SScott Liu 	u16 version;
36066aee900SScott Liu 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
36166aee900SScott Liu 	u8 resp[HEADER_SIZE];
36266aee900SScott Liu 
36366aee900SScott Liu 	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
36466aee900SScott Liu 		error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
36566aee900SScott Liu 						   resp, sizeof(resp));
36666aee900SScott Liu 		if (!error) {
36766aee900SScott Liu 			version = elants_i2c_parse_version(resp);
36866aee900SScott Liu 			ts->test_version = version >> 8;
36966aee900SScott Liu 			ts->solution_version = version & 0xff;
37066aee900SScott Liu 
37166aee900SScott Liu 			return 0;
37266aee900SScott Liu 		}
37366aee900SScott Liu 
37466aee900SScott Liu 		dev_dbg(&client->dev,
37566aee900SScott Liu 			"read test version error rc=%d, buf=%*phC\n",
37666aee900SScott Liu 			error, (int)sizeof(resp), resp);
37766aee900SScott Liu 	}
37866aee900SScott Liu 
37966aee900SScott Liu 	dev_err(&client->dev, "Failed to read test version\n");
38066aee900SScott Liu 
38166aee900SScott Liu 	return -EINVAL;
38266aee900SScott Liu }
38366aee900SScott Liu 
38466aee900SScott Liu static int elants_i2c_query_bc_version(struct elants_data *ts)
38566aee900SScott Liu {
38666aee900SScott Liu 	struct i2c_client *client = ts->client;
38766aee900SScott Liu 	const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_BC_VER, 0x00, 0x01 };
38866aee900SScott Liu 	u8 resp[HEADER_SIZE];
38966aee900SScott Liu 	u16 version;
39066aee900SScott Liu 	int error;
39166aee900SScott Liu 
39266aee900SScott Liu 	error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
39366aee900SScott Liu 					   resp, sizeof(resp));
39466aee900SScott Liu 	if (error) {
39566aee900SScott Liu 		dev_err(&client->dev,
39666aee900SScott Liu 			"read BC version error=%d, buf=%*phC\n",
39766aee900SScott Liu 			error, (int)sizeof(resp), resp);
39866aee900SScott Liu 		return error;
39966aee900SScott Liu 	}
40066aee900SScott Liu 
40166aee900SScott Liu 	version = elants_i2c_parse_version(resp);
40266aee900SScott Liu 	ts->bc_version = version >> 8;
40366aee900SScott Liu 	ts->iap_version = version & 0xff;
40466aee900SScott Liu 
40566aee900SScott Liu 	return 0;
40666aee900SScott Liu }
40766aee900SScott Liu 
40866aee900SScott Liu static int elants_i2c_query_ts_info(struct elants_data *ts)
40966aee900SScott Liu {
41066aee900SScott Liu 	struct i2c_client *client = ts->client;
41166aee900SScott Liu 	int error;
41266aee900SScott Liu 	u8 resp[17];
41366aee900SScott Liu 	u16 phy_x, phy_y, rows, cols, osr;
41466aee900SScott Liu 	const u8 get_resolution_cmd[] = {
41566aee900SScott Liu 		CMD_HEADER_6B_READ, 0x00, 0x00, 0x00, 0x00, 0x00
41666aee900SScott Liu 	};
41766aee900SScott Liu 	const u8 get_osr_cmd[] = {
41866aee900SScott Liu 		CMD_HEADER_READ, E_INFO_OSR, 0x00, 0x01
41966aee900SScott Liu 	};
42066aee900SScott Liu 	const u8 get_physical_scan_cmd[] = {
42166aee900SScott Liu 		CMD_HEADER_READ, E_INFO_PHY_SCAN, 0x00, 0x01
42266aee900SScott Liu 	};
42366aee900SScott Liu 	const u8 get_physical_drive_cmd[] = {
42466aee900SScott Liu 		CMD_HEADER_READ, E_INFO_PHY_DRIVER, 0x00, 0x01
42566aee900SScott Liu 	};
42666aee900SScott Liu 
42766aee900SScott Liu 	/* Get trace number */
42866aee900SScott Liu 	error = elants_i2c_execute_command(client,
42966aee900SScott Liu 					   get_resolution_cmd,
43066aee900SScott Liu 					   sizeof(get_resolution_cmd),
43166aee900SScott Liu 					   resp, sizeof(resp));
43266aee900SScott Liu 	if (error) {
43366aee900SScott Liu 		dev_err(&client->dev, "get resolution command failed: %d\n",
43466aee900SScott Liu 			error);
43566aee900SScott Liu 		return error;
43666aee900SScott Liu 	}
43766aee900SScott Liu 
43866aee900SScott Liu 	rows = resp[2] + resp[6] + resp[10];
43966aee900SScott Liu 	cols = resp[3] + resp[7] + resp[11];
44066aee900SScott Liu 
44166aee900SScott Liu 	/* Process mm_to_pixel information */
44266aee900SScott Liu 	error = elants_i2c_execute_command(client,
44366aee900SScott Liu 					   get_osr_cmd, sizeof(get_osr_cmd),
44466aee900SScott Liu 					   resp, sizeof(resp));
44566aee900SScott Liu 	if (error) {
44666aee900SScott Liu 		dev_err(&client->dev, "get osr command failed: %d\n",
44766aee900SScott Liu 			error);
44866aee900SScott Liu 		return error;
44966aee900SScott Liu 	}
45066aee900SScott Liu 
45166aee900SScott Liu 	osr = resp[3];
45266aee900SScott Liu 
45366aee900SScott Liu 	error = elants_i2c_execute_command(client,
45466aee900SScott Liu 					   get_physical_scan_cmd,
45566aee900SScott Liu 					   sizeof(get_physical_scan_cmd),
45666aee900SScott Liu 					   resp, sizeof(resp));
45766aee900SScott Liu 	if (error) {
45866aee900SScott Liu 		dev_err(&client->dev, "get physical scan command failed: %d\n",
45966aee900SScott Liu 			error);
46066aee900SScott Liu 		return error;
46166aee900SScott Liu 	}
46266aee900SScott Liu 
46366aee900SScott Liu 	phy_x = get_unaligned_be16(&resp[2]);
46466aee900SScott Liu 
46566aee900SScott Liu 	error = elants_i2c_execute_command(client,
46666aee900SScott Liu 					   get_physical_drive_cmd,
46766aee900SScott Liu 					   sizeof(get_physical_drive_cmd),
46866aee900SScott Liu 					   resp, sizeof(resp));
46966aee900SScott Liu 	if (error) {
47066aee900SScott Liu 		dev_err(&client->dev, "get physical drive command failed: %d\n",
47166aee900SScott Liu 			error);
47266aee900SScott Liu 		return error;
47366aee900SScott Liu 	}
47466aee900SScott Liu 
47566aee900SScott Liu 	phy_y = get_unaligned_be16(&resp[2]);
47666aee900SScott Liu 
47766aee900SScott Liu 	dev_dbg(&client->dev, "phy_x=%d, phy_y=%d\n", phy_x, phy_y);
47866aee900SScott Liu 
47966aee900SScott Liu 	if (rows == 0 || cols == 0 || osr == 0) {
48066aee900SScott Liu 		dev_warn(&client->dev,
48166aee900SScott Liu 			 "invalid trace number data: %d, %d, %d\n",
48266aee900SScott Liu 			 rows, cols, osr);
48366aee900SScott Liu 	} else {
48466aee900SScott Liu 		/* translate trace number to TS resolution */
48566aee900SScott Liu 		ts->x_max = ELAN_TS_RESOLUTION(rows, osr);
48666aee900SScott Liu 		ts->x_res = DIV_ROUND_CLOSEST(ts->x_max, phy_x);
48766aee900SScott Liu 		ts->y_max = ELAN_TS_RESOLUTION(cols, osr);
48866aee900SScott Liu 		ts->y_res = DIV_ROUND_CLOSEST(ts->y_max, phy_y);
48966aee900SScott Liu 	}
49066aee900SScott Liu 
49166aee900SScott Liu 	return 0;
49266aee900SScott Liu }
49366aee900SScott Liu 
49466aee900SScott Liu static int elants_i2c_fastboot(struct i2c_client *client)
49566aee900SScott Liu {
49666aee900SScott Liu 	const u8 boot_cmd[] = { 0x4D, 0x61, 0x69, 0x6E };
49766aee900SScott Liu 	int error;
49866aee900SScott Liu 
49966aee900SScott Liu 	error = elants_i2c_send(client, boot_cmd, sizeof(boot_cmd));
50066aee900SScott Liu 	if (error) {
50166aee900SScott Liu 		dev_err(&client->dev, "boot failed: %d\n", error);
50266aee900SScott Liu 		return error;
50366aee900SScott Liu 	}
50466aee900SScott Liu 
50566aee900SScott Liu 	dev_dbg(&client->dev, "boot success -- 0x%x\n", client->addr);
50666aee900SScott Liu 	return 0;
50766aee900SScott Liu }
50866aee900SScott Liu 
50966aee900SScott Liu static int elants_i2c_initialize(struct elants_data *ts)
51066aee900SScott Liu {
51166aee900SScott Liu 	struct i2c_client *client = ts->client;
512bc1d57feSJohnny Chuang 	int error, error2, retry_cnt;
51366aee900SScott Liu 	const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 };
51466aee900SScott Liu 	const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 };
51566aee900SScott Liu 	u8 buf[HEADER_SIZE];
51666aee900SScott Liu 
51766aee900SScott Liu 	for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
51866aee900SScott Liu 		error = elants_i2c_sw_reset(client);
51966aee900SScott Liu 		if (error) {
52066aee900SScott Liu 			/* Continue initializing if it's the last try */
52166aee900SScott Liu 			if (retry_cnt < MAX_RETRIES - 1)
52266aee900SScott Liu 				continue;
52366aee900SScott Liu 		}
52466aee900SScott Liu 
52566aee900SScott Liu 		error = elants_i2c_fastboot(client);
52666aee900SScott Liu 		if (error) {
52766aee900SScott Liu 			/* Continue initializing if it's the last try */
52866aee900SScott Liu 			if (retry_cnt < MAX_RETRIES - 1)
52966aee900SScott Liu 				continue;
53066aee900SScott Liu 		}
53166aee900SScott Liu 
53266aee900SScott Liu 		/* Wait for Hello packet */
53366aee900SScott Liu 		msleep(BOOT_TIME_DELAY_MS);
53466aee900SScott Liu 
53566aee900SScott Liu 		error = elants_i2c_read(client, buf, sizeof(buf));
53666aee900SScott Liu 		if (error) {
53766aee900SScott Liu 			dev_err(&client->dev,
53866aee900SScott Liu 				"failed to read 'hello' packet: %d\n", error);
53966aee900SScott Liu 		} else if (!memcmp(buf, hello_packet, sizeof(hello_packet))) {
54066aee900SScott Liu 			ts->iap_mode = ELAN_IAP_OPERATIONAL;
54166aee900SScott Liu 			break;
54266aee900SScott Liu 		} else if (!memcmp(buf, recov_packet, sizeof(recov_packet))) {
54366aee900SScott Liu 			/*
54466aee900SScott Liu 			 * Setting error code will mark device
54566aee900SScott Liu 			 * in recovery mode below.
54666aee900SScott Liu 			 */
54766aee900SScott Liu 			error = -EIO;
54866aee900SScott Liu 			break;
54966aee900SScott Liu 		} else {
55066aee900SScott Liu 			error = -EINVAL;
55166aee900SScott Liu 			dev_err(&client->dev,
55266aee900SScott Liu 				"invalid 'hello' packet: %*ph\n",
55366aee900SScott Liu 				(int)sizeof(buf), buf);
55466aee900SScott Liu 		}
55566aee900SScott Liu 	}
55666aee900SScott Liu 
557bc1d57feSJohnny Chuang 	/* hw version is available even if device in recovery state */
558bc1d57feSJohnny Chuang 	error2 = elants_i2c_query_hw_version(ts);
55966aee900SScott Liu 	if (!error)
560bc1d57feSJohnny Chuang 		error = error2;
561bc1d57feSJohnny Chuang 
56266aee900SScott Liu 	if (!error)
56366aee900SScott Liu 		error = elants_i2c_query_fw_version(ts);
564bc1d57feSJohnny Chuang 	if (!error)
565bc1d57feSJohnny Chuang 		error = elants_i2c_query_test_version(ts);
566bc1d57feSJohnny Chuang 	if (!error)
567bc1d57feSJohnny Chuang 		error = elants_i2c_query_bc_version(ts);
568bc1d57feSJohnny Chuang 	if (!error)
569bc1d57feSJohnny Chuang 		error = elants_i2c_query_ts_info(ts);
57066aee900SScott Liu 
571bc1d57feSJohnny Chuang 	if (error)
57266aee900SScott Liu 		ts->iap_mode = ELAN_IAP_RECOVERY;
57366aee900SScott Liu 
57466aee900SScott Liu 	return 0;
57566aee900SScott Liu }
57666aee900SScott Liu 
57766aee900SScott Liu /*
57866aee900SScott Liu  * Firmware update interface.
57966aee900SScott Liu  */
58066aee900SScott Liu 
58166aee900SScott Liu static int elants_i2c_fw_write_page(struct i2c_client *client,
58266aee900SScott Liu 				    const void *page)
58366aee900SScott Liu {
58466aee900SScott Liu 	const u8 ack_ok[] = { 0xaa, 0xaa };
58566aee900SScott Liu 	u8 buf[2];
58666aee900SScott Liu 	int retry;
58766aee900SScott Liu 	int error;
58866aee900SScott Liu 
58966aee900SScott Liu 	for (retry = 0; retry < MAX_FW_UPDATE_RETRIES; retry++) {
59066aee900SScott Liu 		error = elants_i2c_send(client, page, ELAN_FW_PAGESIZE);
59166aee900SScott Liu 		if (error) {
59266aee900SScott Liu 			dev_err(&client->dev,
59366aee900SScott Liu 				"IAP Write Page failed: %d\n", error);
59466aee900SScott Liu 			continue;
59566aee900SScott Liu 		}
59666aee900SScott Liu 
59766aee900SScott Liu 		error = elants_i2c_read(client, buf, 2);
59866aee900SScott Liu 		if (error) {
59966aee900SScott Liu 			dev_err(&client->dev,
60066aee900SScott Liu 				"IAP Ack read failed: %d\n", error);
60166aee900SScott Liu 			return error;
60266aee900SScott Liu 		}
60366aee900SScott Liu 
60466aee900SScott Liu 		if (!memcmp(buf, ack_ok, sizeof(ack_ok)))
60566aee900SScott Liu 			return 0;
60666aee900SScott Liu 
60766aee900SScott Liu 		error = -EIO;
60866aee900SScott Liu 		dev_err(&client->dev,
60966aee900SScott Liu 			"IAP Get Ack Error [%02x:%02x]\n",
61066aee900SScott Liu 			buf[0], buf[1]);
61166aee900SScott Liu 	}
61266aee900SScott Liu 
61366aee900SScott Liu 	return error;
61466aee900SScott Liu }
61566aee900SScott Liu 
61666aee900SScott Liu static int elants_i2c_do_update_firmware(struct i2c_client *client,
61766aee900SScott Liu 					 const struct firmware *fw,
61866aee900SScott Liu 					 bool force)
61966aee900SScott Liu {
62066aee900SScott Liu 	const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 };
62166aee900SScott Liu 	const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 };
62266aee900SScott Liu 	const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc };
6236fd38502SJames Chen 	const u8 close_idle[] = {0x54, 0x2c, 0x01, 0x01};
62466aee900SScott Liu 	u8 buf[HEADER_SIZE];
62566aee900SScott Liu 	u16 send_id;
62666aee900SScott Liu 	int page, n_fw_pages;
62766aee900SScott Liu 	int error;
62866aee900SScott Liu 
62966aee900SScott Liu 	/* Recovery mode detection! */
63066aee900SScott Liu 	if (force) {
63166aee900SScott Liu 		dev_dbg(&client->dev, "Recovery mode procedure\n");
63266aee900SScott Liu 		error = elants_i2c_send(client, enter_iap2, sizeof(enter_iap2));
63366aee900SScott Liu 	} else {
63466aee900SScott Liu 		/* Start IAP Procedure */
63566aee900SScott Liu 		dev_dbg(&client->dev, "Normal IAP procedure\n");
6366fd38502SJames Chen 		/* Close idle mode */
6376fd38502SJames Chen 		error = elants_i2c_send(client, close_idle, sizeof(close_idle));
6386fd38502SJames Chen 		if (error)
6396fd38502SJames Chen 			dev_err(&client->dev, "Failed close idle: %d\n", error);
6406fd38502SJames Chen 		msleep(60);
64166aee900SScott Liu 		elants_i2c_sw_reset(client);
6426fd38502SJames Chen 		msleep(20);
64366aee900SScott Liu 		error = elants_i2c_send(client, enter_iap, sizeof(enter_iap));
64466aee900SScott Liu 	}
64566aee900SScott Liu 
64666aee900SScott Liu 	if (error) {
64766aee900SScott Liu 		dev_err(&client->dev, "failed to enter IAP mode: %d\n", error);
64866aee900SScott Liu 		return error;
64966aee900SScott Liu 	}
65066aee900SScott Liu 
65166aee900SScott Liu 	msleep(20);
65266aee900SScott Liu 
65366aee900SScott Liu 	/* check IAP state */
65466aee900SScott Liu 	error = elants_i2c_read(client, buf, 4);
65566aee900SScott Liu 	if (error) {
65666aee900SScott Liu 		dev_err(&client->dev,
65766aee900SScott Liu 			"failed to read IAP acknowledgement: %d\n",
65866aee900SScott Liu 			error);
65966aee900SScott Liu 		return error;
66066aee900SScott Liu 	}
66166aee900SScott Liu 
66266aee900SScott Liu 	if (memcmp(buf, iap_ack, sizeof(iap_ack))) {
66366aee900SScott Liu 		dev_err(&client->dev,
66466aee900SScott Liu 			"failed to enter IAP: %*ph (expected %*ph)\n",
66566aee900SScott Liu 			(int)sizeof(buf), buf, (int)sizeof(iap_ack), iap_ack);
66666aee900SScott Liu 		return -EIO;
66766aee900SScott Liu 	}
66866aee900SScott Liu 
66966aee900SScott Liu 	dev_info(&client->dev, "successfully entered IAP mode");
67066aee900SScott Liu 
67166aee900SScott Liu 	send_id = client->addr;
67266aee900SScott Liu 	error = elants_i2c_send(client, &send_id, 1);
67366aee900SScott Liu 	if (error) {
67466aee900SScott Liu 		dev_err(&client->dev, "sending dummy byte failed: %d\n",
67566aee900SScott Liu 			error);
67666aee900SScott Liu 		return error;
67766aee900SScott Liu 	}
67866aee900SScott Liu 
67966aee900SScott Liu 	/* Clear the last page of Master */
68066aee900SScott Liu 	error = elants_i2c_send(client, fw->data, ELAN_FW_PAGESIZE);
68166aee900SScott Liu 	if (error) {
68266aee900SScott Liu 		dev_err(&client->dev, "clearing of the last page failed: %d\n",
68366aee900SScott Liu 			error);
68466aee900SScott Liu 		return error;
68566aee900SScott Liu 	}
68666aee900SScott Liu 
68766aee900SScott Liu 	error = elants_i2c_read(client, buf, 2);
68866aee900SScott Liu 	if (error) {
68966aee900SScott Liu 		dev_err(&client->dev,
69066aee900SScott Liu 			"failed to read ACK for clearing the last page: %d\n",
69166aee900SScott Liu 			error);
69266aee900SScott Liu 		return error;
69366aee900SScott Liu 	}
69466aee900SScott Liu 
69566aee900SScott Liu 	n_fw_pages = fw->size / ELAN_FW_PAGESIZE;
69666aee900SScott Liu 	dev_dbg(&client->dev, "IAP Pages = %d\n", n_fw_pages);
69766aee900SScott Liu 
69866aee900SScott Liu 	for (page = 0; page < n_fw_pages; page++) {
69966aee900SScott Liu 		error = elants_i2c_fw_write_page(client,
70066aee900SScott Liu 					fw->data + page * ELAN_FW_PAGESIZE);
70166aee900SScott Liu 		if (error) {
70266aee900SScott Liu 			dev_err(&client->dev,
70366aee900SScott Liu 				"failed to write FW page %d: %d\n",
70466aee900SScott Liu 				page, error);
70566aee900SScott Liu 			return error;
70666aee900SScott Liu 		}
70766aee900SScott Liu 	}
70866aee900SScott Liu 
70966aee900SScott Liu 	/* Old iap needs to wait 200ms for WDT and rest is for hello packets */
71066aee900SScott Liu 	msleep(300);
71166aee900SScott Liu 
71266aee900SScott Liu 	dev_info(&client->dev, "firmware update completed\n");
71366aee900SScott Liu 	return 0;
71466aee900SScott Liu }
71566aee900SScott Liu 
71666aee900SScott Liu static int elants_i2c_fw_update(struct elants_data *ts)
71766aee900SScott Liu {
71866aee900SScott Liu 	struct i2c_client *client = ts->client;
71966aee900SScott Liu 	const struct firmware *fw;
72037dee1acSCharlie Mooney 	char *fw_name;
72166aee900SScott Liu 	int error;
72266aee900SScott Liu 
7238c0776a8SDmitry Torokhov 	fw_name = kasprintf(GFP_KERNEL, "elants_i2c_%04x.bin", ts->hw_version);
72437dee1acSCharlie Mooney 	if (!fw_name)
72537dee1acSCharlie Mooney 		return -ENOMEM;
72637dee1acSCharlie Mooney 
72737dee1acSCharlie Mooney 	dev_info(&client->dev, "requesting fw name = %s\n", fw_name);
72837dee1acSCharlie Mooney 	error = request_firmware(&fw, fw_name, &client->dev);
72937dee1acSCharlie Mooney 	kfree(fw_name);
73066aee900SScott Liu 	if (error) {
73137dee1acSCharlie Mooney 		dev_err(&client->dev, "failed to request firmware: %d\n",
73237dee1acSCharlie Mooney 			error);
73366aee900SScott Liu 		return error;
73466aee900SScott Liu 	}
73566aee900SScott Liu 
73666aee900SScott Liu 	if (fw->size % ELAN_FW_PAGESIZE) {
73766aee900SScott Liu 		dev_err(&client->dev, "invalid firmware length: %zu\n",
73866aee900SScott Liu 			fw->size);
73966aee900SScott Liu 		error = -EINVAL;
74066aee900SScott Liu 		goto out;
74166aee900SScott Liu 	}
74266aee900SScott Liu 
74366aee900SScott Liu 	disable_irq(client->irq);
74466aee900SScott Liu 
74566aee900SScott Liu 	error = elants_i2c_do_update_firmware(client, fw,
74666aee900SScott Liu 					ts->iap_mode == ELAN_IAP_RECOVERY);
74766aee900SScott Liu 	if (error) {
74866aee900SScott Liu 		dev_err(&client->dev, "firmware update failed: %d\n", error);
74966aee900SScott Liu 		ts->iap_mode = ELAN_IAP_RECOVERY;
75066aee900SScott Liu 		goto out_enable_irq;
75166aee900SScott Liu 	}
75266aee900SScott Liu 
75366aee900SScott Liu 	error = elants_i2c_initialize(ts);
75466aee900SScott Liu 	if (error) {
75566aee900SScott Liu 		dev_err(&client->dev,
75666aee900SScott Liu 			"failed to initialize device after firmware update: %d\n",
75766aee900SScott Liu 			error);
75866aee900SScott Liu 		ts->iap_mode = ELAN_IAP_RECOVERY;
75966aee900SScott Liu 		goto out_enable_irq;
76066aee900SScott Liu 	}
76166aee900SScott Liu 
76266aee900SScott Liu 	ts->iap_mode = ELAN_IAP_OPERATIONAL;
76366aee900SScott Liu 
76466aee900SScott Liu out_enable_irq:
76566aee900SScott Liu 	ts->state = ELAN_STATE_NORMAL;
76666aee900SScott Liu 	enable_irq(client->irq);
76766aee900SScott Liu 	msleep(100);
76866aee900SScott Liu 
76966aee900SScott Liu 	if (!error)
77066aee900SScott Liu 		elants_i2c_calibrate(ts);
77166aee900SScott Liu out:
77266aee900SScott Liu 	release_firmware(fw);
77366aee900SScott Liu 	return error;
77466aee900SScott Liu }
77566aee900SScott Liu 
77666aee900SScott Liu /*
77766aee900SScott Liu  * Event reporting.
77866aee900SScott Liu  */
77966aee900SScott Liu 
78066aee900SScott Liu static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
78166aee900SScott Liu {
78266aee900SScott Liu 	struct input_dev *input = ts->input;
78366aee900SScott Liu 	unsigned int n_fingers;
78466aee900SScott Liu 	u16 finger_state;
78566aee900SScott Liu 	int i;
78666aee900SScott Liu 
78766aee900SScott Liu 	n_fingers = buf[FW_POS_STATE + 1] & 0x0f;
78866aee900SScott Liu 	finger_state = ((buf[FW_POS_STATE + 1] & 0x30) << 4) |
78966aee900SScott Liu 			buf[FW_POS_STATE];
79066aee900SScott Liu 
79166aee900SScott Liu 	dev_dbg(&ts->client->dev,
79266aee900SScott Liu 		"n_fingers: %u, state: %04x\n",  n_fingers, finger_state);
79366aee900SScott Liu 
79466aee900SScott Liu 	for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) {
79566aee900SScott Liu 		if (finger_state & 1) {
79666aee900SScott Liu 			unsigned int x, y, p, w;
79766aee900SScott Liu 			u8 *pos;
79866aee900SScott Liu 
79966aee900SScott Liu 			pos = &buf[FW_POS_XY + i * 3];
80066aee900SScott Liu 			x = (((u16)pos[0] & 0xf0) << 4) | pos[1];
80166aee900SScott Liu 			y = (((u16)pos[0] & 0x0f) << 8) | pos[2];
80266aee900SScott Liu 			p = buf[FW_POS_PRESSURE + i];
80366aee900SScott Liu 			w = buf[FW_POS_WIDTH + i];
80466aee900SScott Liu 
80566aee900SScott Liu 			dev_dbg(&ts->client->dev, "i=%d x=%d y=%d p=%d w=%d\n",
80666aee900SScott Liu 				i, x, y, p, w);
80766aee900SScott Liu 
80866aee900SScott Liu 			input_mt_slot(input, i);
80966aee900SScott Liu 			input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
81066aee900SScott Liu 			input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
81166aee900SScott Liu 			input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
81266aee900SScott Liu 			input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
81366aee900SScott Liu 			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w);
81466aee900SScott Liu 
81566aee900SScott Liu 			n_fingers--;
81666aee900SScott Liu 		}
81766aee900SScott Liu 
81866aee900SScott Liu 		finger_state >>= 1;
81966aee900SScott Liu 	}
82066aee900SScott Liu 
82166aee900SScott Liu 	input_mt_sync_frame(input);
82266aee900SScott Liu 	input_sync(input);
82366aee900SScott Liu }
82466aee900SScott Liu 
82566aee900SScott Liu static u8 elants_i2c_calculate_checksum(u8 *buf)
82666aee900SScott Liu {
82766aee900SScott Liu 	u8 checksum = 0;
82866aee900SScott Liu 	u8 i;
82966aee900SScott Liu 
83066aee900SScott Liu 	for (i = 0; i < FW_POS_CHECKSUM; i++)
83166aee900SScott Liu 		checksum += buf[i];
83266aee900SScott Liu 
83366aee900SScott Liu 	return checksum;
83466aee900SScott Liu }
83566aee900SScott Liu 
83666aee900SScott Liu static void elants_i2c_event(struct elants_data *ts, u8 *buf)
83766aee900SScott Liu {
83866aee900SScott Liu 	u8 checksum = elants_i2c_calculate_checksum(buf);
83966aee900SScott Liu 
84066aee900SScott Liu 	if (unlikely(buf[FW_POS_CHECKSUM] != checksum))
84166aee900SScott Liu 		dev_warn(&ts->client->dev,
84266aee900SScott Liu 			 "%s: invalid checksum for packet %02x: %02x vs. %02x\n",
84366aee900SScott Liu 			 __func__, buf[FW_POS_HEADER],
84466aee900SScott Liu 			 checksum, buf[FW_POS_CHECKSUM]);
84566aee900SScott Liu 	else if (unlikely(buf[FW_POS_HEADER] != HEADER_REPORT_10_FINGER))
84666aee900SScott Liu 		dev_warn(&ts->client->dev,
84766aee900SScott Liu 			 "%s: unknown packet type: %02x\n",
84866aee900SScott Liu 			 __func__, buf[FW_POS_HEADER]);
84966aee900SScott Liu 	else
85066aee900SScott Liu 		elants_i2c_mt_event(ts, buf);
85166aee900SScott Liu }
85266aee900SScott Liu 
85366aee900SScott Liu static irqreturn_t elants_i2c_irq(int irq, void *_dev)
85466aee900SScott Liu {
85566aee900SScott Liu 	const u8 wait_packet[] = { 0x64, 0x64, 0x64, 0x64 };
85666aee900SScott Liu 	struct elants_data *ts = _dev;
85766aee900SScott Liu 	struct i2c_client *client = ts->client;
85866aee900SScott Liu 	int report_count, report_len;
85966aee900SScott Liu 	int i;
86066aee900SScott Liu 	int len;
86166aee900SScott Liu 
86200f73f97SStephen Boyd 	len = i2c_master_recv_dmasafe(client, ts->buf, sizeof(ts->buf));
86366aee900SScott Liu 	if (len < 0) {
86466aee900SScott Liu 		dev_err(&client->dev, "%s: failed to read data: %d\n",
86566aee900SScott Liu 			__func__, len);
86666aee900SScott Liu 		goto out;
86766aee900SScott Liu 	}
86866aee900SScott Liu 
86966aee900SScott Liu 	dev_dbg(&client->dev, "%s: packet %*ph\n",
87066aee900SScott Liu 		__func__, HEADER_SIZE, ts->buf);
87166aee900SScott Liu 
87266aee900SScott Liu 	switch (ts->state) {
87366aee900SScott Liu 	case ELAN_WAIT_RECALIBRATION:
87466aee900SScott Liu 		if (ts->buf[FW_HDR_TYPE] == CMD_HEADER_REK) {
87566aee900SScott Liu 			memcpy(ts->cmd_resp, ts->buf, sizeof(ts->cmd_resp));
87666aee900SScott Liu 			complete(&ts->cmd_done);
87766aee900SScott Liu 			ts->state = ELAN_STATE_NORMAL;
87866aee900SScott Liu 		}
87966aee900SScott Liu 		break;
88066aee900SScott Liu 
88166aee900SScott Liu 	case ELAN_WAIT_QUEUE_HEADER:
88266aee900SScott Liu 		if (ts->buf[FW_HDR_TYPE] != QUEUE_HEADER_NORMAL)
88366aee900SScott Liu 			break;
88466aee900SScott Liu 
88566aee900SScott Liu 		ts->state = ELAN_STATE_NORMAL;
88666aee900SScott Liu 		/* fall through */
88766aee900SScott Liu 
88866aee900SScott Liu 	case ELAN_STATE_NORMAL:
88966aee900SScott Liu 
89066aee900SScott Liu 		switch (ts->buf[FW_HDR_TYPE]) {
89166aee900SScott Liu 		case CMD_HEADER_HELLO:
89266aee900SScott Liu 		case CMD_HEADER_RESP:
89366aee900SScott Liu 		case CMD_HEADER_REK:
89466aee900SScott Liu 			break;
89566aee900SScott Liu 
89666aee900SScott Liu 		case QUEUE_HEADER_WAIT:
89766aee900SScott Liu 			if (memcmp(ts->buf, wait_packet, sizeof(wait_packet))) {
89866aee900SScott Liu 				dev_err(&client->dev,
89966aee900SScott Liu 					"invalid wait packet %*ph\n",
90066aee900SScott Liu 					HEADER_SIZE, ts->buf);
90166aee900SScott Liu 			} else {
90266aee900SScott Liu 				ts->state = ELAN_WAIT_QUEUE_HEADER;
90366aee900SScott Liu 				udelay(30);
90466aee900SScott Liu 			}
90566aee900SScott Liu 			break;
90666aee900SScott Liu 
90766aee900SScott Liu 		case QUEUE_HEADER_SINGLE:
90866aee900SScott Liu 			elants_i2c_event(ts, &ts->buf[HEADER_SIZE]);
90966aee900SScott Liu 			break;
91066aee900SScott Liu 
91166aee900SScott Liu 		case QUEUE_HEADER_NORMAL:
91266aee900SScott Liu 			report_count = ts->buf[FW_HDR_COUNT];
9131c3415a0SGuenter Roeck 			if (report_count == 0 || report_count > 3) {
91466aee900SScott Liu 				dev_err(&client->dev,
9151c3415a0SGuenter Roeck 					"bad report count: %*ph\n",
91666aee900SScott Liu 					HEADER_SIZE, ts->buf);
91766aee900SScott Liu 				break;
91866aee900SScott Liu 			}
91966aee900SScott Liu 
92066aee900SScott Liu 			report_len = ts->buf[FW_HDR_LENGTH] / report_count;
92166aee900SScott Liu 			if (report_len != PACKET_SIZE) {
92266aee900SScott Liu 				dev_err(&client->dev,
92366aee900SScott Liu 					"mismatching report length: %*ph\n",
92466aee900SScott Liu 					HEADER_SIZE, ts->buf);
92566aee900SScott Liu 				break;
92666aee900SScott Liu 			}
92766aee900SScott Liu 
92866aee900SScott Liu 			for (i = 0; i < report_count; i++) {
92966aee900SScott Liu 				u8 *buf = ts->buf + HEADER_SIZE +
93066aee900SScott Liu 							i * PACKET_SIZE;
93166aee900SScott Liu 				elants_i2c_event(ts, buf);
93266aee900SScott Liu 			}
93366aee900SScott Liu 			break;
93466aee900SScott Liu 
93566aee900SScott Liu 		default:
93666aee900SScott Liu 			dev_err(&client->dev, "unknown packet %*ph\n",
93766aee900SScott Liu 				HEADER_SIZE, ts->buf);
93866aee900SScott Liu 			break;
93966aee900SScott Liu 		}
94066aee900SScott Liu 		break;
94166aee900SScott Liu 	}
94266aee900SScott Liu 
94366aee900SScott Liu out:
94466aee900SScott Liu 	return IRQ_HANDLED;
94566aee900SScott Liu }
94666aee900SScott Liu 
94766aee900SScott Liu /*
94866aee900SScott Liu  * sysfs interface
94966aee900SScott Liu  */
95066aee900SScott Liu static ssize_t calibrate_store(struct device *dev,
95166aee900SScott Liu 			       struct device_attribute *attr,
95266aee900SScott Liu 			      const char *buf, size_t count)
95366aee900SScott Liu {
95466aee900SScott Liu 	struct i2c_client *client = to_i2c_client(dev);
95566aee900SScott Liu 	struct elants_data *ts = i2c_get_clientdata(client);
95666aee900SScott Liu 	int error;
95766aee900SScott Liu 
95866aee900SScott Liu 	error = mutex_lock_interruptible(&ts->sysfs_mutex);
95966aee900SScott Liu 	if (error)
96066aee900SScott Liu 		return error;
96166aee900SScott Liu 
96266aee900SScott Liu 	error = elants_i2c_calibrate(ts);
96366aee900SScott Liu 
96466aee900SScott Liu 	mutex_unlock(&ts->sysfs_mutex);
96566aee900SScott Liu 	return error ?: count;
96666aee900SScott Liu }
96766aee900SScott Liu 
96866aee900SScott Liu static ssize_t write_update_fw(struct device *dev,
96966aee900SScott Liu 			       struct device_attribute *attr,
97066aee900SScott Liu 			       const char *buf, size_t count)
97166aee900SScott Liu {
97266aee900SScott Liu 	struct i2c_client *client = to_i2c_client(dev);
97366aee900SScott Liu 	struct elants_data *ts = i2c_get_clientdata(client);
97466aee900SScott Liu 	int error;
97566aee900SScott Liu 
97666aee900SScott Liu 	error = mutex_lock_interruptible(&ts->sysfs_mutex);
97766aee900SScott Liu 	if (error)
97866aee900SScott Liu 		return error;
97966aee900SScott Liu 
98066aee900SScott Liu 	error = elants_i2c_fw_update(ts);
98166aee900SScott Liu 	dev_dbg(dev, "firmware update result: %d\n", error);
98266aee900SScott Liu 
98366aee900SScott Liu 	mutex_unlock(&ts->sysfs_mutex);
98466aee900SScott Liu 	return error ?: count;
98566aee900SScott Liu }
98666aee900SScott Liu 
98766aee900SScott Liu static ssize_t show_iap_mode(struct device *dev,
98866aee900SScott Liu 			     struct device_attribute *attr, char *buf)
98966aee900SScott Liu {
99066aee900SScott Liu 	struct i2c_client *client = to_i2c_client(dev);
99166aee900SScott Liu 	struct elants_data *ts = i2c_get_clientdata(client);
99266aee900SScott Liu 
99366aee900SScott Liu 	return sprintf(buf, "%s\n",
99466aee900SScott Liu 		       ts->iap_mode == ELAN_IAP_OPERATIONAL ?
99566aee900SScott Liu 				"Normal" : "Recovery");
99666aee900SScott Liu }
99766aee900SScott Liu 
9986cbaefb4SJoe Perches static DEVICE_ATTR_WO(calibrate);
99966aee900SScott Liu static DEVICE_ATTR(iap_mode, S_IRUGO, show_iap_mode, NULL);
100066aee900SScott Liu static DEVICE_ATTR(update_fw, S_IWUSR, NULL, write_update_fw);
100166aee900SScott Liu 
100266aee900SScott Liu struct elants_version_attribute {
100366aee900SScott Liu 	struct device_attribute dattr;
100466aee900SScott Liu 	size_t field_offset;
100566aee900SScott Liu 	size_t field_size;
100666aee900SScott Liu };
100766aee900SScott Liu 
100866aee900SScott Liu #define __ELANTS_FIELD_SIZE(_field)					\
100966aee900SScott Liu 	sizeof(((struct elants_data *)NULL)->_field)
101066aee900SScott Liu #define __ELANTS_VERIFY_SIZE(_field)					\
101166aee900SScott Liu 	(BUILD_BUG_ON_ZERO(__ELANTS_FIELD_SIZE(_field) > 2) +		\
101266aee900SScott Liu 	 __ELANTS_FIELD_SIZE(_field))
101366aee900SScott Liu #define ELANTS_VERSION_ATTR(_field)					\
101466aee900SScott Liu 	struct elants_version_attribute elants_ver_attr_##_field = {	\
101566aee900SScott Liu 		.dattr = __ATTR(_field, S_IRUGO,			\
101666aee900SScott Liu 				elants_version_attribute_show, NULL),	\
101766aee900SScott Liu 		.field_offset = offsetof(struct elants_data, _field),	\
101866aee900SScott Liu 		.field_size = __ELANTS_VERIFY_SIZE(_field),		\
101966aee900SScott Liu 	}
102066aee900SScott Liu 
102166aee900SScott Liu static ssize_t elants_version_attribute_show(struct device *dev,
102266aee900SScott Liu 					     struct device_attribute *dattr,
102366aee900SScott Liu 					     char *buf)
102466aee900SScott Liu {
102566aee900SScott Liu 	struct i2c_client *client = to_i2c_client(dev);
102666aee900SScott Liu 	struct elants_data *ts = i2c_get_clientdata(client);
102766aee900SScott Liu 	struct elants_version_attribute *attr =
102866aee900SScott Liu 		container_of(dattr, struct elants_version_attribute, dattr);
102966aee900SScott Liu 	u8 *field = (u8 *)((char *)ts + attr->field_offset);
103066aee900SScott Liu 	unsigned int fmt_size;
103166aee900SScott Liu 	unsigned int val;
103266aee900SScott Liu 
103366aee900SScott Liu 	if (attr->field_size == 1) {
103466aee900SScott Liu 		val = *field;
103566aee900SScott Liu 		fmt_size = 2; /* 2 HEX digits */
103666aee900SScott Liu 	} else {
103766aee900SScott Liu 		val = *(u16 *)field;
103866aee900SScott Liu 		fmt_size = 4; /* 4 HEX digits */
103966aee900SScott Liu 	}
104066aee900SScott Liu 
104166aee900SScott Liu 	return sprintf(buf, "%0*x\n", fmt_size, val);
104266aee900SScott Liu }
104366aee900SScott Liu 
104466aee900SScott Liu static ELANTS_VERSION_ATTR(fw_version);
104566aee900SScott Liu static ELANTS_VERSION_ATTR(hw_version);
104666aee900SScott Liu static ELANTS_VERSION_ATTR(test_version);
104766aee900SScott Liu static ELANTS_VERSION_ATTR(solution_version);
104866aee900SScott Liu static ELANTS_VERSION_ATTR(bc_version);
104966aee900SScott Liu static ELANTS_VERSION_ATTR(iap_version);
105066aee900SScott Liu 
105166aee900SScott Liu static struct attribute *elants_attributes[] = {
105266aee900SScott Liu 	&dev_attr_calibrate.attr,
105366aee900SScott Liu 	&dev_attr_update_fw.attr,
105466aee900SScott Liu 	&dev_attr_iap_mode.attr,
105566aee900SScott Liu 
105666aee900SScott Liu 	&elants_ver_attr_fw_version.dattr.attr,
105766aee900SScott Liu 	&elants_ver_attr_hw_version.dattr.attr,
105866aee900SScott Liu 	&elants_ver_attr_test_version.dattr.attr,
105966aee900SScott Liu 	&elants_ver_attr_solution_version.dattr.attr,
106066aee900SScott Liu 	&elants_ver_attr_bc_version.dattr.attr,
106166aee900SScott Liu 	&elants_ver_attr_iap_version.dattr.attr,
106266aee900SScott Liu 	NULL
106366aee900SScott Liu };
106466aee900SScott Liu 
106548f960ddSArvind Yadav static const struct attribute_group elants_attribute_group = {
106666aee900SScott Liu 	.attrs = elants_attributes,
106766aee900SScott Liu };
106866aee900SScott Liu 
1069afe10358SDmitry Torokhov static int elants_i2c_power_on(struct elants_data *ts)
1070afe10358SDmitry Torokhov {
1071afe10358SDmitry Torokhov 	int error;
1072afe10358SDmitry Torokhov 
1073afe10358SDmitry Torokhov 	/*
1074afe10358SDmitry Torokhov 	 * If we do not have reset gpio assume platform firmware
1075afe10358SDmitry Torokhov 	 * controls regulators and does power them on for us.
1076afe10358SDmitry Torokhov 	 */
1077afe10358SDmitry Torokhov 	if (IS_ERR_OR_NULL(ts->reset_gpio))
1078afe10358SDmitry Torokhov 		return 0;
1079afe10358SDmitry Torokhov 
1080afe10358SDmitry Torokhov 	gpiod_set_value_cansleep(ts->reset_gpio, 1);
1081afe10358SDmitry Torokhov 
1082afe10358SDmitry Torokhov 	error = regulator_enable(ts->vcc33);
1083afe10358SDmitry Torokhov 	if (error) {
1084afe10358SDmitry Torokhov 		dev_err(&ts->client->dev,
1085afe10358SDmitry Torokhov 			"failed to enable vcc33 regulator: %d\n",
1086afe10358SDmitry Torokhov 			error);
1087afe10358SDmitry Torokhov 		goto release_reset_gpio;
1088afe10358SDmitry Torokhov 	}
1089afe10358SDmitry Torokhov 
1090afe10358SDmitry Torokhov 	error = regulator_enable(ts->vccio);
1091afe10358SDmitry Torokhov 	if (error) {
1092afe10358SDmitry Torokhov 		dev_err(&ts->client->dev,
1093afe10358SDmitry Torokhov 			"failed to enable vccio regulator: %d\n",
1094afe10358SDmitry Torokhov 			error);
1095afe10358SDmitry Torokhov 		regulator_disable(ts->vcc33);
1096afe10358SDmitry Torokhov 		goto release_reset_gpio;
1097afe10358SDmitry Torokhov 	}
1098afe10358SDmitry Torokhov 
1099afe10358SDmitry Torokhov 	/*
1100afe10358SDmitry Torokhov 	 * We need to wait a bit after powering on controller before
1101afe10358SDmitry Torokhov 	 * we are allowed to release reset GPIO.
1102afe10358SDmitry Torokhov 	 */
1103afe10358SDmitry Torokhov 	udelay(ELAN_POWERON_DELAY_USEC);
1104afe10358SDmitry Torokhov 
1105afe10358SDmitry Torokhov release_reset_gpio:
1106afe10358SDmitry Torokhov 	gpiod_set_value_cansleep(ts->reset_gpio, 0);
1107afe10358SDmitry Torokhov 	if (error)
1108afe10358SDmitry Torokhov 		return error;
1109afe10358SDmitry Torokhov 
1110afe10358SDmitry Torokhov 	msleep(ELAN_RESET_DELAY_MSEC);
1111afe10358SDmitry Torokhov 
1112afe10358SDmitry Torokhov 	return 0;
1113afe10358SDmitry Torokhov }
1114afe10358SDmitry Torokhov 
1115afe10358SDmitry Torokhov static void elants_i2c_power_off(void *_data)
1116afe10358SDmitry Torokhov {
1117afe10358SDmitry Torokhov 	struct elants_data *ts = _data;
1118afe10358SDmitry Torokhov 
1119afe10358SDmitry Torokhov 	if (!IS_ERR_OR_NULL(ts->reset_gpio)) {
1120afe10358SDmitry Torokhov 		/*
1121afe10358SDmitry Torokhov 		 * Activate reset gpio to prevent leakage through the
1122afe10358SDmitry Torokhov 		 * pin once we shut off power to the controller.
1123afe10358SDmitry Torokhov 		 */
1124afe10358SDmitry Torokhov 		gpiod_set_value_cansleep(ts->reset_gpio, 1);
1125afe10358SDmitry Torokhov 		regulator_disable(ts->vccio);
1126afe10358SDmitry Torokhov 		regulator_disable(ts->vcc33);
1127afe10358SDmitry Torokhov 	}
1128afe10358SDmitry Torokhov }
1129afe10358SDmitry Torokhov 
113066aee900SScott Liu static int elants_i2c_probe(struct i2c_client *client,
113166aee900SScott Liu 			    const struct i2c_device_id *id)
113266aee900SScott Liu {
113366aee900SScott Liu 	union i2c_smbus_data dummy;
113466aee900SScott Liu 	struct elants_data *ts;
113566aee900SScott Liu 	unsigned long irqflags;
113666aee900SScott Liu 	int error;
113766aee900SScott Liu 
113866aee900SScott Liu 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
113966aee900SScott Liu 		dev_err(&client->dev,
114066aee900SScott Liu 			"%s: i2c check functionality error\n", DEVICE_NAME);
114166aee900SScott Liu 		return -ENXIO;
114266aee900SScott Liu 	}
114366aee900SScott Liu 
114466aee900SScott Liu 	ts = devm_kzalloc(&client->dev, sizeof(struct elants_data), GFP_KERNEL);
114566aee900SScott Liu 	if (!ts)
114666aee900SScott Liu 		return -ENOMEM;
114766aee900SScott Liu 
114866aee900SScott Liu 	mutex_init(&ts->sysfs_mutex);
114966aee900SScott Liu 	init_completion(&ts->cmd_done);
115066aee900SScott Liu 
115166aee900SScott Liu 	ts->client = client;
115266aee900SScott Liu 	i2c_set_clientdata(client, ts);
115366aee900SScott Liu 
1154afe10358SDmitry Torokhov 	ts->vcc33 = devm_regulator_get(&client->dev, "vcc33");
1155afe10358SDmitry Torokhov 	if (IS_ERR(ts->vcc33)) {
1156afe10358SDmitry Torokhov 		error = PTR_ERR(ts->vcc33);
1157afe10358SDmitry Torokhov 		if (error != -EPROBE_DEFER)
1158afe10358SDmitry Torokhov 			dev_err(&client->dev,
1159afe10358SDmitry Torokhov 				"Failed to get 'vcc33' regulator: %d\n",
1160afe10358SDmitry Torokhov 				error);
1161afe10358SDmitry Torokhov 		return error;
1162afe10358SDmitry Torokhov 	}
1163afe10358SDmitry Torokhov 
1164afe10358SDmitry Torokhov 	ts->vccio = devm_regulator_get(&client->dev, "vccio");
1165afe10358SDmitry Torokhov 	if (IS_ERR(ts->vccio)) {
1166afe10358SDmitry Torokhov 		error = PTR_ERR(ts->vccio);
1167afe10358SDmitry Torokhov 		if (error != -EPROBE_DEFER)
1168afe10358SDmitry Torokhov 			dev_err(&client->dev,
1169afe10358SDmitry Torokhov 				"Failed to get 'vccio' regulator: %d\n",
1170afe10358SDmitry Torokhov 				error);
1171afe10358SDmitry Torokhov 		return error;
1172afe10358SDmitry Torokhov 	}
1173afe10358SDmitry Torokhov 
11747229b87bSStephen Rothwell 	ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
1175afe10358SDmitry Torokhov 	if (IS_ERR(ts->reset_gpio)) {
1176afe10358SDmitry Torokhov 		error = PTR_ERR(ts->reset_gpio);
1177afe10358SDmitry Torokhov 
1178afe10358SDmitry Torokhov 		if (error == -EPROBE_DEFER)
1179afe10358SDmitry Torokhov 			return error;
1180afe10358SDmitry Torokhov 
1181afe10358SDmitry Torokhov 		if (error != -ENOENT && error != -ENOSYS) {
1182afe10358SDmitry Torokhov 			dev_err(&client->dev,
1183afe10358SDmitry Torokhov 				"failed to get reset gpio: %d\n",
1184afe10358SDmitry Torokhov 				error);
1185afe10358SDmitry Torokhov 			return error;
1186afe10358SDmitry Torokhov 		}
1187afe10358SDmitry Torokhov 
1188afe10358SDmitry Torokhov 		ts->keep_power_in_suspend = true;
1189afe10358SDmitry Torokhov 	}
1190afe10358SDmitry Torokhov 
1191afe10358SDmitry Torokhov 	error = elants_i2c_power_on(ts);
1192afe10358SDmitry Torokhov 	if (error)
1193afe10358SDmitry Torokhov 		return error;
1194afe10358SDmitry Torokhov 
1195afe10358SDmitry Torokhov 	error = devm_add_action(&client->dev, elants_i2c_power_off, ts);
1196afe10358SDmitry Torokhov 	if (error) {
1197afe10358SDmitry Torokhov 		dev_err(&client->dev,
1198afe10358SDmitry Torokhov 			"failed to install power off action: %d\n", error);
1199afe10358SDmitry Torokhov 		elants_i2c_power_off(ts);
1200afe10358SDmitry Torokhov 		return error;
1201afe10358SDmitry Torokhov 	}
1202afe10358SDmitry Torokhov 
1203afe10358SDmitry Torokhov 	/* Make sure there is something at this address */
1204afe10358SDmitry Torokhov 	if (i2c_smbus_xfer(client->adapter, client->addr, 0,
1205afe10358SDmitry Torokhov 			   I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0) {
1206afe10358SDmitry Torokhov 		dev_err(&client->dev, "nothing at this address\n");
1207afe10358SDmitry Torokhov 		return -ENXIO;
1208afe10358SDmitry Torokhov 	}
1209afe10358SDmitry Torokhov 
121066aee900SScott Liu 	error = elants_i2c_initialize(ts);
121166aee900SScott Liu 	if (error) {
121266aee900SScott Liu 		dev_err(&client->dev, "failed to initialize: %d\n", error);
121366aee900SScott Liu 		return error;
121466aee900SScott Liu 	}
121566aee900SScott Liu 
121666aee900SScott Liu 	ts->input = devm_input_allocate_device(&client->dev);
121766aee900SScott Liu 	if (!ts->input) {
121866aee900SScott Liu 		dev_err(&client->dev, "Failed to allocate input device\n");
121966aee900SScott Liu 		return -ENOMEM;
122066aee900SScott Liu 	}
122166aee900SScott Liu 
122266aee900SScott Liu 	ts->input->name = "Elan Touchscreen";
122366aee900SScott Liu 	ts->input->id.bustype = BUS_I2C;
122466aee900SScott Liu 
122566aee900SScott Liu 	__set_bit(BTN_TOUCH, ts->input->keybit);
122666aee900SScott Liu 	__set_bit(EV_ABS, ts->input->evbit);
122766aee900SScott Liu 	__set_bit(EV_KEY, ts->input->evbit);
122866aee900SScott Liu 
122966aee900SScott Liu 	/* Single touch input params setup */
123066aee900SScott Liu 	input_set_abs_params(ts->input, ABS_X, 0, ts->x_max, 0, 0);
123166aee900SScott Liu 	input_set_abs_params(ts->input, ABS_Y, 0, ts->y_max, 0, 0);
123266aee900SScott Liu 	input_set_abs_params(ts->input, ABS_PRESSURE, 0, 255, 0, 0);
123366aee900SScott Liu 	input_abs_set_res(ts->input, ABS_X, ts->x_res);
123466aee900SScott Liu 	input_abs_set_res(ts->input, ABS_Y, ts->y_res);
123566aee900SScott Liu 
123666aee900SScott Liu 	/* Multitouch input params setup */
123766aee900SScott Liu 	error = input_mt_init_slots(ts->input, MAX_CONTACT_NUM,
123866aee900SScott Liu 				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
123966aee900SScott Liu 	if (error) {
124066aee900SScott Liu 		dev_err(&client->dev,
124166aee900SScott Liu 			"failed to initialize MT slots: %d\n", error);
124266aee900SScott Liu 		return error;
124366aee900SScott Liu 	}
124466aee900SScott Liu 
124566aee900SScott Liu 	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, 0, 0);
124666aee900SScott Liu 	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
124766aee900SScott Liu 	input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
124866aee900SScott Liu 	input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
124966aee900SScott Liu 	input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res);
125066aee900SScott Liu 	input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
125166aee900SScott Liu 
125266aee900SScott Liu 	error = input_register_device(ts->input);
125366aee900SScott Liu 	if (error) {
125466aee900SScott Liu 		dev_err(&client->dev,
125566aee900SScott Liu 			"unable to register input device: %d\n", error);
125666aee900SScott Liu 		return error;
125766aee900SScott Liu 	}
125866aee900SScott Liu 
125966aee900SScott Liu 	/*
12604c83c071SDmitry Torokhov 	 * Platform code (ACPI, DTS) should normally set up interrupt
12614c83c071SDmitry Torokhov 	 * for us, but in case it did not let's fall back to using falling
12624c83c071SDmitry Torokhov 	 * edge to be compatible with older Chromebooks.
126366aee900SScott Liu 	 */
12644c83c071SDmitry Torokhov 	irqflags = irq_get_trigger_type(client->irq);
12654c83c071SDmitry Torokhov 	if (!irqflags)
12664c83c071SDmitry Torokhov 		irqflags = IRQF_TRIGGER_FALLING;
126766aee900SScott Liu 
126866aee900SScott Liu 	error = devm_request_threaded_irq(&client->dev, client->irq,
126966aee900SScott Liu 					  NULL, elants_i2c_irq,
127066aee900SScott Liu 					  irqflags | IRQF_ONESHOT,
127166aee900SScott Liu 					  client->name, ts);
127266aee900SScott Liu 	if (error) {
127366aee900SScott Liu 		dev_err(&client->dev, "Failed to register interrupt\n");
127466aee900SScott Liu 		return error;
127566aee900SScott Liu 	}
127666aee900SScott Liu 
127766aee900SScott Liu 	/*
127866aee900SScott Liu 	 * Systems using device tree should set up wakeup via DTS,
127966aee900SScott Liu 	 * the rest will configure device as wakeup source by default.
128066aee900SScott Liu 	 */
128166aee900SScott Liu 	if (!client->dev.of_node)
128266aee900SScott Liu 		device_init_wakeup(&client->dev, true);
128366aee900SScott Liu 
12848db69a9aSAndi Shyti 	error = devm_device_add_group(&client->dev, &elants_attribute_group);
128566aee900SScott Liu 	if (error) {
128666aee900SScott Liu 		dev_err(&client->dev, "failed to create sysfs attributes: %d\n",
128766aee900SScott Liu 			error);
128866aee900SScott Liu 		return error;
128966aee900SScott Liu 	}
129066aee900SScott Liu 
129166aee900SScott Liu 	return 0;
129266aee900SScott Liu }
129366aee900SScott Liu 
129466aee900SScott Liu static int __maybe_unused elants_i2c_suspend(struct device *dev)
129566aee900SScott Liu {
129666aee900SScott Liu 	struct i2c_client *client = to_i2c_client(dev);
129766aee900SScott Liu 	struct elants_data *ts = i2c_get_clientdata(client);
129866aee900SScott Liu 	const u8 set_sleep_cmd[] = { 0x54, 0x50, 0x00, 0x01 };
129966aee900SScott Liu 	int retry_cnt;
130066aee900SScott Liu 	int error;
130166aee900SScott Liu 
130266aee900SScott Liu 	/* Command not support in IAP recovery mode */
130366aee900SScott Liu 	if (ts->iap_mode != ELAN_IAP_OPERATIONAL)
130466aee900SScott Liu 		return -EBUSY;
130566aee900SScott Liu 
130666aee900SScott Liu 	disable_irq(client->irq);
130766aee900SScott Liu 
1308478e5ed1SJames Chen 	if (device_may_wakeup(dev)) {
1309478e5ed1SJames Chen 		/*
1310478e5ed1SJames Chen 		 * The device will automatically enter idle mode
1311478e5ed1SJames Chen 		 * that has reduced power consumption.
1312478e5ed1SJames Chen 		 */
1313478e5ed1SJames Chen 		ts->wake_irq_enabled = (enable_irq_wake(client->irq) == 0);
1314478e5ed1SJames Chen 	} else if (ts->keep_power_in_suspend) {
131566aee900SScott Liu 		for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
131666aee900SScott Liu 			error = elants_i2c_send(client, set_sleep_cmd,
131766aee900SScott Liu 						sizeof(set_sleep_cmd));
131866aee900SScott Liu 			if (!error)
131966aee900SScott Liu 				break;
132066aee900SScott Liu 
1321afe10358SDmitry Torokhov 			dev_err(&client->dev,
1322afe10358SDmitry Torokhov 				"suspend command failed: %d\n", error);
132366aee900SScott Liu 		}
1324afe10358SDmitry Torokhov 	} else {
1325afe10358SDmitry Torokhov 		elants_i2c_power_off(ts);
1326afe10358SDmitry Torokhov 	}
132766aee900SScott Liu 
132866aee900SScott Liu 	return 0;
132966aee900SScott Liu }
133066aee900SScott Liu 
133166aee900SScott Liu static int __maybe_unused elants_i2c_resume(struct device *dev)
133266aee900SScott Liu {
133366aee900SScott Liu 	struct i2c_client *client = to_i2c_client(dev);
133466aee900SScott Liu 	struct elants_data *ts = i2c_get_clientdata(client);
133566aee900SScott Liu 	const u8 set_active_cmd[] = { 0x54, 0x58, 0x00, 0x01 };
133666aee900SScott Liu 	int retry_cnt;
133766aee900SScott Liu 	int error;
133866aee900SScott Liu 
1339478e5ed1SJames Chen 	if (device_may_wakeup(dev)) {
1340478e5ed1SJames Chen 		if (ts->wake_irq_enabled)
134166aee900SScott Liu 			disable_irq_wake(client->irq);
1342478e5ed1SJames Chen 		elants_i2c_sw_reset(client);
1343478e5ed1SJames Chen 	} else if (ts->keep_power_in_suspend) {
134466aee900SScott Liu 		for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
134566aee900SScott Liu 			error = elants_i2c_send(client, set_active_cmd,
134666aee900SScott Liu 						sizeof(set_active_cmd));
134766aee900SScott Liu 			if (!error)
134866aee900SScott Liu 				break;
134966aee900SScott Liu 
1350afe10358SDmitry Torokhov 			dev_err(&client->dev,
1351afe10358SDmitry Torokhov 				"resume command failed: %d\n", error);
1352afe10358SDmitry Torokhov 		}
1353afe10358SDmitry Torokhov 	} else {
1354afe10358SDmitry Torokhov 		elants_i2c_power_on(ts);
1355afe10358SDmitry Torokhov 		elants_i2c_initialize(ts);
135666aee900SScott Liu 	}
135766aee900SScott Liu 
135866aee900SScott Liu 	ts->state = ELAN_STATE_NORMAL;
135966aee900SScott Liu 	enable_irq(client->irq);
136066aee900SScott Liu 
136166aee900SScott Liu 	return 0;
136266aee900SScott Liu }
136366aee900SScott Liu 
136466aee900SScott Liu static SIMPLE_DEV_PM_OPS(elants_i2c_pm_ops,
136566aee900SScott Liu 			 elants_i2c_suspend, elants_i2c_resume);
136666aee900SScott Liu 
136766aee900SScott Liu static const struct i2c_device_id elants_i2c_id[] = {
136866aee900SScott Liu 	{ DEVICE_NAME, 0 },
136966aee900SScott Liu 	{ }
137066aee900SScott Liu };
137166aee900SScott Liu MODULE_DEVICE_TABLE(i2c, elants_i2c_id);
137266aee900SScott Liu 
137366aee900SScott Liu #ifdef CONFIG_ACPI
137466aee900SScott Liu static const struct acpi_device_id elants_acpi_id[] = {
137566aee900SScott Liu 	{ "ELAN0001", 0 },
137666aee900SScott Liu 	{ }
137766aee900SScott Liu };
137866aee900SScott Liu MODULE_DEVICE_TABLE(acpi, elants_acpi_id);
137966aee900SScott Liu #endif
138066aee900SScott Liu 
138166aee900SScott Liu #ifdef CONFIG_OF
138266aee900SScott Liu static const struct of_device_id elants_of_match[] = {
138366aee900SScott Liu 	{ .compatible = "elan,ekth3500" },
138466aee900SScott Liu 	{ /* sentinel */ }
138566aee900SScott Liu };
138666aee900SScott Liu MODULE_DEVICE_TABLE(of, elants_of_match);
138766aee900SScott Liu #endif
138866aee900SScott Liu 
138966aee900SScott Liu static struct i2c_driver elants_i2c_driver = {
139066aee900SScott Liu 	.probe = elants_i2c_probe,
139166aee900SScott Liu 	.id_table = elants_i2c_id,
139266aee900SScott Liu 	.driver = {
139366aee900SScott Liu 		.name = DEVICE_NAME,
139466aee900SScott Liu 		.pm = &elants_i2c_pm_ops,
139566aee900SScott Liu 		.acpi_match_table = ACPI_PTR(elants_acpi_id),
139666aee900SScott Liu 		.of_match_table = of_match_ptr(elants_of_match),
13979f6a07b6SDmitry Torokhov 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
139866aee900SScott Liu 	},
139966aee900SScott Liu };
140066aee900SScott Liu module_i2c_driver(elants_i2c_driver);
140166aee900SScott Liu 
140266aee900SScott Liu MODULE_AUTHOR("Scott Liu <scott.liu@emc.com.tw>");
140366aee900SScott Liu MODULE_DESCRIPTION("Elan I2c Touchscreen driver");
140466aee900SScott Liu MODULE_LICENSE("GPL");
1405