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