Newer
Older
// SPDX-License-Identifier: GPL-2.0-only
/*
* Elan Microelectronics touch panels with I2C interface
*
* Copyright (C) 2014 Elan Microelectronics Corporation.
* Scott Liu <scott.liu@emc.com.tw>
*
* This code is partly based on hid-multitouch.c:
*
* Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
* Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
* Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
*
* This code is partly based on i2c-hid.c:
*
* Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
* Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
* Copyright (c) 2012 Red Hat, Inc
*/
#include <linux/module.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/async.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/buffer_head.h>
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
/* Device, Driver information */
#define DEVICE_NAME "elants_i2c"
/* Convert from rows or columns into resolution */
#define ELAN_TS_RESOLUTION(n, m) (((n) - 1) * (m))
/* FW header data */
#define HEADER_SIZE 4
#define FW_HDR_TYPE 0
#define FW_HDR_COUNT 1
#define FW_HDR_LENGTH 2
/* Buffer mode Queue Header information */
#define QUEUE_HEADER_SINGLE 0x62
#define QUEUE_HEADER_NORMAL 0X63
#define QUEUE_HEADER_WAIT 0x64
/* Command header definition */
#define CMD_HEADER_WRITE 0x54
#define CMD_HEADER_READ 0x53
#define CMD_HEADER_6B_READ 0x5B
#define CMD_HEADER_ROM_READ 0x96
#define CMD_HEADER_RESP 0x52
#define CMD_HEADER_6B_RESP 0x9B
#define CMD_HEADER_ROM_RESP 0x95
#define CMD_HEADER_HELLO 0x55
#define CMD_HEADER_REK 0x66
/* FW position data */
#define PACKET_SIZE 55
#define MAX_CONTACT_NUM 10
#define FW_POS_HEADER 0
#define FW_POS_STATE 1
#define FW_POS_TOTAL 2
#define FW_POS_XY 3
#define FW_POS_CHECKSUM 34
#define FW_POS_WIDTH 35
#define FW_POS_PRESSURE 45
#define HEADER_REPORT_10_FINGER 0x62
/* Header (4 bytes) plus 3 full 10-finger packets */
#define MAX_PACKET_SIZE 169
#define BOOT_TIME_DELAY_MS 50
/* FW read command, 0x53 0x?? 0x0, 0x01 */
#define E_ELAN_INFO_FW_VER 0x00
#define E_ELAN_INFO_BC_VER 0x10
#define E_ELAN_INFO_REK 0xD0
#define E_ELAN_INFO_TEST_VER 0xE0
#define E_ELAN_INFO_FW_ID 0xF0
#define E_INFO_OSR 0xD6
#define E_INFO_PHY_SCAN 0xD7
#define E_INFO_PHY_DRIVER 0xD8
/* FW write command, 0x54 0x?? 0x0, 0x01 */
#define E_POWER_STATE_SLEEP 0x50
#define E_POWER_STATE_RESUME 0x58
#define MAX_RETRIES 3
#define MAX_FW_UPDATE_RETRIES 30
#define ELAN_FW_PAGESIZE 132
/* calibration timeout definition */
#define ELAN_CALI_TIMEOUT_MSEC 12000
#define ELAN_POWERON_DELAY_USEC 500
#define ELAN_RESET_DELAY_MSEC 20
enum elants_state {
ELAN_STATE_NORMAL,
ELAN_WAIT_QUEUE_HEADER,
ELAN_WAIT_RECALIBRATION,
};
enum elants_iap_mode {
ELAN_IAP_OPERATIONAL,
ELAN_IAP_RECOVERY,
};
/* struct elants_data - represents state of Elan touchscreen device */
struct elants_data {
struct i2c_client *client;
struct input_dev *input;
struct regulator *vcc33;
struct regulator *vccio;
struct gpio_desc *reset_gpio;
u16 fw_version;
u8 test_version;
u8 solution_version;
u8 bc_version;
u8 iap_version;
u16 hw_version;
Johnny Chuang
committed
u8 major_res;
unsigned int x_res; /* resolution in units/mm */
unsigned int y_res;
unsigned int x_max;
unsigned int y_max;
struct touchscreen_properties prop;
enum elants_state state;
enum elants_iap_mode iap_mode;
/* Guards against concurrent access to the device via sysfs */
struct mutex sysfs_mutex;
u8 cmd_resp[HEADER_SIZE];
struct completion cmd_done;
bool wake_irq_enabled;
bool keep_power_in_suspend;
/* Must be last to be used for DMA operations */
u8 buf[MAX_PACKET_SIZE] ____cacheline_aligned;
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
};
static int elants_i2c_send(struct i2c_client *client,
const void *data, size_t size)
{
int ret;
ret = i2c_master_send(client, data, size);
if (ret == size)
return 0;
if (ret >= 0)
ret = -EIO;
dev_err(&client->dev, "%s failed (%*ph): %d\n",
__func__, (int)size, data, ret);
return ret;
}
static int elants_i2c_read(struct i2c_client *client, void *data, size_t size)
{
int ret;
ret = i2c_master_recv(client, data, size);
if (ret == size)
return 0;
if (ret >= 0)
ret = -EIO;
dev_err(&client->dev, "%s failed: %d\n", __func__, ret);
return ret;
}
static int elants_i2c_execute_command(struct i2c_client *client,
const u8 *cmd, size_t cmd_size,
u8 *resp, size_t resp_size,
int retries, const char *cmd_name)
{
struct i2c_msg msgs[2];
int ret;
u8 expected_response;
switch (cmd[0]) {
case CMD_HEADER_READ:
expected_response = CMD_HEADER_RESP;
break;
case CMD_HEADER_6B_READ:
expected_response = CMD_HEADER_6B_RESP;
break;
case CMD_HEADER_ROM_READ:
expected_response = CMD_HEADER_ROM_RESP;
break;
dev_err(&client->dev, "(%s): invalid command: %*ph\n",
cmd_name, (int)cmd_size, cmd);
for (;;) {
msgs[0].addr = client->addr;
msgs[0].flags = client->flags & I2C_M_TEN;
msgs[0].len = cmd_size;
msgs[0].buf = (u8 *)cmd;
msgs[1].addr = client->addr;
msgs[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
msgs[1].flags |= I2C_M_RD;
msgs[1].len = resp_size;
msgs[1].buf = resp;
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret < 0) {
if (--retries > 0) {
dev_dbg(&client->dev,
"(%s) I2C transfer failed: %pe (retrying)\n",
cmd_name, ERR_PTR(ret));
continue;
}
dev_err(&client->dev,
"(%s) I2C transfer failed: %pe\n",
cmd_name, ERR_PTR(ret));
return ret;
}
if (ret != ARRAY_SIZE(msgs) ||
resp[FW_HDR_TYPE] != expected_response) {
if (--retries > 0) {
dev_dbg(&client->dev,
"(%s) unexpected response: %*ph (retrying)\n",
cmd_name, ret, resp);
continue;
}
dev_err(&client->dev,
"(%s) unexpected response: %*ph\n",
cmd_name, ret, resp);
return -EIO;
}
}
static int elants_i2c_calibrate(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int ret, error;
static const u8 w_flashkey[] = { CMD_HEADER_WRITE, 0xC0, 0xE1, 0x5A };
static const u8 rek[] = { CMD_HEADER_WRITE, 0x29, 0x00, 0x01 };
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
static const u8 rek_resp[] = { CMD_HEADER_REK, 0x66, 0x66, 0x66 };
disable_irq(client->irq);
ts->state = ELAN_WAIT_RECALIBRATION;
reinit_completion(&ts->cmd_done);
elants_i2c_send(client, w_flashkey, sizeof(w_flashkey));
elants_i2c_send(client, rek, sizeof(rek));
enable_irq(client->irq);
ret = wait_for_completion_interruptible_timeout(&ts->cmd_done,
msecs_to_jiffies(ELAN_CALI_TIMEOUT_MSEC));
ts->state = ELAN_STATE_NORMAL;
if (ret <= 0) {
error = ret < 0 ? ret : -ETIMEDOUT;
dev_err(&client->dev,
"error while waiting for calibration to complete: %d\n",
error);
return error;
}
if (memcmp(rek_resp, ts->cmd_resp, sizeof(rek_resp))) {
dev_err(&client->dev,
"unexpected calibration response: %*ph\n",
(int)sizeof(ts->cmd_resp), ts->cmd_resp);
return -EINVAL;
}
return 0;
}
static int elants_i2c_sw_reset(struct i2c_client *client)
{
const u8 soft_rst_cmd[] = { 0x77, 0x77, 0x77, 0x77 };
int error;
error = elants_i2c_send(client, soft_rst_cmd,
sizeof(soft_rst_cmd));
if (error) {
dev_err(&client->dev, "software reset failed: %d\n", error);
return error;
}
/*
* We should wait at least 10 msec (but no more than 40) before
* sending fastboot or IAP command to the device.
*/
msleep(30);
return 0;
}
static u16 elants_i2c_parse_version(u8 *buf)
{
return get_unaligned_be32(buf) >> 4;
}
static int elants_i2c_query_hw_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int retry_cnt = MAX_RETRIES;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_ID, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
while (retry_cnt--) {
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp), 1,
"read fw id");
if (error)
return error;
ts->hw_version = elants_i2c_parse_version(resp);
if (ts->hw_version != 0xffff)
return 0;
}
dev_err(&client->dev, "Invalid fw id: %#04x\n", ts->hw_version);
return -EINVAL;
}
static int elants_i2c_query_fw_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int retry_cnt = MAX_RETRIES;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_FW_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
while (retry_cnt--) {
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp), 1,
"read fw version");
if (error)
return error;
ts->fw_version = elants_i2c_parse_version(resp);
if (ts->fw_version != 0x0000 && ts->fw_version != 0xffff)
return 0;
dev_dbg(&client->dev, "(read fw version) resp %*phC\n",
(int)sizeof(resp), resp);
dev_err(&client->dev, "Invalid fw ver: %#04x\n", ts->fw_version);
return -EINVAL;
}
static int elants_i2c_query_test_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
u16 version;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_TEST_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp), MAX_RETRIES,
"read test version");
if (error) {
dev_err(&client->dev, "Failed to read test version\n");
return error;
version = elants_i2c_parse_version(resp);
ts->test_version = version >> 8;
ts->solution_version = version & 0xff;
}
static int elants_i2c_query_bc_version(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
const u8 cmd[] = { CMD_HEADER_READ, E_ELAN_INFO_BC_VER, 0x00, 0x01 };
u8 resp[HEADER_SIZE];
u16 version;
int error;
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp), 1,
"read BC version");
if (error)
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
return error;
version = elants_i2c_parse_version(resp);
ts->bc_version = version >> 8;
ts->iap_version = version & 0xff;
return 0;
}
static int elants_i2c_query_ts_info(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int error;
u8 resp[17];
u16 phy_x, phy_y, rows, cols, osr;
const u8 get_resolution_cmd[] = {
CMD_HEADER_6B_READ, 0x00, 0x00, 0x00, 0x00, 0x00
};
const u8 get_osr_cmd[] = {
CMD_HEADER_READ, E_INFO_OSR, 0x00, 0x01
};
const u8 get_physical_scan_cmd[] = {
CMD_HEADER_READ, E_INFO_PHY_SCAN, 0x00, 0x01
};
const u8 get_physical_drive_cmd[] = {
CMD_HEADER_READ, E_INFO_PHY_DRIVER, 0x00, 0x01
};
/* Get trace number */
error = elants_i2c_execute_command(client,
get_resolution_cmd,
sizeof(get_resolution_cmd),
resp, sizeof(resp), 1,
"get resolution");
if (error)
return error;
rows = resp[2] + resp[6] + resp[10];
cols = resp[3] + resp[7] + resp[11];
Johnny Chuang
committed
/* Get report resolution value of ABS_MT_TOUCH_MAJOR */
ts->major_res = resp[16];
/* Process mm_to_pixel information */
error = elants_i2c_execute_command(client,
get_osr_cmd, sizeof(get_osr_cmd),
resp, sizeof(resp), 1, "get osr");
if (error)
return error;
osr = resp[3];
error = elants_i2c_execute_command(client,
get_physical_scan_cmd,
sizeof(get_physical_scan_cmd),
resp, sizeof(resp), 1,
"get physical scan");
if (error)
return error;
phy_x = get_unaligned_be16(&resp[2]);
error = elants_i2c_execute_command(client,
get_physical_drive_cmd,
sizeof(get_physical_drive_cmd),
resp, sizeof(resp), 1,
"get physical drive");
if (error)
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
return error;
phy_y = get_unaligned_be16(&resp[2]);
dev_dbg(&client->dev, "phy_x=%d, phy_y=%d\n", phy_x, phy_y);
if (rows == 0 || cols == 0 || osr == 0) {
dev_warn(&client->dev,
"invalid trace number data: %d, %d, %d\n",
rows, cols, osr);
} else {
/* translate trace number to TS resolution */
ts->x_max = ELAN_TS_RESOLUTION(rows, osr);
ts->x_res = DIV_ROUND_CLOSEST(ts->x_max, phy_x);
ts->y_max = ELAN_TS_RESOLUTION(cols, osr);
ts->y_res = DIV_ROUND_CLOSEST(ts->y_max, phy_y);
}
return 0;
}
static int elants_i2c_fastboot(struct i2c_client *client)
{
const u8 boot_cmd[] = { 0x4D, 0x61, 0x69, 0x6E };
int error;
error = elants_i2c_send(client, boot_cmd, sizeof(boot_cmd));
if (error) {
dev_err(&client->dev, "boot failed: %d\n", error);
return error;
}
dev_dbg(&client->dev, "boot success -- 0x%x\n", client->addr);
return 0;
}
static int elants_i2c_initialize(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
int error, error2, retry_cnt;
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
const u8 hello_packet[] = { 0x55, 0x55, 0x55, 0x55 };
const u8 recov_packet[] = { 0x55, 0x55, 0x80, 0x80 };
u8 buf[HEADER_SIZE];
for (retry_cnt = 0; retry_cnt < MAX_RETRIES; retry_cnt++) {
error = elants_i2c_sw_reset(client);
if (error) {
/* Continue initializing if it's the last try */
if (retry_cnt < MAX_RETRIES - 1)
continue;
}
error = elants_i2c_fastboot(client);
if (error) {
/* Continue initializing if it's the last try */
if (retry_cnt < MAX_RETRIES - 1)
continue;
}
/* Wait for Hello packet */
msleep(BOOT_TIME_DELAY_MS);
error = elants_i2c_read(client, buf, sizeof(buf));
if (error) {
dev_err(&client->dev,
"failed to read 'hello' packet: %d\n", error);
} else if (!memcmp(buf, hello_packet, sizeof(hello_packet))) {
ts->iap_mode = ELAN_IAP_OPERATIONAL;
break;
} else if (!memcmp(buf, recov_packet, sizeof(recov_packet))) {
/*
* Setting error code will mark device
* in recovery mode below.
*/
error = -EIO;
break;
} else {
error = -EINVAL;
dev_err(&client->dev,
"invalid 'hello' packet: %*ph\n",
(int)sizeof(buf), buf);
}
}
/* hw version is available even if device in recovery state */
error2 = elants_i2c_query_hw_version(ts);
if (!error2)
error2 = elants_i2c_query_bc_version(ts);
error = error2;
if (!error)
error = elants_i2c_query_fw_version(ts);
if (!error)
error = elants_i2c_query_test_version(ts);
if (!error)
error = elants_i2c_query_ts_info(ts);
if (error)
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
ts->iap_mode = ELAN_IAP_RECOVERY;
return 0;
}
/*
* Firmware update interface.
*/
static int elants_i2c_fw_write_page(struct i2c_client *client,
const void *page)
{
const u8 ack_ok[] = { 0xaa, 0xaa };
u8 buf[2];
int retry;
int error;
for (retry = 0; retry < MAX_FW_UPDATE_RETRIES; retry++) {
error = elants_i2c_send(client, page, ELAN_FW_PAGESIZE);
if (error) {
dev_err(&client->dev,
"IAP Write Page failed: %d\n", error);
continue;
}
error = elants_i2c_read(client, buf, 2);
if (error) {
dev_err(&client->dev,
"IAP Ack read failed: %d\n", error);
return error;
}
if (!memcmp(buf, ack_ok, sizeof(ack_ok)))
return 0;
error = -EIO;
dev_err(&client->dev,
"IAP Get Ack Error [%02x:%02x]\n",
buf[0], buf[1]);
}
return error;
}
static int elants_i2c_validate_remark_id(struct elants_data *ts,
const struct firmware *fw)
{
struct i2c_client *client = ts->client;
int error;
const u8 cmd[] = { CMD_HEADER_ROM_READ, 0x80, 0x1F, 0x00, 0x00, 0x21 };
u8 resp[6] = { 0 };
u16 ts_remark_id = 0;
u16 fw_remark_id = 0;
/* Compare TS Remark ID and FW Remark ID */
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
resp, sizeof(resp),
1, "read Remark ID");
if (error)
return error;
ts_remark_id = get_unaligned_be16(&resp[3]);
fw_remark_id = get_unaligned_le16(&fw->data[fw->size - 4]);
if (fw_remark_id != ts_remark_id) {
dev_err(&client->dev,
"Remark ID Mismatched: ts_remark_id=0x%04x, fw_remark_id=0x%04x.\n",
ts_remark_id, fw_remark_id);
return -EINVAL;
}
return 0;
}
static int elants_i2c_do_update_firmware(struct i2c_client *client,
const struct firmware *fw,
bool force)
{
struct elants_data *ts = i2c_get_clientdata(client);
const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 };
const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 };
const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc };
const u8 close_idle[] = { 0x54, 0x2c, 0x01, 0x01 };
u8 buf[HEADER_SIZE];
u16 send_id;
int page, n_fw_pages;
int error;
bool check_remark_id = ts->iap_version >= 0x60;
/* Recovery mode detection! */
if (force) {
dev_dbg(&client->dev, "Recovery mode procedure\n");
if (check_remark_id) {
error = elants_i2c_validate_remark_id(ts, fw);
if (error)
return error;
}
error = elants_i2c_send(client, enter_iap2, sizeof(enter_iap2));
if (error) {
dev_err(&client->dev, "failed to enter IAP mode: %d\n",
error);
return error;
}
} else {
/* Start IAP Procedure */
dev_dbg(&client->dev, "Normal IAP procedure\n");
/* Close idle mode */
error = elants_i2c_send(client, close_idle, sizeof(close_idle));
if (error)
dev_err(&client->dev, "Failed close idle: %d\n", error);
msleep(60);
elants_i2c_sw_reset(client);
if (check_remark_id) {
error = elants_i2c_validate_remark_id(ts, fw);
if (error)
return error;
}
error = elants_i2c_send(client, enter_iap, sizeof(enter_iap));
if (error) {
dev_err(&client->dev, "failed to enter IAP mode: %d\n",
error);
return error;
}
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
}
msleep(20);
/* check IAP state */
error = elants_i2c_read(client, buf, 4);
if (error) {
dev_err(&client->dev,
"failed to read IAP acknowledgement: %d\n",
error);
return error;
}
if (memcmp(buf, iap_ack, sizeof(iap_ack))) {
dev_err(&client->dev,
"failed to enter IAP: %*ph (expected %*ph)\n",
(int)sizeof(buf), buf, (int)sizeof(iap_ack), iap_ack);
return -EIO;
}
dev_info(&client->dev, "successfully entered IAP mode");
send_id = client->addr;
error = elants_i2c_send(client, &send_id, 1);
if (error) {
dev_err(&client->dev, "sending dummy byte failed: %d\n",
error);
return error;
}
/* Clear the last page of Master */
error = elants_i2c_send(client, fw->data, ELAN_FW_PAGESIZE);
if (error) {
dev_err(&client->dev, "clearing of the last page failed: %d\n",
error);
return error;
}
error = elants_i2c_read(client, buf, 2);
if (error) {
dev_err(&client->dev,
"failed to read ACK for clearing the last page: %d\n",
error);
return error;
}
n_fw_pages = fw->size / ELAN_FW_PAGESIZE;
dev_dbg(&client->dev, "IAP Pages = %d\n", n_fw_pages);
for (page = 0; page < n_fw_pages; page++) {
error = elants_i2c_fw_write_page(client,
fw->data + page * ELAN_FW_PAGESIZE);
if (error) {
dev_err(&client->dev,
"failed to write FW page %d: %d\n",
page, error);
return error;
}
}
/* Old iap needs to wait 200ms for WDT and rest is for hello packets */
msleep(300);
dev_info(&client->dev, "firmware update completed\n");
return 0;
}
static int elants_i2c_fw_update(struct elants_data *ts)
{
struct i2c_client *client = ts->client;
const struct firmware *fw;
fw_name = kasprintf(GFP_KERNEL, "elants_i2c_%04x.bin", ts->hw_version);
if (!fw_name)
return -ENOMEM;
dev_info(&client->dev, "requesting fw name = %s\n", fw_name);
error = request_firmware(&fw, fw_name, &client->dev);
kfree(fw_name);
dev_err(&client->dev, "failed to request firmware: %d\n",
error);
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
return error;
}
if (fw->size % ELAN_FW_PAGESIZE) {
dev_err(&client->dev, "invalid firmware length: %zu\n",
fw->size);
error = -EINVAL;
goto out;
}
disable_irq(client->irq);
error = elants_i2c_do_update_firmware(client, fw,
ts->iap_mode == ELAN_IAP_RECOVERY);
if (error) {
dev_err(&client->dev, "firmware update failed: %d\n", error);
ts->iap_mode = ELAN_IAP_RECOVERY;
goto out_enable_irq;
}
error = elants_i2c_initialize(ts);
if (error) {
dev_err(&client->dev,
"failed to initialize device after firmware update: %d\n",
error);
ts->iap_mode = ELAN_IAP_RECOVERY;
goto out_enable_irq;
}
ts->iap_mode = ELAN_IAP_OPERATIONAL;
out_enable_irq:
ts->state = ELAN_STATE_NORMAL;
enable_irq(client->irq);
msleep(100);
if (!error)
elants_i2c_calibrate(ts);
out:
release_firmware(fw);
return error;
}
/*
* Event reporting.
*/
static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
{
struct input_dev *input = ts->input;
unsigned int n_fingers;
u16 finger_state;
int i;
n_fingers = buf[FW_POS_STATE + 1] & 0x0f;
finger_state = ((buf[FW_POS_STATE + 1] & 0x30) << 4) |
buf[FW_POS_STATE];
dev_dbg(&ts->client->dev,
"n_fingers: %u, state: %04x\n", n_fingers, finger_state);
/* Note: all fingers have the same tool type */
tool_type = buf[FW_POS_TOOL_TYPE] & BIT(0) ?
MT_TOOL_FINGER : MT_TOOL_PALM;
for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) {
if (finger_state & 1) {
unsigned int x, y, p, w;
u8 *pos;
pos = &buf[FW_POS_XY + i * 3];
x = (((u16)pos[0] & 0xf0) << 4) | pos[1];
y = (((u16)pos[0] & 0x0f) << 8) | pos[2];
p = buf[FW_POS_PRESSURE + i];
w = buf[FW_POS_WIDTH + i];
dev_dbg(&ts->client->dev, "i=%d x=%d y=%d p=%d w=%d\n",
i, x, y, p, w);
input_mt_slot(input, i);
input_mt_report_slot_state(input, tool_type, true);
touchscreen_report_pos(input, &ts->prop, x, y, true);
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, w);
n_fingers--;
}
finger_state >>= 1;
}
input_mt_sync_frame(input);
input_sync(input);
}
static u8 elants_i2c_calculate_checksum(u8 *buf)
{
u8 checksum = 0;
u8 i;
for (i = 0; i < FW_POS_CHECKSUM; i++)
checksum += buf[i];
return checksum;
}
static void elants_i2c_event(struct elants_data *ts, u8 *buf)
{
u8 checksum = elants_i2c_calculate_checksum(buf);
if (unlikely(buf[FW_POS_CHECKSUM] != checksum))
dev_warn(&ts->client->dev,
"%s: invalid checksum for packet %02x: %02x vs. %02x\n",
__func__, buf[FW_POS_HEADER],
checksum, buf[FW_POS_CHECKSUM]);
else if (unlikely(buf[FW_POS_HEADER] != HEADER_REPORT_10_FINGER))
dev_warn(&ts->client->dev,
"%s: unknown packet type: %02x\n",
__func__, buf[FW_POS_HEADER]);
else
elants_i2c_mt_event(ts, buf);
}
static irqreturn_t elants_i2c_irq(int irq, void *_dev)
{
const u8 wait_packet[] = { 0x64, 0x64, 0x64, 0x64 };
struct elants_data *ts = _dev;
struct i2c_client *client = ts->client;
int report_count, report_len;
int i;
int len;
len = i2c_master_recv_dmasafe(client, ts->buf, sizeof(ts->buf));
if (len < 0) {
dev_err(&client->dev, "%s: failed to read data: %d\n",
__func__, len);
goto out;
}
dev_dbg(&client->dev, "%s: packet %*ph\n",
__func__, HEADER_SIZE, ts->buf);
switch (ts->state) {
case ELAN_WAIT_RECALIBRATION:
if (ts->buf[FW_HDR_TYPE] == CMD_HEADER_REK) {
memcpy(ts->cmd_resp, ts->buf, sizeof(ts->cmd_resp));
complete(&ts->cmd_done);
ts->state = ELAN_STATE_NORMAL;
}
break;
case ELAN_WAIT_QUEUE_HEADER:
if (ts->buf[FW_HDR_TYPE] != QUEUE_HEADER_NORMAL)
break;
ts->state = ELAN_STATE_NORMAL;
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
case ELAN_STATE_NORMAL:
switch (ts->buf[FW_HDR_TYPE]) {
case CMD_HEADER_HELLO:
case CMD_HEADER_RESP:
case CMD_HEADER_REK:
break;
case QUEUE_HEADER_WAIT:
if (memcmp(ts->buf, wait_packet, sizeof(wait_packet))) {
dev_err(&client->dev,
"invalid wait packet %*ph\n",
HEADER_SIZE, ts->buf);
} else {
ts->state = ELAN_WAIT_QUEUE_HEADER;
udelay(30);
}
break;
case QUEUE_HEADER_SINGLE:
elants_i2c_event(ts, &ts->buf[HEADER_SIZE]);
break;
case QUEUE_HEADER_NORMAL:
report_count = ts->buf[FW_HDR_COUNT];
if (report_count == 0 || report_count > 3) {
"bad report count: %*ph\n",