126822652SMichael Srba // SPDX-License-Identifier: GPL-2.0-only
226822652SMichael Srba 
326822652SMichael Srba #include <linux/delay.h>
426822652SMichael Srba #include <linux/i2c.h>
526822652SMichael Srba #include <linux/input.h>
626822652SMichael Srba #include <linux/input/mt.h>
726822652SMichael Srba #include <linux/input/touchscreen.h>
826822652SMichael Srba #include <linux/interrupt.h>
926822652SMichael Srba #include <linux/irq.h>
1026822652SMichael Srba #include <linux/kernel.h>
1126822652SMichael Srba #include <linux/module.h>
1226822652SMichael Srba #include <linux/of.h>
13*075d9b22SNikita Travkin #include <linux/property.h>
1426822652SMichael Srba #include <linux/regulator/consumer.h>
1526822652SMichael Srba #include <linux/slab.h>
1626822652SMichael Srba 
1726822652SMichael Srba /* Register Map */
1826822652SMichael Srba 
19077fdc9bSLinus Walleij #define ZINITIX_SWRESET_CMD			0x0000
20077fdc9bSLinus Walleij #define ZINITIX_WAKEUP_CMD			0x0001
2126822652SMichael Srba 
22077fdc9bSLinus Walleij #define ZINITIX_IDLE_CMD			0x0004
23077fdc9bSLinus Walleij #define ZINITIX_SLEEP_CMD			0x0005
2426822652SMichael Srba 
25077fdc9bSLinus Walleij #define ZINITIX_CLEAR_INT_STATUS_CMD		0x0003
26077fdc9bSLinus Walleij #define ZINITIX_CALIBRATE_CMD			0x0006
27077fdc9bSLinus Walleij #define ZINITIX_SAVE_STATUS_CMD			0x0007
28077fdc9bSLinus Walleij #define ZINITIX_SAVE_CALIBRATION_CMD		0x0008
29077fdc9bSLinus Walleij #define ZINITIX_RECALL_FACTORY_CMD		0x000f
3026822652SMichael Srba 
31077fdc9bSLinus Walleij #define ZINITIX_THRESHOLD			0x0020
3226822652SMichael Srba 
33077fdc9bSLinus Walleij #define ZINITIX_LARGE_PALM_REJECT_AREA_TH	0x003F
3426822652SMichael Srba 
35077fdc9bSLinus Walleij #define ZINITIX_DEBUG_REG			0x0115 /* 0~7 */
3626822652SMichael Srba 
37077fdc9bSLinus Walleij #define ZINITIX_TOUCH_MODE			0x0010
38077fdc9bSLinus Walleij #define ZINITIX_CHIP_REVISION			0x0011
39077fdc9bSLinus Walleij #define ZINITIX_FIRMWARE_VERSION		0x0012
4026822652SMichael Srba 
4126822652SMichael Srba #define ZINITIX_USB_DETECT			0x116
4226822652SMichael Srba 
43077fdc9bSLinus Walleij #define ZINITIX_MINOR_FW_VERSION		0x0121
4426822652SMichael Srba 
45077fdc9bSLinus Walleij #define ZINITIX_VENDOR_ID			0x001C
46077fdc9bSLinus Walleij #define ZINITIX_HW_ID				0x0014
4726822652SMichael Srba 
48077fdc9bSLinus Walleij #define ZINITIX_DATA_VERSION_REG		0x0013
49077fdc9bSLinus Walleij #define ZINITIX_SUPPORTED_FINGER_NUM		0x0015
50077fdc9bSLinus Walleij #define ZINITIX_EEPROM_INFO			0x0018
51077fdc9bSLinus Walleij #define ZINITIX_INITIAL_TOUCH_MODE		0x0019
5226822652SMichael Srba 
53077fdc9bSLinus Walleij #define ZINITIX_TOTAL_NUMBER_OF_X		0x0060
54077fdc9bSLinus Walleij #define ZINITIX_TOTAL_NUMBER_OF_Y		0x0061
5526822652SMichael Srba 
56077fdc9bSLinus Walleij #define ZINITIX_DELAY_RAW_FOR_HOST		0x007f
5726822652SMichael Srba 
58077fdc9bSLinus Walleij #define ZINITIX_BUTTON_SUPPORTED_NUM		0x00B0
59077fdc9bSLinus Walleij #define ZINITIX_BUTTON_SENSITIVITY		0x00B2
60077fdc9bSLinus Walleij #define ZINITIX_DUMMY_BUTTON_SENSITIVITY	0X00C8
6126822652SMichael Srba 
62077fdc9bSLinus Walleij #define ZINITIX_X_RESOLUTION			0x00C0
63077fdc9bSLinus Walleij #define ZINITIX_Y_RESOLUTION			0x00C1
6426822652SMichael Srba 
65077fdc9bSLinus Walleij #define ZINITIX_POINT_STATUS_REG		0x0080
66077fdc9bSLinus Walleij #define ZINITIX_ICON_STATUS_REG			0x00AA
6726822652SMichael Srba 
68077fdc9bSLinus Walleij #define ZINITIX_POINT_COORD_REG			(ZINITIX_POINT_STATUS_REG + 2)
6926822652SMichael Srba 
70077fdc9bSLinus Walleij #define ZINITIX_AFE_FREQUENCY			0x0100
71077fdc9bSLinus Walleij #define ZINITIX_DND_N_COUNT			0x0122
72077fdc9bSLinus Walleij #define ZINITIX_DND_U_COUNT			0x0135
7326822652SMichael Srba 
74077fdc9bSLinus Walleij #define ZINITIX_RAWDATA_REG			0x0200
7526822652SMichael Srba 
76077fdc9bSLinus Walleij #define ZINITIX_EEPROM_INFO_REG			0x0018
7726822652SMichael Srba 
78077fdc9bSLinus Walleij #define ZINITIX_INT_ENABLE_FLAG			0x00f0
79077fdc9bSLinus Walleij #define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL	0x00f1
8026822652SMichael Srba 
81077fdc9bSLinus Walleij #define ZINITIX_BTN_WIDTH			0x016d
8226822652SMichael Srba 
83077fdc9bSLinus Walleij #define ZINITIX_CHECKSUM_RESULT			0x012c
8426822652SMichael Srba 
85077fdc9bSLinus Walleij #define ZINITIX_INIT_FLASH			0x01d0
86077fdc9bSLinus Walleij #define ZINITIX_WRITE_FLASH			0x01d1
87077fdc9bSLinus Walleij #define ZINITIX_READ_FLASH			0x01d2
8826822652SMichael Srba 
8926822652SMichael Srba #define ZINITIX_INTERNAL_FLAG_02		0x011e
9026822652SMichael Srba #define ZINITIX_INTERNAL_FLAG_03		0x011f
9126822652SMichael Srba 
9226822652SMichael Srba #define ZINITIX_I2C_CHECKSUM_WCNT		0x016a
9326822652SMichael Srba #define ZINITIX_I2C_CHECKSUM_RESULT		0x016c
9426822652SMichael Srba 
9526822652SMichael Srba /* Interrupt & status register flags */
9626822652SMichael Srba 
9726822652SMichael Srba #define BIT_PT_CNT_CHANGE			BIT(0)
9826822652SMichael Srba #define BIT_DOWN				BIT(1)
9926822652SMichael Srba #define BIT_MOVE				BIT(2)
10026822652SMichael Srba #define BIT_UP					BIT(3)
10126822652SMichael Srba #define BIT_PALM				BIT(4)
10226822652SMichael Srba #define BIT_PALM_REJECT				BIT(5)
10326822652SMichael Srba #define BIT_RESERVED_0				BIT(6)
10426822652SMichael Srba #define BIT_RESERVED_1				BIT(7)
10526822652SMichael Srba #define BIT_WEIGHT_CHANGE			BIT(8)
10626822652SMichael Srba #define BIT_PT_NO_CHANGE			BIT(9)
10726822652SMichael Srba #define BIT_REJECT				BIT(10)
10826822652SMichael Srba #define BIT_PT_EXIST				BIT(11)
10926822652SMichael Srba #define BIT_RESERVED_2				BIT(12)
11026822652SMichael Srba #define BIT_ERROR				BIT(13)
11126822652SMichael Srba #define BIT_DEBUG				BIT(14)
11226822652SMichael Srba #define BIT_ICON_EVENT				BIT(15)
11326822652SMichael Srba 
11426822652SMichael Srba #define SUB_BIT_EXIST				BIT(0)
11526822652SMichael Srba #define SUB_BIT_DOWN				BIT(1)
11626822652SMichael Srba #define SUB_BIT_MOVE				BIT(2)
11726822652SMichael Srba #define SUB_BIT_UP				BIT(3)
11826822652SMichael Srba #define SUB_BIT_UPDATE				BIT(4)
11926822652SMichael Srba #define SUB_BIT_WAIT				BIT(5)
12026822652SMichael Srba 
12126822652SMichael Srba #define DEFAULT_TOUCH_POINT_MODE		2
12226822652SMichael Srba #define MAX_SUPPORTED_FINGER_NUM		5
123*075d9b22SNikita Travkin #define MAX_SUPPORTED_BUTTON_NUM		8
12426822652SMichael Srba 
12526822652SMichael Srba #define CHIP_ON_DELAY				15 // ms
12626822652SMichael Srba #define FIRMWARE_ON_DELAY			40 // ms
12726822652SMichael Srba 
12826822652SMichael Srba struct point_coord {
12926822652SMichael Srba 	__le16	x;
13026822652SMichael Srba 	__le16	y;
13126822652SMichael Srba 	u8	width;
13226822652SMichael Srba 	u8	sub_status;
13326822652SMichael Srba 	// currently unused, but needed as padding:
13426822652SMichael Srba 	u8	minor_width;
13526822652SMichael Srba 	u8	angle;
13626822652SMichael Srba };
13726822652SMichael Srba 
13826822652SMichael Srba struct touch_event {
13926822652SMichael Srba 	__le16	status;
140e941dc13SLinus Walleij 	u8	finger_mask;
14126822652SMichael Srba 	u8	time_stamp;
14226822652SMichael Srba 	struct point_coord point_coord[MAX_SUPPORTED_FINGER_NUM];
14326822652SMichael Srba };
14426822652SMichael Srba 
14526822652SMichael Srba struct bt541_ts_data {
14626822652SMichael Srba 	struct i2c_client *client;
14726822652SMichael Srba 	struct input_dev *input_dev;
14826822652SMichael Srba 	struct touchscreen_properties prop;
14926822652SMichael Srba 	struct regulator_bulk_data supplies[2];
15026822652SMichael Srba 	u32 zinitix_mode;
151*075d9b22SNikita Travkin 	u32 keycodes[MAX_SUPPORTED_BUTTON_NUM];
152*075d9b22SNikita Travkin 	int num_keycodes;
15326822652SMichael Srba };
15426822652SMichael Srba 
15526822652SMichael Srba static int zinitix_read_data(struct i2c_client *client,
15626822652SMichael Srba 			     u16 reg, void *values, size_t length)
15726822652SMichael Srba {
15826822652SMichael Srba 	__le16 reg_le = cpu_to_le16(reg);
15926822652SMichael Srba 	int ret;
16026822652SMichael Srba 
16126822652SMichael Srba 	/* A single i2c_transfer() transaction does not work here. */
16226822652SMichael Srba 	ret = i2c_master_send(client, (u8 *)&reg_le, sizeof(reg_le));
16326822652SMichael Srba 	if (ret != sizeof(reg_le))
16426822652SMichael Srba 		return ret < 0 ? ret : -EIO;
16526822652SMichael Srba 
16626822652SMichael Srba 	ret = i2c_master_recv(client, (u8 *)values, length);
16726822652SMichael Srba 	if (ret != length)
168a374c19fSYang Li 		return ret < 0 ? ret : -EIO;
16926822652SMichael Srba 
17026822652SMichael Srba 	return 0;
17126822652SMichael Srba }
17226822652SMichael Srba 
17326822652SMichael Srba static int zinitix_write_u16(struct i2c_client *client, u16 reg, u16 value)
17426822652SMichael Srba {
17526822652SMichael Srba 	__le16 packet[2] = {cpu_to_le16(reg), cpu_to_le16(value)};
17626822652SMichael Srba 	int ret;
17726822652SMichael Srba 
17826822652SMichael Srba 	ret = i2c_master_send(client, (u8 *)packet, sizeof(packet));
17926822652SMichael Srba 	if (ret != sizeof(packet))
18026822652SMichael Srba 		return ret < 0 ? ret : -EIO;
18126822652SMichael Srba 
18226822652SMichael Srba 	return 0;
18326822652SMichael Srba }
18426822652SMichael Srba 
18526822652SMichael Srba static int zinitix_write_cmd(struct i2c_client *client, u16 reg)
18626822652SMichael Srba {
18726822652SMichael Srba 	__le16 reg_le = cpu_to_le16(reg);
18826822652SMichael Srba 	int ret;
18926822652SMichael Srba 
19026822652SMichael Srba 	ret = i2c_master_send(client, (u8 *)&reg_le, sizeof(reg_le));
19126822652SMichael Srba 	if (ret != sizeof(reg_le))
19226822652SMichael Srba 		return ret < 0 ? ret : -EIO;
19326822652SMichael Srba 
19426822652SMichael Srba 	return 0;
19526822652SMichael Srba }
19626822652SMichael Srba 
197836f308cSDmitry Torokhov static int zinitix_init_touch(struct bt541_ts_data *bt541)
19826822652SMichael Srba {
19926822652SMichael Srba 	struct i2c_client *client = bt541->client;
20026822652SMichael Srba 	int i;
20126822652SMichael Srba 	int error;
202*075d9b22SNikita Travkin 	u16 int_flags;
20326822652SMichael Srba 
204077fdc9bSLinus Walleij 	error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
20526822652SMichael Srba 	if (error) {
20626822652SMichael Srba 		dev_err(&client->dev, "Failed to write reset command\n");
20726822652SMichael Srba 		return error;
20826822652SMichael Srba 	}
20926822652SMichael Srba 
210077fdc9bSLinus Walleij 	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
21126822652SMichael Srba 	if (error) {
21226822652SMichael Srba 		dev_err(&client->dev,
21326822652SMichael Srba 			"Failed to reset interrupt enable flag\n");
21426822652SMichael Srba 		return error;
21526822652SMichael Srba 	}
21626822652SMichael Srba 
21726822652SMichael Srba 	/* initialize */
218077fdc9bSLinus Walleij 	error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,
21926822652SMichael Srba 				  bt541->prop.max_x);
22026822652SMichael Srba 	if (error)
22126822652SMichael Srba 		return error;
22226822652SMichael Srba 
223077fdc9bSLinus Walleij 	error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,
22426822652SMichael Srba 				  bt541->prop.max_y);
22526822652SMichael Srba 	if (error)
22626822652SMichael Srba 		return error;
22726822652SMichael Srba 
228077fdc9bSLinus Walleij 	error = zinitix_write_u16(client, ZINITIX_SUPPORTED_FINGER_NUM,
22926822652SMichael Srba 				  MAX_SUPPORTED_FINGER_NUM);
23026822652SMichael Srba 	if (error)
23126822652SMichael Srba 		return error;
23226822652SMichael Srba 
233*075d9b22SNikita Travkin 	error = zinitix_write_u16(client, ZINITIX_BUTTON_SUPPORTED_NUM,
234*075d9b22SNikita Travkin 				  bt541->num_keycodes);
235*075d9b22SNikita Travkin 	if (error)
236*075d9b22SNikita Travkin 		return error;
237*075d9b22SNikita Travkin 
238077fdc9bSLinus Walleij 	error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,
23926822652SMichael Srba 				  bt541->zinitix_mode);
24026822652SMichael Srba 	if (error)
24126822652SMichael Srba 		return error;
24226822652SMichael Srba 
243077fdc9bSLinus Walleij 	error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
24426822652SMichael Srba 				  bt541->zinitix_mode);
24526822652SMichael Srba 	if (error)
24626822652SMichael Srba 		return error;
24726822652SMichael Srba 
248*075d9b22SNikita Travkin 	int_flags = BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE | BIT_UP;
249*075d9b22SNikita Travkin 	if (bt541->num_keycodes)
250*075d9b22SNikita Travkin 		int_flags |= BIT_ICON_EVENT;
251*075d9b22SNikita Travkin 
252*075d9b22SNikita Travkin 	error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, int_flags);
25326822652SMichael Srba 	if (error)
25426822652SMichael Srba 		return error;
25526822652SMichael Srba 
25626822652SMichael Srba 	/* clear queue */
25726822652SMichael Srba 	for (i = 0; i < 10; i++) {
258077fdc9bSLinus Walleij 		zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);
25926822652SMichael Srba 		udelay(10);
26026822652SMichael Srba 	}
26126822652SMichael Srba 
26226822652SMichael Srba 	return 0;
26326822652SMichael Srba }
26426822652SMichael Srba 
26526822652SMichael Srba static int zinitix_init_regulators(struct bt541_ts_data *bt541)
26626822652SMichael Srba {
267c54be0e3SLinus Walleij 	struct device *dev = &bt541->client->dev;
26826822652SMichael Srba 	int error;
26926822652SMichael Srba 
270c54be0e3SLinus Walleij 	/*
271c54be0e3SLinus Walleij 	 * Some older device trees have erroneous names for the regulators,
272c54be0e3SLinus Walleij 	 * so check if "vddo" is present and in that case use these names.
273c54be0e3SLinus Walleij 	 * Else use the proper supply names on the component.
274c54be0e3SLinus Walleij 	 */
275eaedf192SRob Herring 	if (of_property_present(dev->of_node, "vddo-supply")) {
27626822652SMichael Srba 		bt541->supplies[0].supply = "vdd";
27726822652SMichael Srba 		bt541->supplies[1].supply = "vddo";
278c54be0e3SLinus Walleij 	} else {
279c54be0e3SLinus Walleij 		/* Else use the proper supply names */
280c54be0e3SLinus Walleij 		bt541->supplies[0].supply = "vcca";
281c54be0e3SLinus Walleij 		bt541->supplies[1].supply = "vdd";
282c54be0e3SLinus Walleij 	}
283c54be0e3SLinus Walleij 	error = devm_regulator_bulk_get(dev,
28426822652SMichael Srba 					ARRAY_SIZE(bt541->supplies),
28526822652SMichael Srba 					bt541->supplies);
28626822652SMichael Srba 	if (error < 0) {
287c54be0e3SLinus Walleij 		dev_err(dev, "Failed to get regulators: %d\n", error);
28826822652SMichael Srba 		return error;
28926822652SMichael Srba 	}
29026822652SMichael Srba 
29126822652SMichael Srba 	return 0;
29226822652SMichael Srba }
29326822652SMichael Srba 
29426822652SMichael Srba static int zinitix_send_power_on_sequence(struct bt541_ts_data *bt541)
29526822652SMichael Srba {
29626822652SMichael Srba 	int error;
29726822652SMichael Srba 	struct i2c_client *client = bt541->client;
29826822652SMichael Srba 
29926822652SMichael Srba 	error = zinitix_write_u16(client, 0xc000, 0x0001);
30026822652SMichael Srba 	if (error) {
30126822652SMichael Srba 		dev_err(&client->dev,
30226822652SMichael Srba 			"Failed to send power sequence(vendor cmd enable)\n");
30326822652SMichael Srba 		return error;
30426822652SMichael Srba 	}
30526822652SMichael Srba 	udelay(10);
30626822652SMichael Srba 
30726822652SMichael Srba 	error = zinitix_write_cmd(client, 0xc004);
30826822652SMichael Srba 	if (error) {
30926822652SMichael Srba 		dev_err(&client->dev,
31026822652SMichael Srba 			"Failed to send power sequence (intn clear)\n");
31126822652SMichael Srba 		return error;
31226822652SMichael Srba 	}
31326822652SMichael Srba 	udelay(10);
31426822652SMichael Srba 
31526822652SMichael Srba 	error = zinitix_write_u16(client, 0xc002, 0x0001);
31626822652SMichael Srba 	if (error) {
31726822652SMichael Srba 		dev_err(&client->dev,
31826822652SMichael Srba 			"Failed to send power sequence (nvm init)\n");
31926822652SMichael Srba 		return error;
32026822652SMichael Srba 	}
32126822652SMichael Srba 	mdelay(2);
32226822652SMichael Srba 
32326822652SMichael Srba 	error = zinitix_write_u16(client, 0xc001, 0x0001);
32426822652SMichael Srba 	if (error) {
32526822652SMichael Srba 		dev_err(&client->dev,
32626822652SMichael Srba 			"Failed to send power sequence (program start)\n");
32726822652SMichael Srba 		return error;
32826822652SMichael Srba 	}
32926822652SMichael Srba 	msleep(FIRMWARE_ON_DELAY);
33026822652SMichael Srba 
33126822652SMichael Srba 	return 0;
33226822652SMichael Srba }
33326822652SMichael Srba 
33426822652SMichael Srba static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot,
33526822652SMichael Srba 				  const struct point_coord *p)
33626822652SMichael Srba {
337e941dc13SLinus Walleij 	u16 x, y;
338e941dc13SLinus Walleij 
339e941dc13SLinus Walleij 	if (unlikely(!(p->sub_status &
340e941dc13SLinus Walleij 		       (SUB_BIT_UP | SUB_BIT_DOWN | SUB_BIT_MOVE)))) {
341e941dc13SLinus Walleij 		dev_dbg(&bt541->client->dev, "unknown finger event %#02x\n",
342e941dc13SLinus Walleij 			p->sub_status);
343e941dc13SLinus Walleij 		return;
344e941dc13SLinus Walleij 	}
345e941dc13SLinus Walleij 
346e941dc13SLinus Walleij 	x = le16_to_cpu(p->x);
347e941dc13SLinus Walleij 	y = le16_to_cpu(p->y);
348e941dc13SLinus Walleij 
34926822652SMichael Srba 	input_mt_slot(bt541->input_dev, slot);
350e941dc13SLinus Walleij 	if (input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER,
351e941dc13SLinus Walleij 				       !(p->sub_status & SUB_BIT_UP))) {
352e941dc13SLinus Walleij 		touchscreen_report_pos(bt541->input_dev,
353e941dc13SLinus Walleij 				       &bt541->prop, x, y, true);
354e941dc13SLinus Walleij 		input_report_abs(bt541->input_dev,
355e941dc13SLinus Walleij 				 ABS_MT_TOUCH_MAJOR, p->width);
356e941dc13SLinus Walleij 		dev_dbg(&bt541->client->dev, "finger %d %s (%u, %u)\n",
357e941dc13SLinus Walleij 			slot, p->sub_status & SUB_BIT_DOWN ? "down" : "move",
358e941dc13SLinus Walleij 			x, y);
359e941dc13SLinus Walleij 	} else {
360e941dc13SLinus Walleij 		dev_dbg(&bt541->client->dev, "finger %d up (%u, %u)\n",
361e941dc13SLinus Walleij 			slot, x, y);
362e941dc13SLinus Walleij 	}
36326822652SMichael Srba }
36426822652SMichael Srba 
365*075d9b22SNikita Travkin static void zinitix_report_keys(struct bt541_ts_data *bt541, u16 icon_events)
366*075d9b22SNikita Travkin {
367*075d9b22SNikita Travkin 	int i;
368*075d9b22SNikita Travkin 
369*075d9b22SNikita Travkin 	for (i = 0; i < bt541->num_keycodes; i++)
370*075d9b22SNikita Travkin 		input_report_key(bt541->input_dev,
371*075d9b22SNikita Travkin 				 bt541->keycodes[i], icon_events & BIT(i));
372*075d9b22SNikita Travkin }
373*075d9b22SNikita Travkin 
37426822652SMichael Srba static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
37526822652SMichael Srba {
37626822652SMichael Srba 	struct bt541_ts_data *bt541 = bt541_handler;
37726822652SMichael Srba 	struct i2c_client *client = bt541->client;
37826822652SMichael Srba 	struct touch_event touch_event;
379e941dc13SLinus Walleij 	unsigned long finger_mask;
380*075d9b22SNikita Travkin 	__le16 icon_events;
38126822652SMichael Srba 	int error;
38226822652SMichael Srba 	int i;
38326822652SMichael Srba 
38426822652SMichael Srba 	memset(&touch_event, 0, sizeof(struct touch_event));
38526822652SMichael Srba 
386077fdc9bSLinus Walleij 	error = zinitix_read_data(bt541->client, ZINITIX_POINT_STATUS_REG,
38726822652SMichael Srba 				  &touch_event, sizeof(struct touch_event));
38826822652SMichael Srba 	if (error) {
38926822652SMichael Srba 		dev_err(&client->dev, "Failed to read in touchpoint struct\n");
39026822652SMichael Srba 		goto out;
39126822652SMichael Srba 	}
39226822652SMichael Srba 
393*075d9b22SNikita Travkin 	if (le16_to_cpu(touch_event.status) & BIT_ICON_EVENT) {
394*075d9b22SNikita Travkin 		error = zinitix_read_data(bt541->client, ZINITIX_ICON_STATUS_REG,
395*075d9b22SNikita Travkin 					  &icon_events, sizeof(icon_events));
396*075d9b22SNikita Travkin 		if (error) {
397*075d9b22SNikita Travkin 			dev_err(&client->dev, "Failed to read icon events\n");
398*075d9b22SNikita Travkin 			goto out;
399*075d9b22SNikita Travkin 		}
400*075d9b22SNikita Travkin 
401*075d9b22SNikita Travkin 		zinitix_report_keys(bt541, le16_to_cpu(icon_events));
402*075d9b22SNikita Travkin 	}
403*075d9b22SNikita Travkin 
404e941dc13SLinus Walleij 	finger_mask = touch_event.finger_mask;
405e941dc13SLinus Walleij 	for_each_set_bit(i, &finger_mask, MAX_SUPPORTED_FINGER_NUM) {
406e941dc13SLinus Walleij 		const struct point_coord *p = &touch_event.point_coord[i];
407e941dc13SLinus Walleij 
408e941dc13SLinus Walleij 		/* Only process contacts that are actually reported */
409e941dc13SLinus Walleij 		if (p->sub_status & SUB_BIT_EXIST)
410e941dc13SLinus Walleij 			zinitix_report_finger(bt541, i, p);
411e941dc13SLinus Walleij 	}
41226822652SMichael Srba 
41326822652SMichael Srba 	input_mt_sync_frame(bt541->input_dev);
41426822652SMichael Srba 	input_sync(bt541->input_dev);
41526822652SMichael Srba 
41626822652SMichael Srba out:
417077fdc9bSLinus Walleij 	zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);
41826822652SMichael Srba 	return IRQ_HANDLED;
41926822652SMichael Srba }
42026822652SMichael Srba 
42126822652SMichael Srba static int zinitix_start(struct bt541_ts_data *bt541)
42226822652SMichael Srba {
42326822652SMichael Srba 	int error;
42426822652SMichael Srba 
42526822652SMichael Srba 	error = regulator_bulk_enable(ARRAY_SIZE(bt541->supplies),
42626822652SMichael Srba 				      bt541->supplies);
42726822652SMichael Srba 	if (error) {
42826822652SMichael Srba 		dev_err(&bt541->client->dev,
42926822652SMichael Srba 			"Failed to enable regulators: %d\n", error);
43026822652SMichael Srba 		return error;
43126822652SMichael Srba 	}
43226822652SMichael Srba 
43326822652SMichael Srba 	msleep(CHIP_ON_DELAY);
43426822652SMichael Srba 
43526822652SMichael Srba 	error = zinitix_send_power_on_sequence(bt541);
43626822652SMichael Srba 	if (error) {
43726822652SMichael Srba 		dev_err(&bt541->client->dev,
43826822652SMichael Srba 			"Error while sending power-on sequence: %d\n", error);
43926822652SMichael Srba 		return error;
44026822652SMichael Srba 	}
44126822652SMichael Srba 
44226822652SMichael Srba 	error = zinitix_init_touch(bt541);
44326822652SMichael Srba 	if (error) {
44426822652SMichael Srba 		dev_err(&bt541->client->dev,
44526822652SMichael Srba 			"Error while configuring touch IC\n");
44626822652SMichael Srba 		return error;
44726822652SMichael Srba 	}
44826822652SMichael Srba 
44926822652SMichael Srba 	enable_irq(bt541->client->irq);
45026822652SMichael Srba 
45126822652SMichael Srba 	return 0;
45226822652SMichael Srba }
45326822652SMichael Srba 
45426822652SMichael Srba static int zinitix_stop(struct bt541_ts_data *bt541)
45526822652SMichael Srba {
45626822652SMichael Srba 	int error;
45726822652SMichael Srba 
45826822652SMichael Srba 	disable_irq(bt541->client->irq);
45926822652SMichael Srba 
46026822652SMichael Srba 	error = regulator_bulk_disable(ARRAY_SIZE(bt541->supplies),
46126822652SMichael Srba 				       bt541->supplies);
46226822652SMichael Srba 	if (error) {
46326822652SMichael Srba 		dev_err(&bt541->client->dev,
46426822652SMichael Srba 			"Failed to disable regulators: %d\n", error);
46526822652SMichael Srba 		return error;
46626822652SMichael Srba 	}
46726822652SMichael Srba 
46826822652SMichael Srba 	return 0;
46926822652SMichael Srba }
47026822652SMichael Srba 
47126822652SMichael Srba static int zinitix_input_open(struct input_dev *dev)
47226822652SMichael Srba {
47326822652SMichael Srba 	struct bt541_ts_data *bt541 = input_get_drvdata(dev);
47426822652SMichael Srba 
47526822652SMichael Srba 	return zinitix_start(bt541);
47626822652SMichael Srba }
47726822652SMichael Srba 
47826822652SMichael Srba static void zinitix_input_close(struct input_dev *dev)
47926822652SMichael Srba {
48026822652SMichael Srba 	struct bt541_ts_data *bt541 = input_get_drvdata(dev);
48126822652SMichael Srba 
48226822652SMichael Srba 	zinitix_stop(bt541);
48326822652SMichael Srba }
48426822652SMichael Srba 
48526822652SMichael Srba static int zinitix_init_input_dev(struct bt541_ts_data *bt541)
48626822652SMichael Srba {
48726822652SMichael Srba 	struct input_dev *input_dev;
48826822652SMichael Srba 	int error;
489*075d9b22SNikita Travkin 	int i;
49026822652SMichael Srba 
49126822652SMichael Srba 	input_dev = devm_input_allocate_device(&bt541->client->dev);
49226822652SMichael Srba 	if (!input_dev) {
49326822652SMichael Srba 		dev_err(&bt541->client->dev,
49426822652SMichael Srba 			"Failed to allocate input device.");
49526822652SMichael Srba 		return -ENOMEM;
49626822652SMichael Srba 	}
49726822652SMichael Srba 
49826822652SMichael Srba 	input_set_drvdata(input_dev, bt541);
49926822652SMichael Srba 	bt541->input_dev = input_dev;
50026822652SMichael Srba 
50126822652SMichael Srba 	input_dev->name = "Zinitix Capacitive TouchScreen";
50226822652SMichael Srba 	input_dev->phys = "input/ts";
50326822652SMichael Srba 	input_dev->id.bustype = BUS_I2C;
50426822652SMichael Srba 	input_dev->open = zinitix_input_open;
50526822652SMichael Srba 	input_dev->close = zinitix_input_close;
50626822652SMichael Srba 
507*075d9b22SNikita Travkin 	if (bt541->num_keycodes) {
508*075d9b22SNikita Travkin 		input_dev->keycode = bt541->keycodes;
509*075d9b22SNikita Travkin 		input_dev->keycodemax = bt541->num_keycodes;
510*075d9b22SNikita Travkin 		input_dev->keycodesize = sizeof(bt541->keycodes[0]);
511*075d9b22SNikita Travkin 		for (i = 0; i < bt541->num_keycodes; i++)
512*075d9b22SNikita Travkin 			input_set_capability(input_dev, EV_KEY, bt541->keycodes[i]);
513*075d9b22SNikita Travkin 	}
514*075d9b22SNikita Travkin 
51526822652SMichael Srba 	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
51626822652SMichael Srba 	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
51726822652SMichael Srba 	input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
51826822652SMichael Srba 	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
51926822652SMichael Srba 
52026822652SMichael Srba 	touchscreen_parse_properties(input_dev, true, &bt541->prop);
52126822652SMichael Srba 	if (!bt541->prop.max_x || !bt541->prop.max_y) {
52226822652SMichael Srba 		dev_err(&bt541->client->dev,
52326822652SMichael Srba 			"Touchscreen-size-x and/or touchscreen-size-y not set in dts\n");
52426822652SMichael Srba 		return -EINVAL;
52526822652SMichael Srba 	}
52626822652SMichael Srba 
52726822652SMichael Srba 	error = input_mt_init_slots(input_dev, MAX_SUPPORTED_FINGER_NUM,
52826822652SMichael Srba 				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
52926822652SMichael Srba 	if (error) {
53026822652SMichael Srba 		dev_err(&bt541->client->dev,
53126822652SMichael Srba 			"Failed to initialize MT slots: %d", error);
53226822652SMichael Srba 		return error;
53326822652SMichael Srba 	}
53426822652SMichael Srba 
53526822652SMichael Srba 	error = input_register_device(input_dev);
53626822652SMichael Srba 	if (error) {
53726822652SMichael Srba 		dev_err(&bt541->client->dev,
53826822652SMichael Srba 			"Failed to register input device: %d", error);
53926822652SMichael Srba 		return error;
54026822652SMichael Srba 	}
54126822652SMichael Srba 
54226822652SMichael Srba 	return 0;
54326822652SMichael Srba }
54426822652SMichael Srba 
54526822652SMichael Srba static int zinitix_ts_probe(struct i2c_client *client)
54626822652SMichael Srba {
54726822652SMichael Srba 	struct bt541_ts_data *bt541;
54826822652SMichael Srba 	int error;
54926822652SMichael Srba 
55026822652SMichael Srba 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
55126822652SMichael Srba 		dev_err(&client->dev,
55226822652SMichael Srba 			"Failed to assert adapter's support for plain I2C.\n");
55326822652SMichael Srba 		return -ENXIO;
55426822652SMichael Srba 	}
55526822652SMichael Srba 
55626822652SMichael Srba 	bt541 = devm_kzalloc(&client->dev, sizeof(*bt541), GFP_KERNEL);
55726822652SMichael Srba 	if (!bt541)
55826822652SMichael Srba 		return -ENOMEM;
55926822652SMichael Srba 
56026822652SMichael Srba 	bt541->client = client;
56126822652SMichael Srba 	i2c_set_clientdata(client, bt541);
56226822652SMichael Srba 
56326822652SMichael Srba 	error = zinitix_init_regulators(bt541);
56426822652SMichael Srba 	if (error) {
56526822652SMichael Srba 		dev_err(&client->dev,
56626822652SMichael Srba 			"Failed to initialize regulators: %d\n", error);
56726822652SMichael Srba 		return error;
56826822652SMichael Srba 	}
56926822652SMichael Srba 
570cf73ed89SNikita Travkin 	error = devm_request_threaded_irq(&client->dev, client->irq,
571cf73ed89SNikita Travkin 					  NULL, zinitix_ts_irq_handler,
572cf73ed89SNikita Travkin 					  IRQF_ONESHOT | IRQF_NO_AUTOEN,
573cf73ed89SNikita Travkin 					  client->name, bt541);
574cf73ed89SNikita Travkin 	if (error) {
575cf73ed89SNikita Travkin 		dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
576cf73ed89SNikita Travkin 		return error;
577cf73ed89SNikita Travkin 	}
578cf73ed89SNikita Travkin 
579*075d9b22SNikita Travkin 	bt541->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes");
580*075d9b22SNikita Travkin 	if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) {
581*075d9b22SNikita Travkin 		dev_err(&client->dev, "too many keys defined (%d)\n", bt541->num_keycodes);
582*075d9b22SNikita Travkin 		return -EINVAL;
583*075d9b22SNikita Travkin 	}
584*075d9b22SNikita Travkin 
585*075d9b22SNikita Travkin 	error = device_property_read_u32_array(&client->dev, "linux,keycodes",
586*075d9b22SNikita Travkin 					       bt541->keycodes,
587*075d9b22SNikita Travkin 					       bt541->num_keycodes);
588*075d9b22SNikita Travkin 	if (error) {
589*075d9b22SNikita Travkin 		dev_err(&client->dev,
590*075d9b22SNikita Travkin 			"Unable to parse \"linux,keycodes\" property: %d\n", error);
591*075d9b22SNikita Travkin 		return error;
592*075d9b22SNikita Travkin 	}
593*075d9b22SNikita Travkin 
59426822652SMichael Srba 	error = zinitix_init_input_dev(bt541);
59526822652SMichael Srba 	if (error) {
59626822652SMichael Srba 		dev_err(&client->dev,
59726822652SMichael Srba 			"Failed to initialize input device: %d\n", error);
59826822652SMichael Srba 		return error;
59926822652SMichael Srba 	}
60026822652SMichael Srba 
60126822652SMichael Srba 	error = device_property_read_u32(&client->dev, "zinitix,mode",
60226822652SMichael Srba 					 &bt541->zinitix_mode);
60326822652SMichael Srba 	if (error < 0) {
60426822652SMichael Srba 		/* fall back to mode 2 */
60526822652SMichael Srba 		bt541->zinitix_mode = DEFAULT_TOUCH_POINT_MODE;
60626822652SMichael Srba 	}
60726822652SMichael Srba 
60826822652SMichael Srba 	if (bt541->zinitix_mode != 2) {
60926822652SMichael Srba 		/*
61026822652SMichael Srba 		 * If there are devices that don't support mode 2, support
61126822652SMichael Srba 		 * for other modes (0, 1) will be needed.
61226822652SMichael Srba 		 */
61326822652SMichael Srba 		dev_err(&client->dev,
61426822652SMichael Srba 			"Malformed zinitix,mode property, must be 2 (supplied: %d)\n",
61526822652SMichael Srba 			bt541->zinitix_mode);
61626822652SMichael Srba 		return -EINVAL;
61726822652SMichael Srba 	}
61826822652SMichael Srba 
61926822652SMichael Srba 	return 0;
62026822652SMichael Srba }
62126822652SMichael Srba 
62261df952bSJonathan Cameron static int zinitix_suspend(struct device *dev)
62326822652SMichael Srba {
62426822652SMichael Srba 	struct i2c_client *client = to_i2c_client(dev);
62526822652SMichael Srba 	struct bt541_ts_data *bt541 = i2c_get_clientdata(client);
62626822652SMichael Srba 
62726822652SMichael Srba 	mutex_lock(&bt541->input_dev->mutex);
62826822652SMichael Srba 
629d69f0a43SAndrzej Pietrasiewicz 	if (input_device_enabled(bt541->input_dev))
63026822652SMichael Srba 		zinitix_stop(bt541);
63126822652SMichael Srba 
63226822652SMichael Srba 	mutex_unlock(&bt541->input_dev->mutex);
63326822652SMichael Srba 
63426822652SMichael Srba 	return 0;
63526822652SMichael Srba }
63626822652SMichael Srba 
63761df952bSJonathan Cameron static int zinitix_resume(struct device *dev)
63826822652SMichael Srba {
63926822652SMichael Srba 	struct i2c_client *client = to_i2c_client(dev);
64026822652SMichael Srba 	struct bt541_ts_data *bt541 = i2c_get_clientdata(client);
64126822652SMichael Srba 	int ret = 0;
64226822652SMichael Srba 
64326822652SMichael Srba 	mutex_lock(&bt541->input_dev->mutex);
64426822652SMichael Srba 
645d69f0a43SAndrzej Pietrasiewicz 	if (input_device_enabled(bt541->input_dev))
64626822652SMichael Srba 		ret = zinitix_start(bt541);
64726822652SMichael Srba 
64826822652SMichael Srba 	mutex_unlock(&bt541->input_dev->mutex);
64926822652SMichael Srba 
65026822652SMichael Srba 	return ret;
65126822652SMichael Srba }
65226822652SMichael Srba 
65361df952bSJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(zinitix_pm_ops, zinitix_suspend, zinitix_resume);
65426822652SMichael Srba 
65526822652SMichael Srba #ifdef CONFIG_OF
65626822652SMichael Srba static const struct of_device_id zinitix_of_match[] = {
657de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt402" },
658de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt403" },
659de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt404" },
660de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt412" },
661de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt413" },
662de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt431" },
663de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt432" },
664de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt531" },
6659df136b5SNikita Travkin 	{ .compatible = "zinitix,bt532" },
666de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt538" },
66726822652SMichael Srba 	{ .compatible = "zinitix,bt541" },
668de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt548" },
669de8aa31aSLinus Walleij 	{ .compatible = "zinitix,bt554" },
670de8aa31aSLinus Walleij 	{ .compatible = "zinitix,at100" },
67126822652SMichael Srba 	{ }
67226822652SMichael Srba };
67326822652SMichael Srba MODULE_DEVICE_TABLE(of, zinitix_of_match);
67426822652SMichael Srba #endif
67526822652SMichael Srba 
67626822652SMichael Srba static struct i2c_driver zinitix_ts_driver = {
677d8bde56dSUwe Kleine-König 	.probe = zinitix_ts_probe,
67826822652SMichael Srba 	.driver = {
67926822652SMichael Srba 		.name = "Zinitix-TS",
68061df952bSJonathan Cameron 		.pm = pm_sleep_ptr(&zinitix_pm_ops),
68126822652SMichael Srba 		.of_match_table = of_match_ptr(zinitix_of_match),
68226822652SMichael Srba 	},
68326822652SMichael Srba };
68426822652SMichael Srba module_i2c_driver(zinitix_ts_driver);
68526822652SMichael Srba 
68626822652SMichael Srba MODULE_AUTHOR("Michael Srba <[email protected]>");
68726822652SMichael Srba MODULE_DESCRIPTION("Zinitix touchscreen driver");
68826822652SMichael Srba MODULE_LICENSE("GPL v2");
689