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