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 *)®_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 *)®_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