2 * Weida HiTech WDT87xx TouchScreen I2C driver
4 * Copyright (c) 2015 Weida Hi-Tech Co., Ltd.
5 * HN Chen <hn.chen@weidahitech.com>
7 * This software is licensed under the terms of the GNU General Public
8 * License, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
12 #include <linux/i2c.h>
13 #include <linux/input.h>
14 #include <linux/interrupt.h>
15 #include <linux/delay.h>
16 #include <linux/irq.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <linux/firmware.h>
21 #include <linux/input/mt.h>
22 #include <linux/acpi.h>
23 #include <asm/unaligned.h>
25 #define WDT87XX_NAME "wdt87xx_i2c"
26 #define WDT87XX_DRV_VER "0.9.6"
27 #define WDT87XX_FW_NAME "wdt87xx_fw.bin"
28 #define WDT87XX_CFG_NAME "wdt87xx_cfg.bin"
30 #define MODE_ACTIVE 0x01
31 #define MODE_READY 0x02
32 #define MODE_IDLE 0x03
33 #define MODE_SLEEP 0x04
34 #define MODE_STOP 0xFF
36 #define WDT_MAX_FINGER 10
37 #define WDT_RAW_BUF_COUNT 54
38 #define WDT_V1_RAW_BUF_COUNT 74
39 #define WDT_FIRMWARE_ID 0xa9e368f5
41 #define PG_SIZE 0x1000
44 #define MAX_UNIT_AXIS 0x7FFF
46 #define PKT_READ_SIZE 72
47 #define PKT_WRITE_SIZE 80
49 /* the finger definition of the report event */
50 #define FINGER_EV_OFFSET_ID 0
51 #define FINGER_EV_OFFSET_X 1
52 #define FINGER_EV_OFFSET_Y 3
53 #define FINGER_EV_SIZE 5
55 #define FINGER_EV_V1_OFFSET_ID 0
56 #define FINGER_EV_V1_OFFSET_W 1
57 #define FINGER_EV_V1_OFFSET_P 2
58 #define FINGER_EV_V1_OFFSET_X 3
59 #define FINGER_EV_V1_OFFSET_Y 5
60 #define FINGER_EV_V1_SIZE 7
62 /* The definition of a report packet */
63 #define TOUCH_PK_OFFSET_REPORT_ID 0
64 #define TOUCH_PK_OFFSET_EVENT 1
65 #define TOUCH_PK_OFFSET_SCAN_TIME 51
66 #define TOUCH_PK_OFFSET_FNGR_NUM 53
68 #define TOUCH_PK_V1_OFFSET_REPORT_ID 0
69 #define TOUCH_PK_V1_OFFSET_EVENT 1
70 #define TOUCH_PK_V1_OFFSET_SCAN_TIME 71
71 #define TOUCH_PK_V1_OFFSET_FNGR_NUM 73
73 /* The definition of the controller parameters */
74 #define CTL_PARAM_OFFSET_FW_ID 0
75 #define CTL_PARAM_OFFSET_PLAT_ID 2
76 #define CTL_PARAM_OFFSET_XMLS_ID1 4
77 #define CTL_PARAM_OFFSET_XMLS_ID2 6
78 #define CTL_PARAM_OFFSET_PHY_CH_X 8
79 #define CTL_PARAM_OFFSET_PHY_CH_Y 10
80 #define CTL_PARAM_OFFSET_PHY_X0 12
81 #define CTL_PARAM_OFFSET_PHY_X1 14
82 #define CTL_PARAM_OFFSET_PHY_Y0 16
83 #define CTL_PARAM_OFFSET_PHY_Y1 18
84 #define CTL_PARAM_OFFSET_PHY_W 22
85 #define CTL_PARAM_OFFSET_PHY_H 24
86 #define CTL_PARAM_OFFSET_FACTOR 32
88 /* Communication commands */
89 #define PACKET_SIZE 56
90 #define VND_REQ_READ 0x06
91 #define VND_READ_DATA 0x07
92 #define VND_REQ_WRITE 0x08
94 #define VND_CMD_START 0x00
95 #define VND_CMD_STOP 0x01
96 #define VND_CMD_RESET 0x09
98 #define VND_CMD_ERASE 0x1A
100 #define VND_GET_CHECKSUM 0x66
102 #define VND_SET_DATA 0x83
103 #define VND_SET_COMMAND_DATA 0x84
104 #define VND_SET_CHECKSUM_CALC 0x86
105 #define VND_SET_CHECKSUM_LENGTH 0x87
107 #define VND_CMD_SFLCK 0xFC
108 #define VND_CMD_SFUNL 0xFD
110 #define CMD_SFLCK_KEY 0xC39B
111 #define CMD_SFUNL_KEY 0x95DA
113 #define STRIDX_PLATFORM_ID 0x80
114 #define STRIDX_PARAMETERS 0x81
116 #define CMD_BUF_SIZE 8
117 #define PKT_BUF_SIZE 64
119 /* The definition of the command packet */
120 #define CMD_REPORT_ID_OFFSET 0x0
121 #define CMD_TYPE_OFFSET 0x1
122 #define CMD_INDEX_OFFSET 0x2
123 #define CMD_KEY_OFFSET 0x3
124 #define CMD_LENGTH_OFFSET 0x4
125 #define CMD_DATA_OFFSET 0x8
127 /* The definition of firmware chunk tags */
128 #define FOURCC_ID_RIFF 0x46464952
129 #define FOURCC_ID_WHIF 0x46494857
130 #define FOURCC_ID_FRMT 0x544D5246
131 #define FOURCC_ID_FRWR 0x52575246
132 #define FOURCC_ID_CNFG 0x47464E43
134 #define CHUNK_ID_FRMT FOURCC_ID_FRMT
135 #define CHUNK_ID_FRWR FOURCC_ID_FRWR
136 #define CHUNK_ID_CNFG FOURCC_ID_CNFG
138 #define FW_FOURCC1_OFFSET 0
139 #define FW_SIZE_OFFSET 4
140 #define FW_FOURCC2_OFFSET 8
141 #define FW_PAYLOAD_OFFSET 40
143 #define FW_CHUNK_ID_OFFSET 0
144 #define FW_CHUNK_SIZE_OFFSET 4
145 #define FW_CHUNK_TGT_START_OFFSET 8
146 #define FW_CHUNK_PAYLOAD_LEN_OFFSET 12
147 #define FW_CHUNK_SRC_START_OFFSET 16
148 #define FW_CHUNK_VERSION_OFFSET 20
149 #define FW_CHUNK_ATTR_OFFSET 24
150 #define FW_CHUNK_PAYLOAD_OFFSET 32
152 /* Controller requires minimum 300us between commands */
153 #define WDT_COMMAND_DELAY_MS 2
154 #define WDT_FLASH_WRITE_DELAY_MS 4
156 struct wdt87xx_sys_param
{
170 struct wdt87xx_data
{
171 struct i2c_client
*client
;
172 struct input_dev
*input
;
173 /* Mutex for fw update to prevent concurrent access */
174 struct mutex fw_mutex
;
175 struct wdt87xx_sys_param param
;
179 static int wdt87xx_i2c_xfer(struct i2c_client
*client
,
180 void *txdata
, size_t txlen
,
181 void *rxdata
, size_t rxlen
)
183 struct i2c_msg msgs
[] = {
185 .addr
= client
->addr
,
191 .addr
= client
->addr
,
200 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
201 if (ret
!= ARRAY_SIZE(msgs
)) {
202 error
= ret
< 0 ? ret
: -EIO
;
203 dev_err(&client
->dev
, "%s: i2c transfer failed: %d\n",
211 static int wdt87xx_get_string(struct i2c_client
*client
, u8 str_idx
,
214 u8 tx_buf
[] = { 0x22, 0x00, 0x13, 0x0E, str_idx
, 0x23, 0x00 };
215 u8 rx_buf
[PKT_WRITE_SIZE
];
216 size_t rx_len
= len
+ 2;
219 if (rx_len
> sizeof(rx_buf
))
222 error
= wdt87xx_i2c_xfer(client
, tx_buf
, sizeof(tx_buf
),
225 dev_err(&client
->dev
, "get string failed: %d\n", error
);
229 if (rx_buf
[1] != 0x03) {
230 dev_err(&client
->dev
, "unexpected response to get string: %d\n",
235 rx_len
= min_t(size_t, len
, rx_buf
[0]);
236 memcpy(buf
, &rx_buf
[2], rx_len
);
238 mdelay(WDT_COMMAND_DELAY_MS
);
243 static int wdt87xx_get_feature(struct i2c_client
*client
,
244 u8
*buf
, size_t buf_size
)
247 u8 rx_buf
[PKT_WRITE_SIZE
];
249 size_t rx_len
= buf_size
+ 2;
252 if (rx_len
> sizeof(rx_buf
))
255 /* Get feature command packet */
256 tx_buf
[tx_len
++] = 0x22;
257 tx_buf
[tx_len
++] = 0x00;
258 if (buf
[CMD_REPORT_ID_OFFSET
] > 0xF) {
259 tx_buf
[tx_len
++] = 0x30;
260 tx_buf
[tx_len
++] = 0x02;
261 tx_buf
[tx_len
++] = buf
[CMD_REPORT_ID_OFFSET
];
263 tx_buf
[tx_len
++] = 0x30 | buf
[CMD_REPORT_ID_OFFSET
];
264 tx_buf
[tx_len
++] = 0x02;
266 tx_buf
[tx_len
++] = 0x23;
267 tx_buf
[tx_len
++] = 0x00;
269 error
= wdt87xx_i2c_xfer(client
, tx_buf
, tx_len
, rx_buf
, rx_len
);
271 dev_err(&client
->dev
, "get feature failed: %d\n", error
);
275 rx_len
= min_t(size_t, buf_size
, get_unaligned_le16(rx_buf
));
276 memcpy(buf
, &rx_buf
[2], rx_len
);
278 mdelay(WDT_COMMAND_DELAY_MS
);
283 static int wdt87xx_set_feature(struct i2c_client
*client
,
284 const u8
*buf
, size_t buf_size
)
286 u8 tx_buf
[PKT_WRITE_SIZE
];
290 /* Set feature command packet */
291 tx_buf
[tx_len
++] = 0x22;
292 tx_buf
[tx_len
++] = 0x00;
293 if (buf
[CMD_REPORT_ID_OFFSET
] > 0xF) {
294 tx_buf
[tx_len
++] = 0x30;
295 tx_buf
[tx_len
++] = 0x03;
296 tx_buf
[tx_len
++] = buf
[CMD_REPORT_ID_OFFSET
];
298 tx_buf
[tx_len
++] = 0x30 | buf
[CMD_REPORT_ID_OFFSET
];
299 tx_buf
[tx_len
++] = 0x03;
301 tx_buf
[tx_len
++] = 0x23;
302 tx_buf
[tx_len
++] = 0x00;
303 tx_buf
[tx_len
++] = (buf_size
& 0xFF);
304 tx_buf
[tx_len
++] = ((buf_size
& 0xFF00) >> 8);
306 if (tx_len
+ buf_size
> sizeof(tx_buf
))
309 memcpy(&tx_buf
[tx_len
], buf
, buf_size
);
312 error
= i2c_master_send(client
, tx_buf
, tx_len
);
314 dev_err(&client
->dev
, "set feature failed: %d\n", error
);
318 mdelay(WDT_COMMAND_DELAY_MS
);
323 static int wdt87xx_send_command(struct i2c_client
*client
, int cmd
, int value
)
325 u8 cmd_buf
[CMD_BUF_SIZE
];
327 /* Set the command packet */
328 cmd_buf
[CMD_REPORT_ID_OFFSET
] = VND_REQ_WRITE
;
329 cmd_buf
[CMD_TYPE_OFFSET
] = VND_SET_COMMAND_DATA
;
330 put_unaligned_le16((u16
)cmd
, &cmd_buf
[CMD_INDEX_OFFSET
]);
337 put_unaligned_le32((value
& 0xFF), &cmd_buf
[CMD_LENGTH_OFFSET
]);
341 put_unaligned_le16(CMD_SFLCK_KEY
, &cmd_buf
[CMD_KEY_OFFSET
]);
345 put_unaligned_le16(CMD_SFUNL_KEY
, &cmd_buf
[CMD_KEY_OFFSET
]);
349 case VND_SET_CHECKSUM_CALC
:
350 case VND_SET_CHECKSUM_LENGTH
:
351 put_unaligned_le32(value
, &cmd_buf
[CMD_KEY_OFFSET
]);
355 cmd_buf
[CMD_REPORT_ID_OFFSET
] = 0;
356 dev_err(&client
->dev
, "Invalid command: %d\n", cmd
);
360 return wdt87xx_set_feature(client
, cmd_buf
, sizeof(cmd_buf
));
363 static int wdt87xx_sw_reset(struct i2c_client
*client
)
367 dev_dbg(&client
->dev
, "resetting device now\n");
369 error
= wdt87xx_send_command(client
, VND_CMD_RESET
, 0);
371 dev_err(&client
->dev
, "reset failed\n");
375 /* Wait the device to be ready */
381 static const void *wdt87xx_get_fw_chunk(const struct firmware
*fw
, u32 id
)
383 size_t pos
= FW_PAYLOAD_OFFSET
;
384 u32 chunk_id
, chunk_size
;
386 while (pos
< fw
->size
) {
387 chunk_id
= get_unaligned_le32(fw
->data
+
388 pos
+ FW_CHUNK_ID_OFFSET
);
390 return fw
->data
+ pos
;
392 chunk_size
= get_unaligned_le32(fw
->data
+
393 pos
+ FW_CHUNK_SIZE_OFFSET
);
394 pos
+= chunk_size
+ 2 * sizeof(u32
); /* chunk ID + size */
400 static int wdt87xx_get_sysparam(struct i2c_client
*client
,
401 struct wdt87xx_sys_param
*param
)
403 u8 buf
[PKT_READ_SIZE
];
406 error
= wdt87xx_get_string(client
, STRIDX_PARAMETERS
, buf
, 34);
408 dev_err(&client
->dev
, "failed to get parameters\n");
412 param
->xmls_id1
= get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_XMLS_ID1
);
413 param
->xmls_id2
= get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_XMLS_ID2
);
414 param
->phy_ch_x
= get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_PHY_CH_X
);
415 param
->phy_ch_y
= get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_PHY_CH_Y
);
416 param
->phy_w
= get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_PHY_W
) / 10;
417 param
->phy_h
= get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_PHY_H
) / 10;
419 /* Get the scaling factor of pixel to logical coordinate */
420 param
->scaling_factor
=
421 get_unaligned_le16(buf
+ CTL_PARAM_OFFSET_FACTOR
);
423 param
->max_x
= MAX_UNIT_AXIS
;
424 param
->max_y
= DIV_ROUND_CLOSEST(MAX_UNIT_AXIS
* param
->phy_h
,
427 error
= wdt87xx_get_string(client
, STRIDX_PLATFORM_ID
, buf
, 8);
429 dev_err(&client
->dev
, "failed to get platform id\n");
433 param
->plat_id
= buf
[1];
436 error
= wdt87xx_get_feature(client
, buf
, 16);
438 dev_err(&client
->dev
, "failed to get firmware id\n");
442 if (buf
[0] != 0xf2) {
443 dev_err(&client
->dev
, "wrong id of fw response: 0x%x\n",
448 param
->fw_id
= get_unaligned_le16(&buf
[1]);
450 dev_info(&client
->dev
,
451 "fw_id: 0x%x, plat_id: 0x%x, xml_id1: %04x, xml_id2: %04x\n",
452 param
->fw_id
, param
->plat_id
,
453 param
->xmls_id1
, param
->xmls_id2
);
458 static int wdt87xx_validate_firmware(struct wdt87xx_data
*wdt
,
459 const struct firmware
*fw
)
461 const void *fw_chunk
;
467 data1
= get_unaligned_le32(fw
->data
+ FW_FOURCC1_OFFSET
);
468 data2
= get_unaligned_le32(fw
->data
+ FW_FOURCC2_OFFSET
);
469 if (data1
!= FOURCC_ID_RIFF
|| data2
!= FOURCC_ID_WHIF
) {
470 dev_err(&wdt
->client
->dev
, "check fw tag failed\n");
474 size
= get_unaligned_le32(fw
->data
+ FW_SIZE_OFFSET
);
475 if (size
!= fw
->size
) {
476 dev_err(&wdt
->client
->dev
,
477 "fw size mismatch: expected %d, actual %zu\n",
483 * Get the chip_id from the firmware. Make sure that it is the
484 * right controller to do the firmware and config update.
486 fw_chunk
= wdt87xx_get_fw_chunk(fw
, CHUNK_ID_FRWR
);
488 dev_err(&wdt
->client
->dev
,
489 "unable to locate firmware chunk\n");
493 fw_chip_id
= (get_unaligned_le32(fw_chunk
+
494 FW_CHUNK_VERSION_OFFSET
) >> 12) & 0xF;
495 chip_id
= (wdt
->param
.fw_id
>> 12) & 0xF;
497 if (fw_chip_id
!= chip_id
) {
498 dev_err(&wdt
->client
->dev
,
499 "fw version mismatch: fw %d vs. chip %d\n",
500 fw_chip_id
, chip_id
);
507 static int wdt87xx_validate_fw_chunk(const void *data
, int id
)
509 if (id
== CHUNK_ID_FRWR
) {
512 fw_id
= get_unaligned_le32(data
+ FW_CHUNK_PAYLOAD_OFFSET
);
513 if (fw_id
!= WDT_FIRMWARE_ID
)
520 static int wdt87xx_write_data(struct i2c_client
*client
, const char *data
,
521 u32 address
, int length
)
526 u8 pkt_buf
[PKT_BUF_SIZE
];
528 /* Address and length should be 4 bytes aligned */
529 if ((address
& 0x3) != 0 || (length
& 0x3) != 0) {
530 dev_err(&client
->dev
,
531 "addr & len must be 4 bytes aligned %x, %x\n",
537 packet_size
= min(length
, PACKET_SIZE
);
539 pkt_buf
[CMD_REPORT_ID_OFFSET
] = VND_REQ_WRITE
;
540 pkt_buf
[CMD_TYPE_OFFSET
] = VND_SET_DATA
;
541 put_unaligned_le16(packet_size
, &pkt_buf
[CMD_INDEX_OFFSET
]);
542 put_unaligned_le32(address
, &pkt_buf
[CMD_LENGTH_OFFSET
]);
543 memcpy(&pkt_buf
[CMD_DATA_OFFSET
], data
, packet_size
);
545 error
= wdt87xx_set_feature(client
, pkt_buf
, sizeof(pkt_buf
));
549 length
-= packet_size
;
551 address
+= packet_size
;
553 /* Wait for the controller to finish the write */
554 mdelay(WDT_FLASH_WRITE_DELAY_MS
);
556 if ((++count
% 32) == 0) {
557 /* Delay for fw to clear watch dog */
565 static u16
misr(u16 cur_value
, u8 new_value
)
582 y
= (y
& ~1) | (bit0
& 1);
587 static u16
wdt87xx_calculate_checksum(const u8
*data
, size_t length
)
592 for (i
= 0; i
< length
; i
++)
593 checksum
= misr(checksum
, data
[i
]);
598 static int wdt87xx_get_checksum(struct i2c_client
*client
, u16
*checksum
,
599 u32 address
, int length
)
603 u8 pkt_buf
[PKT_BUF_SIZE
];
604 u8 cmd_buf
[CMD_BUF_SIZE
];
606 error
= wdt87xx_send_command(client
, VND_SET_CHECKSUM_LENGTH
, length
);
608 dev_err(&client
->dev
, "failed to set checksum length\n");
612 error
= wdt87xx_send_command(client
, VND_SET_CHECKSUM_CALC
, address
);
614 dev_err(&client
->dev
, "failed to set checksum address\n");
618 /* Wait the operation to complete */
619 time_delay
= DIV_ROUND_UP(length
, 1024);
620 msleep(time_delay
* 30);
622 memset(cmd_buf
, 0, sizeof(cmd_buf
));
623 cmd_buf
[CMD_REPORT_ID_OFFSET
] = VND_REQ_READ
;
624 cmd_buf
[CMD_TYPE_OFFSET
] = VND_GET_CHECKSUM
;
625 error
= wdt87xx_set_feature(client
, cmd_buf
, sizeof(cmd_buf
));
627 dev_err(&client
->dev
, "failed to request checksum\n");
631 memset(pkt_buf
, 0, sizeof(pkt_buf
));
632 pkt_buf
[CMD_REPORT_ID_OFFSET
] = VND_READ_DATA
;
633 error
= wdt87xx_get_feature(client
, pkt_buf
, sizeof(pkt_buf
));
635 dev_err(&client
->dev
, "failed to read checksum\n");
639 *checksum
= get_unaligned_le16(&pkt_buf
[CMD_DATA_OFFSET
]);
643 static int wdt87xx_write_firmware(struct i2c_client
*client
, const void *chunk
)
645 u32 start_addr
= get_unaligned_le32(chunk
+ FW_CHUNK_TGT_START_OFFSET
);
646 u32 size
= get_unaligned_le32(chunk
+ FW_CHUNK_PAYLOAD_LEN_OFFSET
);
647 const void *data
= chunk
+ FW_CHUNK_PAYLOAD_OFFSET
;
652 u16 device_checksum
, firmware_checksum
;
654 dev_dbg(&client
->dev
, "start 4k page program\n");
656 error
= wdt87xx_send_command(client
, VND_CMD_STOP
, MODE_STOP
);
658 dev_err(&client
->dev
, "stop report mode failed\n");
662 error
= wdt87xx_send_command(client
, VND_CMD_SFUNL
, 0);
664 dev_err(&client
->dev
, "unlock failed\n");
665 goto out_enable_reporting
;
671 dev_dbg(&client
->dev
, "%s: %x, %x\n", __func__
,
674 page_size
= min_t(u32
, size
, PG_SIZE
);
677 for (retry
= 0; retry
< MAX_RETRIES
; retry
++) {
678 error
= wdt87xx_send_command(client
, VND_CMD_ERASE
,
681 dev_err(&client
->dev
,
682 "erase failed at %#08x\n", start_addr
);
688 error
= wdt87xx_write_data(client
, data
, start_addr
,
691 dev_err(&client
->dev
,
692 "write failed at %#08x (%d bytes)\n",
693 start_addr
, page_size
);
697 error
= wdt87xx_get_checksum(client
, &device_checksum
,
698 start_addr
, page_size
);
700 dev_err(&client
->dev
,
701 "failed to retrieve checksum for %#08x (len: %d)\n",
702 start_addr
, page_size
);
707 wdt87xx_calculate_checksum(data
, page_size
);
709 if (device_checksum
== firmware_checksum
)
712 dev_err(&client
->dev
,
713 "checksum fail: %d vs %d, retry %d\n",
714 device_checksum
, firmware_checksum
, retry
);
717 if (retry
== MAX_RETRIES
) {
718 dev_err(&client
->dev
, "page write failed\n");
720 goto out_lock_device
;
723 start_addr
= start_addr
+ page_size
;
724 data
= data
+ page_size
;
728 err1
= wdt87xx_send_command(client
, VND_CMD_SFLCK
, 0);
730 dev_err(&client
->dev
, "lock failed\n");
734 out_enable_reporting
:
735 err1
= wdt87xx_send_command(client
, VND_CMD_START
, 0);
737 dev_err(&client
->dev
, "start to report failed\n");
739 return error
? error
: err1
;
742 static int wdt87xx_load_chunk(struct i2c_client
*client
,
743 const struct firmware
*fw
, u32 ck_id
)
748 chunk
= wdt87xx_get_fw_chunk(fw
, ck_id
);
750 dev_err(&client
->dev
, "unable to locate chunk (type %d)\n",
755 error
= wdt87xx_validate_fw_chunk(chunk
, ck_id
);
757 dev_err(&client
->dev
, "invalid chunk (type %d): %d\n",
762 error
= wdt87xx_write_firmware(client
, chunk
);
764 dev_err(&client
->dev
,
765 "failed to write fw chunk (type %d): %d\n",
773 static int wdt87xx_do_update_firmware(struct i2c_client
*client
,
774 const struct firmware
*fw
,
775 unsigned int chunk_id
)
777 struct wdt87xx_data
*wdt
= i2c_get_clientdata(client
);
780 error
= wdt87xx_validate_firmware(wdt
, fw
);
784 error
= mutex_lock_interruptible(&wdt
->fw_mutex
);
788 disable_irq(client
->irq
);
790 error
= wdt87xx_load_chunk(client
, fw
, chunk_id
);
792 dev_err(&client
->dev
,
793 "firmware load failed (type: %d): %d\n",
798 error
= wdt87xx_sw_reset(client
);
800 dev_err(&client
->dev
, "soft reset failed: %d\n", error
);
804 /* Refresh the parameters */
805 error
= wdt87xx_get_sysparam(client
, &wdt
->param
);
807 dev_err(&client
->dev
,
808 "failed to refresh system paramaters: %d\n", error
);
810 enable_irq(client
->irq
);
811 mutex_unlock(&wdt
->fw_mutex
);
813 return error
? error
: 0;
816 static int wdt87xx_update_firmware(struct device
*dev
,
817 const char *fw_name
, unsigned int chunk_id
)
819 struct i2c_client
*client
= to_i2c_client(dev
);
820 const struct firmware
*fw
;
823 error
= request_firmware(&fw
, fw_name
, dev
);
825 dev_err(&client
->dev
, "unable to retrieve firmware %s: %d\n",
830 error
= wdt87xx_do_update_firmware(client
, fw
, chunk_id
);
832 release_firmware(fw
);
834 return error
? error
: 0;
837 static ssize_t
config_csum_show(struct device
*dev
,
838 struct device_attribute
*attr
, char *buf
)
840 struct i2c_client
*client
= to_i2c_client(dev
);
841 struct wdt87xx_data
*wdt
= i2c_get_clientdata(client
);
844 cfg_csum
= wdt
->param
.xmls_id1
;
845 cfg_csum
= (cfg_csum
<< 16) | wdt
->param
.xmls_id2
;
847 return scnprintf(buf
, PAGE_SIZE
, "%x\n", cfg_csum
);
850 static ssize_t
fw_version_show(struct device
*dev
,
851 struct device_attribute
*attr
, char *buf
)
853 struct i2c_client
*client
= to_i2c_client(dev
);
854 struct wdt87xx_data
*wdt
= i2c_get_clientdata(client
);
856 return scnprintf(buf
, PAGE_SIZE
, "%x\n", wdt
->param
.fw_id
);
859 static ssize_t
plat_id_show(struct device
*dev
,
860 struct device_attribute
*attr
, char *buf
)
862 struct i2c_client
*client
= to_i2c_client(dev
);
863 struct wdt87xx_data
*wdt
= i2c_get_clientdata(client
);
865 return scnprintf(buf
, PAGE_SIZE
, "%x\n", wdt
->param
.plat_id
);
868 static ssize_t
update_config_store(struct device
*dev
,
869 struct device_attribute
*attr
,
870 const char *buf
, size_t count
)
874 error
= wdt87xx_update_firmware(dev
, WDT87XX_CFG_NAME
, CHUNK_ID_CNFG
);
876 return error
? error
: count
;
879 static ssize_t
update_fw_store(struct device
*dev
,
880 struct device_attribute
*attr
,
881 const char *buf
, size_t count
)
885 error
= wdt87xx_update_firmware(dev
, WDT87XX_FW_NAME
, CHUNK_ID_FRWR
);
887 return error
? error
: count
;
890 static DEVICE_ATTR_RO(config_csum
);
891 static DEVICE_ATTR_RO(fw_version
);
892 static DEVICE_ATTR_RO(plat_id
);
893 static DEVICE_ATTR_WO(update_config
);
894 static DEVICE_ATTR_WO(update_fw
);
896 static struct attribute
*wdt87xx_attrs
[] = {
897 &dev_attr_config_csum
.attr
,
898 &dev_attr_fw_version
.attr
,
899 &dev_attr_plat_id
.attr
,
900 &dev_attr_update_config
.attr
,
901 &dev_attr_update_fw
.attr
,
905 static const struct attribute_group wdt87xx_attr_group
= {
906 .attrs
= wdt87xx_attrs
,
909 static void wdt87xx_report_contact(struct input_dev
*input
,
910 struct wdt87xx_sys_param
*param
,
917 finger_id
= (buf
[FINGER_EV_V1_OFFSET_ID
] >> 3) - 1;
921 /* Check if this is an active contact */
922 if (!(buf
[FINGER_EV_V1_OFFSET_ID
] & 0x1))
925 w
= buf
[FINGER_EV_V1_OFFSET_W
];
926 w
*= param
->scaling_factor
;
928 p
= buf
[FINGER_EV_V1_OFFSET_P
];
930 x
= get_unaligned_le16(buf
+ FINGER_EV_V1_OFFSET_X
);
932 y
= get_unaligned_le16(buf
+ FINGER_EV_V1_OFFSET_Y
);
933 y
= DIV_ROUND_CLOSEST(y
* param
->phy_h
, param
->phy_w
);
935 /* Refuse incorrect coordinates */
936 if (x
> param
->max_x
|| y
> param
->max_y
)
939 dev_dbg(input
->dev
.parent
, "tip on (%d), x(%d), y(%d)\n",
942 input_mt_slot(input
, finger_id
);
943 input_mt_report_slot_state(input
, MT_TOOL_FINGER
, 1);
944 input_report_abs(input
, ABS_MT_TOUCH_MAJOR
, w
);
945 input_report_abs(input
, ABS_MT_PRESSURE
, p
);
946 input_report_abs(input
, ABS_MT_POSITION_X
, x
);
947 input_report_abs(input
, ABS_MT_POSITION_Y
, y
);
950 static irqreturn_t
wdt87xx_ts_interrupt(int irq
, void *dev_id
)
952 struct wdt87xx_data
*wdt
= dev_id
;
953 struct i2c_client
*client
= wdt
->client
;
956 u8 raw_buf
[WDT_V1_RAW_BUF_COUNT
] = {0};
958 error
= i2c_master_recv(client
, raw_buf
, WDT_V1_RAW_BUF_COUNT
);
960 dev_err(&client
->dev
, "read v1 raw data failed: %d\n", error
);
964 fingers
= raw_buf
[TOUCH_PK_V1_OFFSET_FNGR_NUM
];
968 for (i
= 0; i
< WDT_MAX_FINGER
; i
++)
969 wdt87xx_report_contact(wdt
->input
,
971 &raw_buf
[TOUCH_PK_V1_OFFSET_EVENT
+
972 i
* FINGER_EV_V1_SIZE
]);
974 input_mt_sync_frame(wdt
->input
);
975 input_sync(wdt
->input
);
981 static int wdt87xx_ts_create_input_device(struct wdt87xx_data
*wdt
)
983 struct device
*dev
= &wdt
->client
->dev
;
984 struct input_dev
*input
;
985 unsigned int res
= DIV_ROUND_CLOSEST(MAX_UNIT_AXIS
, wdt
->param
.phy_w
);
988 input
= devm_input_allocate_device(dev
);
990 dev_err(dev
, "failed to allocate input device\n");
995 input
->name
= "WDT87xx Touchscreen";
996 input
->id
.bustype
= BUS_I2C
;
997 input
->phys
= wdt
->phys
;
999 input_set_abs_params(input
, ABS_MT_POSITION_X
, 0,
1000 wdt
->param
.max_x
, 0, 0);
1001 input_set_abs_params(input
, ABS_MT_POSITION_Y
, 0,
1002 wdt
->param
.max_y
, 0, 0);
1003 input_abs_set_res(input
, ABS_MT_POSITION_X
, res
);
1004 input_abs_set_res(input
, ABS_MT_POSITION_Y
, res
);
1006 input_set_abs_params(input
, ABS_MT_TOUCH_MAJOR
,
1007 0, wdt
->param
.max_x
, 0, 0);
1008 input_set_abs_params(input
, ABS_MT_PRESSURE
, 0, 0xFF, 0, 0);
1010 input_mt_init_slots(input
, WDT_MAX_FINGER
,
1011 INPUT_MT_DIRECT
| INPUT_MT_DROP_UNUSED
);
1013 error
= input_register_device(input
);
1015 dev_err(dev
, "failed to register input device: %d\n", error
);
1022 static int wdt87xx_ts_probe(struct i2c_client
*client
,
1023 const struct i2c_device_id
*id
)
1025 struct wdt87xx_data
*wdt
;
1028 dev_dbg(&client
->dev
, "adapter=%d, client irq: %d\n",
1029 client
->adapter
->nr
, client
->irq
);
1031 /* Check if the I2C function is ok in this adaptor */
1032 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
))
1035 wdt
= devm_kzalloc(&client
->dev
, sizeof(*wdt
), GFP_KERNEL
);
1039 wdt
->client
= client
;
1040 mutex_init(&wdt
->fw_mutex
);
1041 i2c_set_clientdata(client
, wdt
);
1043 snprintf(wdt
->phys
, sizeof(wdt
->phys
), "i2c-%u-%04x/input0",
1044 client
->adapter
->nr
, client
->addr
);
1046 error
= wdt87xx_get_sysparam(client
, &wdt
->param
);
1050 error
= wdt87xx_ts_create_input_device(wdt
);
1054 error
= devm_request_threaded_irq(&client
->dev
, client
->irq
,
1055 NULL
, wdt87xx_ts_interrupt
,
1059 dev_err(&client
->dev
, "request irq failed: %d\n", error
);
1063 error
= sysfs_create_group(&client
->dev
.kobj
, &wdt87xx_attr_group
);
1065 dev_err(&client
->dev
, "create sysfs failed: %d\n", error
);
1072 static int wdt87xx_ts_remove(struct i2c_client
*client
)
1074 sysfs_remove_group(&client
->dev
.kobj
, &wdt87xx_attr_group
);
1079 static int __maybe_unused
wdt87xx_suspend(struct device
*dev
)
1081 struct i2c_client
*client
= to_i2c_client(dev
);
1084 disable_irq(client
->irq
);
1086 error
= wdt87xx_send_command(client
, VND_CMD_STOP
, MODE_IDLE
);
1088 enable_irq(client
->irq
);
1089 dev_err(&client
->dev
,
1090 "failed to stop device when suspending: %d\n",
1098 static int __maybe_unused
wdt87xx_resume(struct device
*dev
)
1100 struct i2c_client
*client
= to_i2c_client(dev
);
1104 * The chip may have been reset while system is resuming,
1105 * give it some time to settle.
1109 error
= wdt87xx_send_command(client
, VND_CMD_START
, 0);
1111 dev_err(&client
->dev
,
1112 "failed to start device when resuming: %d\n",
1115 enable_irq(client
->irq
);
1120 static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops
, wdt87xx_suspend
, wdt87xx_resume
);
1122 static const struct i2c_device_id wdt87xx_dev_id
[] = {
1123 { WDT87XX_NAME
, 0 },
1126 MODULE_DEVICE_TABLE(i2c
, wdt87xx_dev_id
);
1128 static const struct acpi_device_id wdt87xx_acpi_id
[] = {
1132 MODULE_DEVICE_TABLE(acpi
, wdt87xx_acpi_id
);
1134 static struct i2c_driver wdt87xx_driver
= {
1135 .probe
= wdt87xx_ts_probe
,
1136 .remove
= wdt87xx_ts_remove
,
1137 .id_table
= wdt87xx_dev_id
,
1139 .name
= WDT87XX_NAME
,
1140 .pm
= &wdt87xx_pm_ops
,
1141 .acpi_match_table
= ACPI_PTR(wdt87xx_acpi_id
),
1144 module_i2c_driver(wdt87xx_driver
);
1146 MODULE_AUTHOR("HN Chen <hn.chen@weidahitech.com>");
1147 MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver");
1148 MODULE_VERSION(WDT87XX_DRV_VER
);
1149 MODULE_LICENSE("GPL");