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>
13075d9b22SNikita 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
38dac97383SLinus Walleij
39077fdc9bSLinus Walleij #define ZINITIX_CHIP_REVISION 0x0011
40dac97383SLinus Walleij #define ZINITIX_CHIP_BTX0X_MASK 0xF0F0
41dac97383SLinus Walleij #define ZINITIX_CHIP_BT4X2 0x4020
42dac97383SLinus Walleij #define ZINITIX_CHIP_BT4X3 0x4030
43dac97383SLinus Walleij #define ZINITIX_CHIP_BT4X4 0x4040
44dac97383SLinus Walleij
45077fdc9bSLinus Walleij #define ZINITIX_FIRMWARE_VERSION 0x0012
4626822652SMichael Srba
4726822652SMichael Srba #define ZINITIX_USB_DETECT 0x116
4826822652SMichael Srba
49077fdc9bSLinus Walleij #define ZINITIX_MINOR_FW_VERSION 0x0121
5026822652SMichael Srba
51077fdc9bSLinus Walleij #define ZINITIX_VENDOR_ID 0x001C
52077fdc9bSLinus Walleij #define ZINITIX_HW_ID 0x0014
5326822652SMichael Srba
54077fdc9bSLinus Walleij #define ZINITIX_DATA_VERSION_REG 0x0013
55077fdc9bSLinus Walleij #define ZINITIX_SUPPORTED_FINGER_NUM 0x0015
56077fdc9bSLinus Walleij #define ZINITIX_EEPROM_INFO 0x0018
57077fdc9bSLinus Walleij #define ZINITIX_INITIAL_TOUCH_MODE 0x0019
5826822652SMichael Srba
59077fdc9bSLinus Walleij #define ZINITIX_TOTAL_NUMBER_OF_X 0x0060
60077fdc9bSLinus Walleij #define ZINITIX_TOTAL_NUMBER_OF_Y 0x0061
6126822652SMichael Srba
62077fdc9bSLinus Walleij #define ZINITIX_DELAY_RAW_FOR_HOST 0x007f
6326822652SMichael Srba
64077fdc9bSLinus Walleij #define ZINITIX_BUTTON_SUPPORTED_NUM 0x00B0
65077fdc9bSLinus Walleij #define ZINITIX_BUTTON_SENSITIVITY 0x00B2
66077fdc9bSLinus Walleij #define ZINITIX_DUMMY_BUTTON_SENSITIVITY 0X00C8
6726822652SMichael Srba
68077fdc9bSLinus Walleij #define ZINITIX_X_RESOLUTION 0x00C0
69077fdc9bSLinus Walleij #define ZINITIX_Y_RESOLUTION 0x00C1
7026822652SMichael Srba
71077fdc9bSLinus Walleij #define ZINITIX_POINT_STATUS_REG 0x0080
72dac97383SLinus Walleij
73dac97383SLinus Walleij #define ZINITIX_BT4X2_ICON_STATUS_REG 0x009A
74dac97383SLinus Walleij #define ZINITIX_BT4X3_ICON_STATUS_REG 0x00A0
75dac97383SLinus Walleij #define ZINITIX_BT4X4_ICON_STATUS_REG 0x00A0
76dac97383SLinus Walleij #define ZINITIX_BT5XX_ICON_STATUS_REG 0x00AA
7726822652SMichael Srba
78077fdc9bSLinus Walleij #define ZINITIX_POINT_COORD_REG (ZINITIX_POINT_STATUS_REG + 2)
7926822652SMichael Srba
80077fdc9bSLinus Walleij #define ZINITIX_AFE_FREQUENCY 0x0100
81077fdc9bSLinus Walleij #define ZINITIX_DND_N_COUNT 0x0122
82077fdc9bSLinus Walleij #define ZINITIX_DND_U_COUNT 0x0135
8326822652SMichael Srba
84077fdc9bSLinus Walleij #define ZINITIX_RAWDATA_REG 0x0200
8526822652SMichael Srba
86077fdc9bSLinus Walleij #define ZINITIX_EEPROM_INFO_REG 0x0018
8726822652SMichael Srba
88077fdc9bSLinus Walleij #define ZINITIX_INT_ENABLE_FLAG 0x00f0
89077fdc9bSLinus Walleij #define ZINITIX_PERIODICAL_INTERRUPT_INTERVAL 0x00f1
9026822652SMichael Srba
91077fdc9bSLinus Walleij #define ZINITIX_BTN_WIDTH 0x016d
9226822652SMichael Srba
93077fdc9bSLinus Walleij #define ZINITIX_CHECKSUM_RESULT 0x012c
9426822652SMichael Srba
95077fdc9bSLinus Walleij #define ZINITIX_INIT_FLASH 0x01d0
96077fdc9bSLinus Walleij #define ZINITIX_WRITE_FLASH 0x01d1
97077fdc9bSLinus Walleij #define ZINITIX_READ_FLASH 0x01d2
9826822652SMichael Srba
9926822652SMichael Srba #define ZINITIX_INTERNAL_FLAG_02 0x011e
10026822652SMichael Srba #define ZINITIX_INTERNAL_FLAG_03 0x011f
10126822652SMichael Srba
10226822652SMichael Srba #define ZINITIX_I2C_CHECKSUM_WCNT 0x016a
10326822652SMichael Srba #define ZINITIX_I2C_CHECKSUM_RESULT 0x016c
10426822652SMichael Srba
10526822652SMichael Srba /* Interrupt & status register flags */
10626822652SMichael Srba
10726822652SMichael Srba #define BIT_PT_CNT_CHANGE BIT(0)
10826822652SMichael Srba #define BIT_DOWN BIT(1)
10926822652SMichael Srba #define BIT_MOVE BIT(2)
11026822652SMichael Srba #define BIT_UP BIT(3)
11126822652SMichael Srba #define BIT_PALM BIT(4)
11226822652SMichael Srba #define BIT_PALM_REJECT BIT(5)
11326822652SMichael Srba #define BIT_RESERVED_0 BIT(6)
11426822652SMichael Srba #define BIT_RESERVED_1 BIT(7)
11526822652SMichael Srba #define BIT_WEIGHT_CHANGE BIT(8)
11626822652SMichael Srba #define BIT_PT_NO_CHANGE BIT(9)
11726822652SMichael Srba #define BIT_REJECT BIT(10)
11826822652SMichael Srba #define BIT_PT_EXIST BIT(11)
11926822652SMichael Srba #define BIT_RESERVED_2 BIT(12)
12026822652SMichael Srba #define BIT_ERROR BIT(13)
12126822652SMichael Srba #define BIT_DEBUG BIT(14)
12226822652SMichael Srba #define BIT_ICON_EVENT BIT(15)
12326822652SMichael Srba
12426822652SMichael Srba #define SUB_BIT_EXIST BIT(0)
12526822652SMichael Srba #define SUB_BIT_DOWN BIT(1)
12626822652SMichael Srba #define SUB_BIT_MOVE BIT(2)
12726822652SMichael Srba #define SUB_BIT_UP BIT(3)
12826822652SMichael Srba #define SUB_BIT_UPDATE BIT(4)
12926822652SMichael Srba #define SUB_BIT_WAIT BIT(5)
13026822652SMichael Srba
13126822652SMichael Srba #define DEFAULT_TOUCH_POINT_MODE 2
13226822652SMichael Srba #define MAX_SUPPORTED_FINGER_NUM 5
133075d9b22SNikita Travkin #define MAX_SUPPORTED_BUTTON_NUM 8
13426822652SMichael Srba
13526822652SMichael Srba #define CHIP_ON_DELAY 15 // ms
13626822652SMichael Srba #define FIRMWARE_ON_DELAY 40 // ms
13726822652SMichael Srba
13826822652SMichael Srba struct point_coord {
13926822652SMichael Srba __le16 x;
14026822652SMichael Srba __le16 y;
14126822652SMichael Srba u8 width;
14226822652SMichael Srba u8 sub_status;
14326822652SMichael Srba // currently unused, but needed as padding:
14426822652SMichael Srba u8 minor_width;
14526822652SMichael Srba u8 angle;
14626822652SMichael Srba };
14726822652SMichael Srba
14826822652SMichael Srba struct touch_event {
14926822652SMichael Srba __le16 status;
150e941dc13SLinus Walleij u8 finger_mask;
15126822652SMichael Srba u8 time_stamp;
15226822652SMichael Srba struct point_coord point_coord[MAX_SUPPORTED_FINGER_NUM];
15326822652SMichael Srba };
15426822652SMichael Srba
15526822652SMichael Srba struct bt541_ts_data {
15626822652SMichael Srba struct i2c_client *client;
15726822652SMichael Srba struct input_dev *input_dev;
15826822652SMichael Srba struct touchscreen_properties prop;
15926822652SMichael Srba struct regulator_bulk_data supplies[2];
16026822652SMichael Srba u32 zinitix_mode;
161075d9b22SNikita Travkin u32 keycodes[MAX_SUPPORTED_BUTTON_NUM];
162075d9b22SNikita Travkin int num_keycodes;
1635278bb4cSLinus Walleij bool have_versioninfo;
1645278bb4cSLinus Walleij u16 chip_revision;
1655278bb4cSLinus Walleij u16 firmware_version;
1665278bb4cSLinus Walleij u16 regdata_version;
167dac97383SLinus Walleij u16 icon_status_reg;
16826822652SMichael Srba };
16926822652SMichael Srba
zinitix_read_data(struct i2c_client * client,u16 reg,void * values,size_t length)17026822652SMichael Srba static int zinitix_read_data(struct i2c_client *client,
17126822652SMichael Srba u16 reg, void *values, size_t length)
17226822652SMichael Srba {
17326822652SMichael Srba __le16 reg_le = cpu_to_le16(reg);
17426822652SMichael Srba int ret;
17526822652SMichael Srba
17626822652SMichael Srba /* A single i2c_transfer() transaction does not work here. */
17726822652SMichael Srba ret = i2c_master_send(client, (u8 *)®_le, sizeof(reg_le));
17826822652SMichael Srba if (ret != sizeof(reg_le))
17926822652SMichael Srba return ret < 0 ? ret : -EIO;
18026822652SMichael Srba
18126822652SMichael Srba ret = i2c_master_recv(client, (u8 *)values, length);
18226822652SMichael Srba if (ret != length)
183a374c19fSYang Li return ret < 0 ? ret : -EIO;
18426822652SMichael Srba
18526822652SMichael Srba return 0;
18626822652SMichael Srba }
18726822652SMichael Srba
zinitix_write_u16(struct i2c_client * client,u16 reg,u16 value)18826822652SMichael Srba static int zinitix_write_u16(struct i2c_client *client, u16 reg, u16 value)
18926822652SMichael Srba {
19026822652SMichael Srba __le16 packet[2] = {cpu_to_le16(reg), cpu_to_le16(value)};
19126822652SMichael Srba int ret;
19226822652SMichael Srba
19326822652SMichael Srba ret = i2c_master_send(client, (u8 *)packet, sizeof(packet));
19426822652SMichael Srba if (ret != sizeof(packet))
19526822652SMichael Srba return ret < 0 ? ret : -EIO;
19626822652SMichael Srba
19726822652SMichael Srba return 0;
19826822652SMichael Srba }
19926822652SMichael Srba
zinitix_write_cmd(struct i2c_client * client,u16 reg)20026822652SMichael Srba static int zinitix_write_cmd(struct i2c_client *client, u16 reg)
20126822652SMichael Srba {
20226822652SMichael Srba __le16 reg_le = cpu_to_le16(reg);
20326822652SMichael Srba int ret;
20426822652SMichael Srba
20526822652SMichael Srba ret = i2c_master_send(client, (u8 *)®_le, sizeof(reg_le));
20626822652SMichael Srba if (ret != sizeof(reg_le))
20726822652SMichael Srba return ret < 0 ? ret : -EIO;
20826822652SMichael Srba
20926822652SMichael Srba return 0;
21026822652SMichael Srba }
21126822652SMichael Srba
zinitix_get_u16_reg(struct bt541_ts_data * bt541,u16 vreg)2125278bb4cSLinus Walleij static u16 zinitix_get_u16_reg(struct bt541_ts_data *bt541, u16 vreg)
2135278bb4cSLinus Walleij {
2145278bb4cSLinus Walleij struct i2c_client *client = bt541->client;
2155278bb4cSLinus Walleij int error;
2165278bb4cSLinus Walleij __le16 val;
2175278bb4cSLinus Walleij
2185278bb4cSLinus Walleij error = zinitix_read_data(client, vreg, (void *)&val, 2);
2195278bb4cSLinus Walleij if (error)
2205278bb4cSLinus Walleij return U8_MAX;
2215278bb4cSLinus Walleij
2225278bb4cSLinus Walleij return le16_to_cpu(val);
2235278bb4cSLinus Walleij }
2245278bb4cSLinus Walleij
zinitix_init_touch(struct bt541_ts_data * bt541)225836f308cSDmitry Torokhov static int zinitix_init_touch(struct bt541_ts_data *bt541)
22626822652SMichael Srba {
22726822652SMichael Srba struct i2c_client *client = bt541->client;
22826822652SMichael Srba int i;
22926822652SMichael Srba int error;
230075d9b22SNikita Travkin u16 int_flags;
23126822652SMichael Srba
232077fdc9bSLinus Walleij error = zinitix_write_cmd(client, ZINITIX_SWRESET_CMD);
23326822652SMichael Srba if (error) {
23426822652SMichael Srba dev_err(&client->dev, "Failed to write reset command\n");
23526822652SMichael Srba return error;
23626822652SMichael Srba }
23726822652SMichael Srba
2385278bb4cSLinus Walleij /*
2395278bb4cSLinus Walleij * Read and cache the chip revision and firmware version the first time
2405278bb4cSLinus Walleij * we get here.
2415278bb4cSLinus Walleij */
2425278bb4cSLinus Walleij if (!bt541->have_versioninfo) {
2435278bb4cSLinus Walleij bt541->chip_revision = zinitix_get_u16_reg(bt541,
2445278bb4cSLinus Walleij ZINITIX_CHIP_REVISION);
2455278bb4cSLinus Walleij bt541->firmware_version = zinitix_get_u16_reg(bt541,
2465278bb4cSLinus Walleij ZINITIX_FIRMWARE_VERSION);
2475278bb4cSLinus Walleij bt541->regdata_version = zinitix_get_u16_reg(bt541,
2485278bb4cSLinus Walleij ZINITIX_DATA_VERSION_REG);
2495278bb4cSLinus Walleij bt541->have_versioninfo = true;
2505278bb4cSLinus Walleij
2515278bb4cSLinus Walleij dev_dbg(&client->dev,
2525278bb4cSLinus Walleij "chip revision %04x firmware version %04x regdata version %04x\n",
2535278bb4cSLinus Walleij bt541->chip_revision, bt541->firmware_version,
2545278bb4cSLinus Walleij bt541->regdata_version);
255dac97383SLinus Walleij
256dac97383SLinus Walleij /*
257dac97383SLinus Walleij * Determine the "icon" status register which varies by the
258dac97383SLinus Walleij * chip.
259dac97383SLinus Walleij */
260dac97383SLinus Walleij switch (bt541->chip_revision & ZINITIX_CHIP_BTX0X_MASK) {
261dac97383SLinus Walleij case ZINITIX_CHIP_BT4X2:
262dac97383SLinus Walleij bt541->icon_status_reg = ZINITIX_BT4X2_ICON_STATUS_REG;
263dac97383SLinus Walleij break;
264dac97383SLinus Walleij
265dac97383SLinus Walleij case ZINITIX_CHIP_BT4X3:
266dac97383SLinus Walleij bt541->icon_status_reg = ZINITIX_BT4X3_ICON_STATUS_REG;
267dac97383SLinus Walleij break;
268dac97383SLinus Walleij
269dac97383SLinus Walleij case ZINITIX_CHIP_BT4X4:
270dac97383SLinus Walleij bt541->icon_status_reg = ZINITIX_BT4X4_ICON_STATUS_REG;
271dac97383SLinus Walleij break;
272dac97383SLinus Walleij
273dac97383SLinus Walleij default:
274dac97383SLinus Walleij bt541->icon_status_reg = ZINITIX_BT5XX_ICON_STATUS_REG;
275dac97383SLinus Walleij break;
276dac97383SLinus Walleij }
2775278bb4cSLinus Walleij }
2785278bb4cSLinus Walleij
279077fdc9bSLinus Walleij error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, 0x0);
28026822652SMichael Srba if (error) {
28126822652SMichael Srba dev_err(&client->dev,
28226822652SMichael Srba "Failed to reset interrupt enable flag\n");
28326822652SMichael Srba return error;
28426822652SMichael Srba }
28526822652SMichael Srba
28626822652SMichael Srba /* initialize */
287077fdc9bSLinus Walleij error = zinitix_write_u16(client, ZINITIX_X_RESOLUTION,
28826822652SMichael Srba bt541->prop.max_x);
28926822652SMichael Srba if (error)
29026822652SMichael Srba return error;
29126822652SMichael Srba
292077fdc9bSLinus Walleij error = zinitix_write_u16(client, ZINITIX_Y_RESOLUTION,
29326822652SMichael Srba bt541->prop.max_y);
29426822652SMichael Srba if (error)
29526822652SMichael Srba return error;
29626822652SMichael Srba
297077fdc9bSLinus Walleij error = zinitix_write_u16(client, ZINITIX_SUPPORTED_FINGER_NUM,
29826822652SMichael Srba MAX_SUPPORTED_FINGER_NUM);
29926822652SMichael Srba if (error)
30026822652SMichael Srba return error;
30126822652SMichael Srba
302075d9b22SNikita Travkin error = zinitix_write_u16(client, ZINITIX_BUTTON_SUPPORTED_NUM,
303075d9b22SNikita Travkin bt541->num_keycodes);
304075d9b22SNikita Travkin if (error)
305075d9b22SNikita Travkin return error;
306075d9b22SNikita Travkin
307077fdc9bSLinus Walleij error = zinitix_write_u16(client, ZINITIX_INITIAL_TOUCH_MODE,
30826822652SMichael Srba bt541->zinitix_mode);
30926822652SMichael Srba if (error)
31026822652SMichael Srba return error;
31126822652SMichael Srba
312077fdc9bSLinus Walleij error = zinitix_write_u16(client, ZINITIX_TOUCH_MODE,
31326822652SMichael Srba bt541->zinitix_mode);
31426822652SMichael Srba if (error)
31526822652SMichael Srba return error;
31626822652SMichael Srba
317075d9b22SNikita Travkin int_flags = BIT_PT_CNT_CHANGE | BIT_DOWN | BIT_MOVE | BIT_UP;
318075d9b22SNikita Travkin if (bt541->num_keycodes)
319075d9b22SNikita Travkin int_flags |= BIT_ICON_EVENT;
320075d9b22SNikita Travkin
321075d9b22SNikita Travkin error = zinitix_write_u16(client, ZINITIX_INT_ENABLE_FLAG, int_flags);
32226822652SMichael Srba if (error)
32326822652SMichael Srba return error;
32426822652SMichael Srba
32526822652SMichael Srba /* clear queue */
32626822652SMichael Srba for (i = 0; i < 10; i++) {
327077fdc9bSLinus Walleij zinitix_write_cmd(client, ZINITIX_CLEAR_INT_STATUS_CMD);
32826822652SMichael Srba udelay(10);
32926822652SMichael Srba }
33026822652SMichael Srba
33126822652SMichael Srba return 0;
33226822652SMichael Srba }
33326822652SMichael Srba
zinitix_init_regulators(struct bt541_ts_data * bt541)33426822652SMichael Srba static int zinitix_init_regulators(struct bt541_ts_data *bt541)
33526822652SMichael Srba {
336c54be0e3SLinus Walleij struct device *dev = &bt541->client->dev;
33726822652SMichael Srba int error;
33826822652SMichael Srba
339c54be0e3SLinus Walleij /*
340c54be0e3SLinus Walleij * Some older device trees have erroneous names for the regulators,
341c54be0e3SLinus Walleij * so check if "vddo" is present and in that case use these names.
342c54be0e3SLinus Walleij * Else use the proper supply names on the component.
343c54be0e3SLinus Walleij */
344eaedf192SRob Herring if (of_property_present(dev->of_node, "vddo-supply")) {
34526822652SMichael Srba bt541->supplies[0].supply = "vdd";
34626822652SMichael Srba bt541->supplies[1].supply = "vddo";
347c54be0e3SLinus Walleij } else {
348c54be0e3SLinus Walleij /* Else use the proper supply names */
349c54be0e3SLinus Walleij bt541->supplies[0].supply = "vcca";
350c54be0e3SLinus Walleij bt541->supplies[1].supply = "vdd";
351c54be0e3SLinus Walleij }
352c54be0e3SLinus Walleij error = devm_regulator_bulk_get(dev,
35326822652SMichael Srba ARRAY_SIZE(bt541->supplies),
35426822652SMichael Srba bt541->supplies);
35526822652SMichael Srba if (error < 0) {
356c54be0e3SLinus Walleij dev_err(dev, "Failed to get regulators: %d\n", error);
35726822652SMichael Srba return error;
35826822652SMichael Srba }
35926822652SMichael Srba
36026822652SMichael Srba return 0;
36126822652SMichael Srba }
36226822652SMichael Srba
zinitix_send_power_on_sequence(struct bt541_ts_data * bt541)36326822652SMichael Srba static int zinitix_send_power_on_sequence(struct bt541_ts_data *bt541)
36426822652SMichael Srba {
36526822652SMichael Srba int error;
36626822652SMichael Srba struct i2c_client *client = bt541->client;
36726822652SMichael Srba
36826822652SMichael Srba error = zinitix_write_u16(client, 0xc000, 0x0001);
36926822652SMichael Srba if (error) {
37026822652SMichael Srba dev_err(&client->dev,
37126822652SMichael Srba "Failed to send power sequence(vendor cmd enable)\n");
37226822652SMichael Srba return error;
37326822652SMichael Srba }
37426822652SMichael Srba udelay(10);
37526822652SMichael Srba
37626822652SMichael Srba error = zinitix_write_cmd(client, 0xc004);
37726822652SMichael Srba if (error) {
37826822652SMichael Srba dev_err(&client->dev,
37926822652SMichael Srba "Failed to send power sequence (intn clear)\n");
38026822652SMichael Srba return error;
38126822652SMichael Srba }
38226822652SMichael Srba udelay(10);
38326822652SMichael Srba
38426822652SMichael Srba error = zinitix_write_u16(client, 0xc002, 0x0001);
38526822652SMichael Srba if (error) {
38626822652SMichael Srba dev_err(&client->dev,
38726822652SMichael Srba "Failed to send power sequence (nvm init)\n");
38826822652SMichael Srba return error;
38926822652SMichael Srba }
39026822652SMichael Srba mdelay(2);
39126822652SMichael Srba
39226822652SMichael Srba error = zinitix_write_u16(client, 0xc001, 0x0001);
39326822652SMichael Srba if (error) {
39426822652SMichael Srba dev_err(&client->dev,
39526822652SMichael Srba "Failed to send power sequence (program start)\n");
39626822652SMichael Srba return error;
39726822652SMichael Srba }
39826822652SMichael Srba msleep(FIRMWARE_ON_DELAY);
39926822652SMichael Srba
40026822652SMichael Srba return 0;
40126822652SMichael Srba }
40226822652SMichael Srba
zinitix_report_finger(struct bt541_ts_data * bt541,int slot,const struct point_coord * p)40326822652SMichael Srba static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot,
40426822652SMichael Srba const struct point_coord *p)
40526822652SMichael Srba {
406e941dc13SLinus Walleij u16 x, y;
407e941dc13SLinus Walleij
408e941dc13SLinus Walleij if (unlikely(!(p->sub_status &
409e941dc13SLinus Walleij (SUB_BIT_UP | SUB_BIT_DOWN | SUB_BIT_MOVE)))) {
410e941dc13SLinus Walleij dev_dbg(&bt541->client->dev, "unknown finger event %#02x\n",
411e941dc13SLinus Walleij p->sub_status);
412e941dc13SLinus Walleij return;
413e941dc13SLinus Walleij }
414e941dc13SLinus Walleij
415e941dc13SLinus Walleij x = le16_to_cpu(p->x);
416e941dc13SLinus Walleij y = le16_to_cpu(p->y);
417e941dc13SLinus Walleij
41826822652SMichael Srba input_mt_slot(bt541->input_dev, slot);
419e941dc13SLinus Walleij if (input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER,
420e941dc13SLinus Walleij !(p->sub_status & SUB_BIT_UP))) {
421e941dc13SLinus Walleij touchscreen_report_pos(bt541->input_dev,
422e941dc13SLinus Walleij &bt541->prop, x, y, true);
423e941dc13SLinus Walleij input_report_abs(bt541->input_dev,
424e941dc13SLinus Walleij ABS_MT_TOUCH_MAJOR, p->width);
425e941dc13SLinus Walleij dev_dbg(&bt541->client->dev, "finger %d %s (%u, %u)\n",
426e941dc13SLinus Walleij slot, p->sub_status & SUB_BIT_DOWN ? "down" : "move",
427e941dc13SLinus Walleij x, y);
428e941dc13SLinus Walleij } else {
429e941dc13SLinus Walleij dev_dbg(&bt541->client->dev, "finger %d up (%u, %u)\n",
430e941dc13SLinus Walleij slot, x, y);
431e941dc13SLinus Walleij }
43226822652SMichael Srba }
43326822652SMichael Srba
zinitix_report_keys(struct bt541_ts_data * bt541,u16 icon_events)434075d9b22SNikita Travkin static void zinitix_report_keys(struct bt541_ts_data *bt541, u16 icon_events)
435075d9b22SNikita Travkin {
436075d9b22SNikita Travkin int i;
437075d9b22SNikita Travkin
438075d9b22SNikita Travkin for (i = 0; i < bt541->num_keycodes; i++)
439075d9b22SNikita Travkin input_report_key(bt541->input_dev,
440075d9b22SNikita Travkin bt541->keycodes[i], icon_events & BIT(i));
441075d9b22SNikita Travkin }
442075d9b22SNikita Travkin
zinitix_ts_irq_handler(int irq,void * bt541_handler)44326822652SMichael Srba static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
44426822652SMichael Srba {
44526822652SMichael Srba struct bt541_ts_data *bt541 = bt541_handler;
44626822652SMichael Srba struct i2c_client *client = bt541->client;
44726822652SMichael Srba struct touch_event touch_event;
448e941dc13SLinus Walleij unsigned long finger_mask;
449075d9b22SNikita Travkin __le16 icon_events;
45026822652SMichael Srba int error;
45126822652SMichael Srba int i;
45226822652SMichael Srba
45326822652SMichael Srba memset(&touch_event, 0, sizeof(struct touch_event));
45426822652SMichael Srba
455077fdc9bSLinus Walleij error = zinitix_read_data(bt541->client, ZINITIX_POINT_STATUS_REG,
45626822652SMichael Srba &touch_event, sizeof(struct touch_event));
45726822652SMichael Srba if (error) {
45826822652SMichael Srba dev_err(&client->dev, "Failed to read in touchpoint struct\n");
45926822652SMichael Srba goto out;
46026822652SMichael Srba }
46126822652SMichael Srba
462075d9b22SNikita Travkin if (le16_to_cpu(touch_event.status) & BIT_ICON_EVENT) {
463dac97383SLinus Walleij error = zinitix_read_data(bt541->client, bt541->icon_status_reg,
464075d9b22SNikita Travkin &icon_events, sizeof(icon_events));
465075d9b22SNikita Travkin if (error) {
466075d9b22SNikita Travkin dev_err(&client->dev, "Failed to read icon events\n");
467075d9b22SNikita Travkin goto out;
468075d9b22SNikita Travkin }
469075d9b22SNikita Travkin
470075d9b22SNikita Travkin zinitix_report_keys(bt541, le16_to_cpu(icon_events));
471075d9b22SNikita Travkin }
472075d9b22SNikita Travkin
473e941dc13SLinus Walleij finger_mask = touch_event.finger_mask;
474e941dc13SLinus Walleij for_each_set_bit(i, &finger_mask, MAX_SUPPORTED_FINGER_NUM) {
475e941dc13SLinus Walleij const struct point_coord *p = &touch_event.point_coord[i];
476e941dc13SLinus Walleij
477e941dc13SLinus Walleij /* Only process contacts that are actually reported */
478e941dc13SLinus Walleij if (p->sub_status & SUB_BIT_EXIST)
479e941dc13SLinus Walleij zinitix_report_finger(bt541, i, p);
480e941dc13SLinus Walleij }
48126822652SMichael Srba
48226822652SMichael Srba input_mt_sync_frame(bt541->input_dev);
48326822652SMichael Srba input_sync(bt541->input_dev);
48426822652SMichael Srba
48526822652SMichael Srba out:
486077fdc9bSLinus Walleij zinitix_write_cmd(bt541->client, ZINITIX_CLEAR_INT_STATUS_CMD);
48726822652SMichael Srba return IRQ_HANDLED;
48826822652SMichael Srba }
48926822652SMichael Srba
zinitix_start(struct bt541_ts_data * bt541)49026822652SMichael Srba static int zinitix_start(struct bt541_ts_data *bt541)
49126822652SMichael Srba {
49226822652SMichael Srba int error;
49326822652SMichael Srba
49426822652SMichael Srba error = regulator_bulk_enable(ARRAY_SIZE(bt541->supplies),
49526822652SMichael Srba bt541->supplies);
49626822652SMichael Srba if (error) {
49726822652SMichael Srba dev_err(&bt541->client->dev,
49826822652SMichael Srba "Failed to enable regulators: %d\n", error);
49926822652SMichael Srba return error;
50026822652SMichael Srba }
50126822652SMichael Srba
50226822652SMichael Srba msleep(CHIP_ON_DELAY);
50326822652SMichael Srba
50426822652SMichael Srba error = zinitix_send_power_on_sequence(bt541);
50526822652SMichael Srba if (error) {
50626822652SMichael Srba dev_err(&bt541->client->dev,
50726822652SMichael Srba "Error while sending power-on sequence: %d\n", error);
50826822652SMichael Srba return error;
50926822652SMichael Srba }
51026822652SMichael Srba
51126822652SMichael Srba error = zinitix_init_touch(bt541);
51226822652SMichael Srba if (error) {
51326822652SMichael Srba dev_err(&bt541->client->dev,
51426822652SMichael Srba "Error while configuring touch IC\n");
51526822652SMichael Srba return error;
51626822652SMichael Srba }
51726822652SMichael Srba
51826822652SMichael Srba enable_irq(bt541->client->irq);
51926822652SMichael Srba
52026822652SMichael Srba return 0;
52126822652SMichael Srba }
52226822652SMichael Srba
zinitix_stop(struct bt541_ts_data * bt541)52326822652SMichael Srba static int zinitix_stop(struct bt541_ts_data *bt541)
52426822652SMichael Srba {
52526822652SMichael Srba int error;
52626822652SMichael Srba
52726822652SMichael Srba disable_irq(bt541->client->irq);
52826822652SMichael Srba
52926822652SMichael Srba error = regulator_bulk_disable(ARRAY_SIZE(bt541->supplies),
53026822652SMichael Srba bt541->supplies);
53126822652SMichael Srba if (error) {
53226822652SMichael Srba dev_err(&bt541->client->dev,
53326822652SMichael Srba "Failed to disable regulators: %d\n", error);
53426822652SMichael Srba return error;
53526822652SMichael Srba }
53626822652SMichael Srba
53726822652SMichael Srba return 0;
53826822652SMichael Srba }
53926822652SMichael Srba
zinitix_input_open(struct input_dev * dev)54026822652SMichael Srba static int zinitix_input_open(struct input_dev *dev)
54126822652SMichael Srba {
54226822652SMichael Srba struct bt541_ts_data *bt541 = input_get_drvdata(dev);
54326822652SMichael Srba
54426822652SMichael Srba return zinitix_start(bt541);
54526822652SMichael Srba }
54626822652SMichael Srba
zinitix_input_close(struct input_dev * dev)54726822652SMichael Srba static void zinitix_input_close(struct input_dev *dev)
54826822652SMichael Srba {
54926822652SMichael Srba struct bt541_ts_data *bt541 = input_get_drvdata(dev);
55026822652SMichael Srba
55126822652SMichael Srba zinitix_stop(bt541);
55226822652SMichael Srba }
55326822652SMichael Srba
zinitix_init_input_dev(struct bt541_ts_data * bt541)55426822652SMichael Srba static int zinitix_init_input_dev(struct bt541_ts_data *bt541)
55526822652SMichael Srba {
55626822652SMichael Srba struct input_dev *input_dev;
55726822652SMichael Srba int error;
558075d9b22SNikita Travkin int i;
55926822652SMichael Srba
56026822652SMichael Srba input_dev = devm_input_allocate_device(&bt541->client->dev);
56126822652SMichael Srba if (!input_dev) {
56226822652SMichael Srba dev_err(&bt541->client->dev,
56326822652SMichael Srba "Failed to allocate input device.");
56426822652SMichael Srba return -ENOMEM;
56526822652SMichael Srba }
56626822652SMichael Srba
56726822652SMichael Srba input_set_drvdata(input_dev, bt541);
56826822652SMichael Srba bt541->input_dev = input_dev;
56926822652SMichael Srba
57026822652SMichael Srba input_dev->name = "Zinitix Capacitive TouchScreen";
57126822652SMichael Srba input_dev->phys = "input/ts";
57226822652SMichael Srba input_dev->id.bustype = BUS_I2C;
57326822652SMichael Srba input_dev->open = zinitix_input_open;
57426822652SMichael Srba input_dev->close = zinitix_input_close;
57526822652SMichael Srba
576075d9b22SNikita Travkin if (bt541->num_keycodes) {
577075d9b22SNikita Travkin input_dev->keycode = bt541->keycodes;
578075d9b22SNikita Travkin input_dev->keycodemax = bt541->num_keycodes;
579075d9b22SNikita Travkin input_dev->keycodesize = sizeof(bt541->keycodes[0]);
580075d9b22SNikita Travkin for (i = 0; i < bt541->num_keycodes; i++)
581075d9b22SNikita Travkin input_set_capability(input_dev, EV_KEY, bt541->keycodes[i]);
582075d9b22SNikita Travkin }
583075d9b22SNikita Travkin
58426822652SMichael Srba input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
58526822652SMichael Srba input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
58626822652SMichael Srba input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
58726822652SMichael Srba input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
58826822652SMichael Srba
58926822652SMichael Srba touchscreen_parse_properties(input_dev, true, &bt541->prop);
59026822652SMichael Srba if (!bt541->prop.max_x || !bt541->prop.max_y) {
59126822652SMichael Srba dev_err(&bt541->client->dev,
59226822652SMichael Srba "Touchscreen-size-x and/or touchscreen-size-y not set in dts\n");
59326822652SMichael Srba return -EINVAL;
59426822652SMichael Srba }
59526822652SMichael Srba
59626822652SMichael Srba error = input_mt_init_slots(input_dev, MAX_SUPPORTED_FINGER_NUM,
59726822652SMichael Srba INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
59826822652SMichael Srba if (error) {
59926822652SMichael Srba dev_err(&bt541->client->dev,
60026822652SMichael Srba "Failed to initialize MT slots: %d", error);
60126822652SMichael Srba return error;
60226822652SMichael Srba }
60326822652SMichael Srba
60426822652SMichael Srba error = input_register_device(input_dev);
60526822652SMichael Srba if (error) {
60626822652SMichael Srba dev_err(&bt541->client->dev,
60726822652SMichael Srba "Failed to register input device: %d", error);
60826822652SMichael Srba return error;
60926822652SMichael Srba }
61026822652SMichael Srba
61126822652SMichael Srba return 0;
61226822652SMichael Srba }
61326822652SMichael Srba
zinitix_ts_probe(struct i2c_client * client)61426822652SMichael Srba static int zinitix_ts_probe(struct i2c_client *client)
61526822652SMichael Srba {
61626822652SMichael Srba struct bt541_ts_data *bt541;
61726822652SMichael Srba int error;
61826822652SMichael Srba
61926822652SMichael Srba if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
62026822652SMichael Srba dev_err(&client->dev,
62126822652SMichael Srba "Failed to assert adapter's support for plain I2C.\n");
62226822652SMichael Srba return -ENXIO;
62326822652SMichael Srba }
62426822652SMichael Srba
62526822652SMichael Srba bt541 = devm_kzalloc(&client->dev, sizeof(*bt541), GFP_KERNEL);
62626822652SMichael Srba if (!bt541)
62726822652SMichael Srba return -ENOMEM;
62826822652SMichael Srba
62926822652SMichael Srba bt541->client = client;
63026822652SMichael Srba i2c_set_clientdata(client, bt541);
63126822652SMichael Srba
63226822652SMichael Srba error = zinitix_init_regulators(bt541);
63326822652SMichael Srba if (error) {
63426822652SMichael Srba dev_err(&client->dev,
63526822652SMichael Srba "Failed to initialize regulators: %d\n", error);
63626822652SMichael Srba return error;
63726822652SMichael Srba }
63826822652SMichael Srba
639cf73ed89SNikita Travkin error = devm_request_threaded_irq(&client->dev, client->irq,
640cf73ed89SNikita Travkin NULL, zinitix_ts_irq_handler,
641cf73ed89SNikita Travkin IRQF_ONESHOT | IRQF_NO_AUTOEN,
642cf73ed89SNikita Travkin client->name, bt541);
643cf73ed89SNikita Travkin if (error) {
644cf73ed89SNikita Travkin dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
645cf73ed89SNikita Travkin return error;
646cf73ed89SNikita Travkin }
647cf73ed89SNikita Travkin
648*2de01e0eSNikita Travkin if (device_property_present(&client->dev, "linux,keycodes")) {
649*2de01e0eSNikita Travkin bt541->num_keycodes = device_property_count_u32(&client->dev,
650*2de01e0eSNikita Travkin "linux,keycodes");
651*2de01e0eSNikita Travkin if (bt541->num_keycodes < 0) {
652*2de01e0eSNikita Travkin dev_err(&client->dev, "Failed to count keys (%d)\n",
653*2de01e0eSNikita Travkin bt541->num_keycodes);
654*2de01e0eSNikita Travkin return bt541->num_keycodes;
655*2de01e0eSNikita Travkin } else if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) {
656*2de01e0eSNikita Travkin dev_err(&client->dev, "Too many keys defined (%d)\n",
657*2de01e0eSNikita Travkin bt541->num_keycodes);
658075d9b22SNikita Travkin return -EINVAL;
659075d9b22SNikita Travkin }
660075d9b22SNikita Travkin
661*2de01e0eSNikita Travkin error = device_property_read_u32_array(&client->dev,
662*2de01e0eSNikita Travkin "linux,keycodes",
663075d9b22SNikita Travkin bt541->keycodes,
664075d9b22SNikita Travkin bt541->num_keycodes);
665075d9b22SNikita Travkin if (error) {
666075d9b22SNikita Travkin dev_err(&client->dev,
667*2de01e0eSNikita Travkin "Unable to parse \"linux,keycodes\" property: %d\n",
668*2de01e0eSNikita Travkin error);
669075d9b22SNikita Travkin return error;
670075d9b22SNikita Travkin }
671*2de01e0eSNikita Travkin }
672075d9b22SNikita Travkin
67326822652SMichael Srba error = zinitix_init_input_dev(bt541);
67426822652SMichael Srba if (error) {
67526822652SMichael Srba dev_err(&client->dev,
67626822652SMichael Srba "Failed to initialize input device: %d\n", error);
67726822652SMichael Srba return error;
67826822652SMichael Srba }
67926822652SMichael Srba
68026822652SMichael Srba error = device_property_read_u32(&client->dev, "zinitix,mode",
68126822652SMichael Srba &bt541->zinitix_mode);
68226822652SMichael Srba if (error < 0) {
68326822652SMichael Srba /* fall back to mode 2 */
68426822652SMichael Srba bt541->zinitix_mode = DEFAULT_TOUCH_POINT_MODE;
68526822652SMichael Srba }
68626822652SMichael Srba
68726822652SMichael Srba if (bt541->zinitix_mode != 2) {
68826822652SMichael Srba /*
68926822652SMichael Srba * If there are devices that don't support mode 2, support
69026822652SMichael Srba * for other modes (0, 1) will be needed.
69126822652SMichael Srba */
69226822652SMichael Srba dev_err(&client->dev,
69326822652SMichael Srba "Malformed zinitix,mode property, must be 2 (supplied: %d)\n",
69426822652SMichael Srba bt541->zinitix_mode);
69526822652SMichael Srba return -EINVAL;
69626822652SMichael Srba }
69726822652SMichael Srba
69826822652SMichael Srba return 0;
69926822652SMichael Srba }
70026822652SMichael Srba
zinitix_suspend(struct device * dev)70161df952bSJonathan Cameron static int zinitix_suspend(struct device *dev)
70226822652SMichael Srba {
70326822652SMichael Srba struct i2c_client *client = to_i2c_client(dev);
70426822652SMichael Srba struct bt541_ts_data *bt541 = i2c_get_clientdata(client);
70526822652SMichael Srba
70626822652SMichael Srba mutex_lock(&bt541->input_dev->mutex);
70726822652SMichael Srba
708d69f0a43SAndrzej Pietrasiewicz if (input_device_enabled(bt541->input_dev))
70926822652SMichael Srba zinitix_stop(bt541);
71026822652SMichael Srba
71126822652SMichael Srba mutex_unlock(&bt541->input_dev->mutex);
71226822652SMichael Srba
71326822652SMichael Srba return 0;
71426822652SMichael Srba }
71526822652SMichael Srba
zinitix_resume(struct device * dev)71661df952bSJonathan Cameron static int zinitix_resume(struct device *dev)
71726822652SMichael Srba {
71826822652SMichael Srba struct i2c_client *client = to_i2c_client(dev);
71926822652SMichael Srba struct bt541_ts_data *bt541 = i2c_get_clientdata(client);
72026822652SMichael Srba int ret = 0;
72126822652SMichael Srba
72226822652SMichael Srba mutex_lock(&bt541->input_dev->mutex);
72326822652SMichael Srba
724d69f0a43SAndrzej Pietrasiewicz if (input_device_enabled(bt541->input_dev))
72526822652SMichael Srba ret = zinitix_start(bt541);
72626822652SMichael Srba
72726822652SMichael Srba mutex_unlock(&bt541->input_dev->mutex);
72826822652SMichael Srba
72926822652SMichael Srba return ret;
73026822652SMichael Srba }
73126822652SMichael Srba
73261df952bSJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(zinitix_pm_ops, zinitix_suspend, zinitix_resume);
73326822652SMichael Srba
73426822652SMichael Srba #ifdef CONFIG_OF
73526822652SMichael Srba static const struct of_device_id zinitix_of_match[] = {
736de8aa31aSLinus Walleij { .compatible = "zinitix,bt402" },
737de8aa31aSLinus Walleij { .compatible = "zinitix,bt403" },
738de8aa31aSLinus Walleij { .compatible = "zinitix,bt404" },
739de8aa31aSLinus Walleij { .compatible = "zinitix,bt412" },
740de8aa31aSLinus Walleij { .compatible = "zinitix,bt413" },
741de8aa31aSLinus Walleij { .compatible = "zinitix,bt431" },
742de8aa31aSLinus Walleij { .compatible = "zinitix,bt432" },
743de8aa31aSLinus Walleij { .compatible = "zinitix,bt531" },
7449df136b5SNikita Travkin { .compatible = "zinitix,bt532" },
745de8aa31aSLinus Walleij { .compatible = "zinitix,bt538" },
74626822652SMichael Srba { .compatible = "zinitix,bt541" },
747de8aa31aSLinus Walleij { .compatible = "zinitix,bt548" },
748de8aa31aSLinus Walleij { .compatible = "zinitix,bt554" },
749de8aa31aSLinus Walleij { .compatible = "zinitix,at100" },
75026822652SMichael Srba { }
75126822652SMichael Srba };
75226822652SMichael Srba MODULE_DEVICE_TABLE(of, zinitix_of_match);
75326822652SMichael Srba #endif
75426822652SMichael Srba
75526822652SMichael Srba static struct i2c_driver zinitix_ts_driver = {
756d8bde56dSUwe Kleine-König .probe = zinitix_ts_probe,
75726822652SMichael Srba .driver = {
75826822652SMichael Srba .name = "Zinitix-TS",
75961df952bSJonathan Cameron .pm = pm_sleep_ptr(&zinitix_pm_ops),
76026822652SMichael Srba .of_match_table = of_match_ptr(zinitix_of_match),
76126822652SMichael Srba },
76226822652SMichael Srba };
76326822652SMichael Srba module_i2c_driver(zinitix_ts_driver);
76426822652SMichael Srba
76526822652SMichael Srba MODULE_AUTHOR("Michael Srba <[email protected]>");
76626822652SMichael Srba MODULE_DESCRIPTION("Zinitix touchscreen driver");
76726822652SMichael Srba MODULE_LICENSE("GPL v2");
768