Input: wdt87xx_i2c - populate vendor and product in input device
[linux-2.6-block.git] / drivers / input / touchscreen / wdt87xx_i2c.c
CommitLineData
3e30c11c
HC
1/*
2 * Weida HiTech WDT87xx TouchScreen I2C driver
3 *
4 * Copyright (c) 2015 Weida Hi-Tech Co., Ltd.
5 * HN Chen <hn.chen@weidahitech.com>
6 *
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.
10 */
11
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>
17#include <linux/io.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>
24
25#define WDT87XX_NAME "wdt87xx_i2c"
d5ebe37e 26#define WDT87XX_DRV_VER "0.9.7"
3e30c11c
HC
27#define WDT87XX_FW_NAME "wdt87xx_fw.bin"
28#define WDT87XX_CFG_NAME "wdt87xx_cfg.bin"
29
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
35
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
40
41#define PG_SIZE 0x1000
42#define MAX_RETRIES 3
43
44#define MAX_UNIT_AXIS 0x7FFF
45
46#define PKT_READ_SIZE 72
47#define PKT_WRITE_SIZE 80
48
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
54
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
61
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
67
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
72
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
d55d0b56 86#define CTL_PARAM_OFFSET_FACTOR 32
3e30c11c 87
d5ebe37e
HC
88/* The definition of the device descriptor */
89#define WDT_GD_DEVICE 1
90#define DEV_DESC_OFFSET_VID 8
91#define DEV_DESC_OFFSET_PID 10
92
3e30c11c
HC
93/* Communication commands */
94#define PACKET_SIZE 56
95#define VND_REQ_READ 0x06
96#define VND_READ_DATA 0x07
97#define VND_REQ_WRITE 0x08
98
99#define VND_CMD_START 0x00
100#define VND_CMD_STOP 0x01
101#define VND_CMD_RESET 0x09
102
103#define VND_CMD_ERASE 0x1A
104
105#define VND_GET_CHECKSUM 0x66
106
107#define VND_SET_DATA 0x83
108#define VND_SET_COMMAND_DATA 0x84
109#define VND_SET_CHECKSUM_CALC 0x86
110#define VND_SET_CHECKSUM_LENGTH 0x87
111
112#define VND_CMD_SFLCK 0xFC
113#define VND_CMD_SFUNL 0xFD
114
115#define CMD_SFLCK_KEY 0xC39B
116#define CMD_SFUNL_KEY 0x95DA
117
118#define STRIDX_PLATFORM_ID 0x80
119#define STRIDX_PARAMETERS 0x81
120
121#define CMD_BUF_SIZE 8
122#define PKT_BUF_SIZE 64
123
124/* The definition of the command packet */
125#define CMD_REPORT_ID_OFFSET 0x0
126#define CMD_TYPE_OFFSET 0x1
127#define CMD_INDEX_OFFSET 0x2
128#define CMD_KEY_OFFSET 0x3
129#define CMD_LENGTH_OFFSET 0x4
130#define CMD_DATA_OFFSET 0x8
131
132/* The definition of firmware chunk tags */
133#define FOURCC_ID_RIFF 0x46464952
134#define FOURCC_ID_WHIF 0x46494857
135#define FOURCC_ID_FRMT 0x544D5246
136#define FOURCC_ID_FRWR 0x52575246
137#define FOURCC_ID_CNFG 0x47464E43
138
139#define CHUNK_ID_FRMT FOURCC_ID_FRMT
140#define CHUNK_ID_FRWR FOURCC_ID_FRWR
141#define CHUNK_ID_CNFG FOURCC_ID_CNFG
142
143#define FW_FOURCC1_OFFSET 0
144#define FW_SIZE_OFFSET 4
145#define FW_FOURCC2_OFFSET 8
146#define FW_PAYLOAD_OFFSET 40
147
148#define FW_CHUNK_ID_OFFSET 0
149#define FW_CHUNK_SIZE_OFFSET 4
150#define FW_CHUNK_TGT_START_OFFSET 8
151#define FW_CHUNK_PAYLOAD_LEN_OFFSET 12
152#define FW_CHUNK_SRC_START_OFFSET 16
153#define FW_CHUNK_VERSION_OFFSET 20
154#define FW_CHUNK_ATTR_OFFSET 24
155#define FW_CHUNK_PAYLOAD_OFFSET 32
156
157/* Controller requires minimum 300us between commands */
158#define WDT_COMMAND_DELAY_MS 2
159#define WDT_FLASH_WRITE_DELAY_MS 4
160
161struct wdt87xx_sys_param {
162 u16 fw_id;
163 u16 plat_id;
164 u16 xmls_id1;
165 u16 xmls_id2;
166 u16 phy_ch_x;
167 u16 phy_ch_y;
168 u16 phy_w;
169 u16 phy_h;
d55d0b56 170 u16 scaling_factor;
3e30c11c
HC
171 u32 max_x;
172 u32 max_y;
d5ebe37e
HC
173 u16 vendor_id;
174 u16 product_id;
3e30c11c
HC
175};
176
177struct wdt87xx_data {
178 struct i2c_client *client;
179 struct input_dev *input;
180 /* Mutex for fw update to prevent concurrent access */
181 struct mutex fw_mutex;
182 struct wdt87xx_sys_param param;
183 u8 phys[32];
184};
185
186static int wdt87xx_i2c_xfer(struct i2c_client *client,
187 void *txdata, size_t txlen,
188 void *rxdata, size_t rxlen)
189{
190 struct i2c_msg msgs[] = {
191 {
192 .addr = client->addr,
193 .flags = 0,
194 .len = txlen,
195 .buf = txdata,
196 },
197 {
198 .addr = client->addr,
199 .flags = I2C_M_RD,
200 .len = rxlen,
201 .buf = rxdata,
202 },
203 };
204 int error;
205 int ret;
206
207 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
208 if (ret != ARRAY_SIZE(msgs)) {
209 error = ret < 0 ? ret : -EIO;
210 dev_err(&client->dev, "%s: i2c transfer failed: %d\n",
211 __func__, error);
212 return error;
213 }
214
215 return 0;
216}
217
d5ebe37e
HC
218static int wdt87xx_get_desc(struct i2c_client *client, u8 desc_idx,
219 u8 *buf, size_t len)
220{
221 u8 tx_buf[] = { 0x22, 0x00, 0x10, 0x0E, 0x23, 0x00 };
222 int error;
223
224 tx_buf[2] |= desc_idx & 0xF;
225
226 error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
227 buf, len);
228 if (error) {
229 dev_err(&client->dev, "get desc failed: %d\n", error);
230 return error;
231 }
232
233 if (buf[0] != len) {
234 dev_err(&client->dev, "unexpected response to get desc: %d\n",
235 buf[0]);
236 return -EINVAL;
237 }
238
239 mdelay(WDT_COMMAND_DELAY_MS);
240
241 return 0;
242}
243
3e30c11c
HC
244static int wdt87xx_get_string(struct i2c_client *client, u8 str_idx,
245 u8 *buf, size_t len)
246{
247 u8 tx_buf[] = { 0x22, 0x00, 0x13, 0x0E, str_idx, 0x23, 0x00 };
248 u8 rx_buf[PKT_WRITE_SIZE];
249 size_t rx_len = len + 2;
250 int error;
251
252 if (rx_len > sizeof(rx_buf))
253 return -EINVAL;
254
255 error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
256 rx_buf, rx_len);
257 if (error) {
258 dev_err(&client->dev, "get string failed: %d\n", error);
259 return error;
260 }
261
262 if (rx_buf[1] != 0x03) {
263 dev_err(&client->dev, "unexpected response to get string: %d\n",
264 rx_buf[1]);
265 return -EINVAL;
266 }
267
268 rx_len = min_t(size_t, len, rx_buf[0]);
269 memcpy(buf, &rx_buf[2], rx_len);
270
271 mdelay(WDT_COMMAND_DELAY_MS);
272
273 return 0;
274}
275
276static int wdt87xx_get_feature(struct i2c_client *client,
277 u8 *buf, size_t buf_size)
278{
279 u8 tx_buf[8];
280 u8 rx_buf[PKT_WRITE_SIZE];
281 size_t tx_len = 0;
282 size_t rx_len = buf_size + 2;
283 int error;
284
285 if (rx_len > sizeof(rx_buf))
286 return -EINVAL;
287
288 /* Get feature command packet */
289 tx_buf[tx_len++] = 0x22;
290 tx_buf[tx_len++] = 0x00;
291 if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
292 tx_buf[tx_len++] = 0x30;
293 tx_buf[tx_len++] = 0x02;
294 tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
295 } else {
296 tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
297 tx_buf[tx_len++] = 0x02;
298 }
299 tx_buf[tx_len++] = 0x23;
300 tx_buf[tx_len++] = 0x00;
301
302 error = wdt87xx_i2c_xfer(client, tx_buf, tx_len, rx_buf, rx_len);
303 if (error) {
304 dev_err(&client->dev, "get feature failed: %d\n", error);
305 return error;
306 }
307
308 rx_len = min_t(size_t, buf_size, get_unaligned_le16(rx_buf));
309 memcpy(buf, &rx_buf[2], rx_len);
310
311 mdelay(WDT_COMMAND_DELAY_MS);
312
313 return 0;
314}
315
316static int wdt87xx_set_feature(struct i2c_client *client,
317 const u8 *buf, size_t buf_size)
318{
319 u8 tx_buf[PKT_WRITE_SIZE];
320 int tx_len = 0;
321 int error;
322
323 /* Set feature command packet */
324 tx_buf[tx_len++] = 0x22;
325 tx_buf[tx_len++] = 0x00;
326 if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
327 tx_buf[tx_len++] = 0x30;
328 tx_buf[tx_len++] = 0x03;
329 tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
330 } else {
331 tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
332 tx_buf[tx_len++] = 0x03;
333 }
334 tx_buf[tx_len++] = 0x23;
335 tx_buf[tx_len++] = 0x00;
336 tx_buf[tx_len++] = (buf_size & 0xFF);
337 tx_buf[tx_len++] = ((buf_size & 0xFF00) >> 8);
338
339 if (tx_len + buf_size > sizeof(tx_buf))
340 return -EINVAL;
341
342 memcpy(&tx_buf[tx_len], buf, buf_size);
343 tx_len += buf_size;
344
345 error = i2c_master_send(client, tx_buf, tx_len);
346 if (error < 0) {
347 dev_err(&client->dev, "set feature failed: %d\n", error);
348 return error;
349 }
350
351 mdelay(WDT_COMMAND_DELAY_MS);
352
353 return 0;
354}
355
356static int wdt87xx_send_command(struct i2c_client *client, int cmd, int value)
357{
358 u8 cmd_buf[CMD_BUF_SIZE];
359
360 /* Set the command packet */
361 cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
362 cmd_buf[CMD_TYPE_OFFSET] = VND_SET_COMMAND_DATA;
363 put_unaligned_le16((u16)cmd, &cmd_buf[CMD_INDEX_OFFSET]);
364
365 switch (cmd) {
366 case VND_CMD_START:
367 case VND_CMD_STOP:
368 case VND_CMD_RESET:
369 /* Mode selector */
370 put_unaligned_le32((value & 0xFF), &cmd_buf[CMD_LENGTH_OFFSET]);
371 break;
372
373 case VND_CMD_SFLCK:
374 put_unaligned_le16(CMD_SFLCK_KEY, &cmd_buf[CMD_KEY_OFFSET]);
375 break;
376
377 case VND_CMD_SFUNL:
378 put_unaligned_le16(CMD_SFUNL_KEY, &cmd_buf[CMD_KEY_OFFSET]);
379 break;
380
381 case VND_CMD_ERASE:
382 case VND_SET_CHECKSUM_CALC:
383 case VND_SET_CHECKSUM_LENGTH:
384 put_unaligned_le32(value, &cmd_buf[CMD_KEY_OFFSET]);
385 break;
386
387 default:
388 cmd_buf[CMD_REPORT_ID_OFFSET] = 0;
389 dev_err(&client->dev, "Invalid command: %d\n", cmd);
390 return -EINVAL;
391 }
392
393 return wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
394}
395
396static int wdt87xx_sw_reset(struct i2c_client *client)
397{
398 int error;
399
400 dev_dbg(&client->dev, "resetting device now\n");
401
402 error = wdt87xx_send_command(client, VND_CMD_RESET, 0);
403 if (error) {
404 dev_err(&client->dev, "reset failed\n");
405 return error;
406 }
407
408 /* Wait the device to be ready */
409 msleep(200);
410
411 return 0;
412}
413
414static const void *wdt87xx_get_fw_chunk(const struct firmware *fw, u32 id)
415{
416 size_t pos = FW_PAYLOAD_OFFSET;
417 u32 chunk_id, chunk_size;
418
419 while (pos < fw->size) {
420 chunk_id = get_unaligned_le32(fw->data +
421 pos + FW_CHUNK_ID_OFFSET);
422 if (chunk_id == id)
423 return fw->data + pos;
424
425 chunk_size = get_unaligned_le32(fw->data +
426 pos + FW_CHUNK_SIZE_OFFSET);
427 pos += chunk_size + 2 * sizeof(u32); /* chunk ID + size */
428 }
429
430 return NULL;
431}
432
433static int wdt87xx_get_sysparam(struct i2c_client *client,
434 struct wdt87xx_sys_param *param)
435{
436 u8 buf[PKT_READ_SIZE];
437 int error;
438
d5ebe37e
HC
439 error = wdt87xx_get_desc(client, WDT_GD_DEVICE, buf, 18);
440 if (error) {
441 dev_err(&client->dev, "failed to get device desc\n");
442 return error;
443 }
444
445 param->vendor_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_VID);
446 param->product_id = get_unaligned_le16(buf + DEV_DESC_OFFSET_PID);
447
d55d0b56 448 error = wdt87xx_get_string(client, STRIDX_PARAMETERS, buf, 34);
3e30c11c
HC
449 if (error) {
450 dev_err(&client->dev, "failed to get parameters\n");
451 return error;
452 }
453
454 param->xmls_id1 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID1);
455 param->xmls_id2 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID2);
456 param->phy_ch_x = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_X);
457 param->phy_ch_y = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_Y);
458 param->phy_w = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_W) / 10;
459 param->phy_h = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_H) / 10;
460
d55d0b56
HC
461 /* Get the scaling factor of pixel to logical coordinate */
462 param->scaling_factor =
463 get_unaligned_le16(buf + CTL_PARAM_OFFSET_FACTOR);
464
3e30c11c
HC
465 param->max_x = MAX_UNIT_AXIS;
466 param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h,
467 param->phy_w);
468
469 error = wdt87xx_get_string(client, STRIDX_PLATFORM_ID, buf, 8);
470 if (error) {
471 dev_err(&client->dev, "failed to get platform id\n");
472 return error;
473 }
474
475 param->plat_id = buf[1];
476
477 buf[0] = 0xf2;
478 error = wdt87xx_get_feature(client, buf, 16);
479 if (error) {
480 dev_err(&client->dev, "failed to get firmware id\n");
481 return error;
482 }
483
484 if (buf[0] != 0xf2) {
485 dev_err(&client->dev, "wrong id of fw response: 0x%x\n",
486 buf[0]);
487 return -EINVAL;
488 }
489
490 param->fw_id = get_unaligned_le16(&buf[1]);
491
492 dev_info(&client->dev,
57ff96e0 493 "fw_id: 0x%x, plat_id: 0x%x, xml_id1: %04x, xml_id2: %04x\n",
3e30c11c
HC
494 param->fw_id, param->plat_id,
495 param->xmls_id1, param->xmls_id2);
496
497 return 0;
498}
499
500static int wdt87xx_validate_firmware(struct wdt87xx_data *wdt,
501 const struct firmware *fw)
502{
503 const void *fw_chunk;
504 u32 data1, data2;
505 u32 size;
506 u8 fw_chip_id;
507 u8 chip_id;
508
509 data1 = get_unaligned_le32(fw->data + FW_FOURCC1_OFFSET);
510 data2 = get_unaligned_le32(fw->data + FW_FOURCC2_OFFSET);
511 if (data1 != FOURCC_ID_RIFF || data2 != FOURCC_ID_WHIF) {
512 dev_err(&wdt->client->dev, "check fw tag failed\n");
513 return -EINVAL;
514 }
515
516 size = get_unaligned_le32(fw->data + FW_SIZE_OFFSET);
517 if (size != fw->size) {
518 dev_err(&wdt->client->dev,
11ddba28 519 "fw size mismatch: expected %d, actual %zu\n",
3e30c11c
HC
520 size, fw->size);
521 return -EINVAL;
522 }
523
524 /*
525 * Get the chip_id from the firmware. Make sure that it is the
526 * right controller to do the firmware and config update.
527 */
528 fw_chunk = wdt87xx_get_fw_chunk(fw, CHUNK_ID_FRWR);
529 if (!fw_chunk) {
530 dev_err(&wdt->client->dev,
531 "unable to locate firmware chunk\n");
532 return -EINVAL;
533 }
534
535 fw_chip_id = (get_unaligned_le32(fw_chunk +
536 FW_CHUNK_VERSION_OFFSET) >> 12) & 0xF;
537 chip_id = (wdt->param.fw_id >> 12) & 0xF;
538
539 if (fw_chip_id != chip_id) {
540 dev_err(&wdt->client->dev,
541 "fw version mismatch: fw %d vs. chip %d\n",
542 fw_chip_id, chip_id);
543 return -ENODEV;
544 }
545
546 return 0;
547}
548
549static int wdt87xx_validate_fw_chunk(const void *data, int id)
550{
551 if (id == CHUNK_ID_FRWR) {
552 u32 fw_id;
553
554 fw_id = get_unaligned_le32(data + FW_CHUNK_PAYLOAD_OFFSET);
555 if (fw_id != WDT_FIRMWARE_ID)
556 return -EINVAL;
557 }
558
559 return 0;
560}
561
562static int wdt87xx_write_data(struct i2c_client *client, const char *data,
563 u32 address, int length)
564{
565 u16 packet_size;
566 int count = 0;
567 int error;
568 u8 pkt_buf[PKT_BUF_SIZE];
569
570 /* Address and length should be 4 bytes aligned */
571 if ((address & 0x3) != 0 || (length & 0x3) != 0) {
572 dev_err(&client->dev,
573 "addr & len must be 4 bytes aligned %x, %x\n",
574 address, length);
575 return -EINVAL;
576 }
577
578 while (length) {
579 packet_size = min(length, PACKET_SIZE);
580
581 pkt_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
582 pkt_buf[CMD_TYPE_OFFSET] = VND_SET_DATA;
583 put_unaligned_le16(packet_size, &pkt_buf[CMD_INDEX_OFFSET]);
584 put_unaligned_le32(address, &pkt_buf[CMD_LENGTH_OFFSET]);
585 memcpy(&pkt_buf[CMD_DATA_OFFSET], data, packet_size);
586
587 error = wdt87xx_set_feature(client, pkt_buf, sizeof(pkt_buf));
588 if (error)
589 return error;
590
591 length -= packet_size;
592 data += packet_size;
593 address += packet_size;
594
595 /* Wait for the controller to finish the write */
596 mdelay(WDT_FLASH_WRITE_DELAY_MS);
597
598 if ((++count % 32) == 0) {
599 /* Delay for fw to clear watch dog */
600 msleep(20);
601 }
602 }
603
604 return 0;
605}
606
607static u16 misr(u16 cur_value, u8 new_value)
608{
609 u32 a, b;
610 u32 bit0;
611 u32 y;
612
613 a = cur_value;
614 b = new_value;
615 bit0 = a ^ (b & 1);
616 bit0 ^= a >> 1;
617 bit0 ^= a >> 2;
618 bit0 ^= a >> 4;
619 bit0 ^= a >> 5;
620 bit0 ^= a >> 7;
621 bit0 ^= a >> 11;
622 bit0 ^= a >> 15;
623 y = (a << 1) ^ b;
624 y = (y & ~1) | (bit0 & 1);
625
626 return (u16)y;
627}
628
629static u16 wdt87xx_calculate_checksum(const u8 *data, size_t length)
630{
631 u16 checksum = 0;
632 size_t i;
633
634 for (i = 0; i < length; i++)
635 checksum = misr(checksum, data[i]);
636
637 return checksum;
638}
639
640static int wdt87xx_get_checksum(struct i2c_client *client, u16 *checksum,
641 u32 address, int length)
642{
643 int error;
644 int time_delay;
645 u8 pkt_buf[PKT_BUF_SIZE];
646 u8 cmd_buf[CMD_BUF_SIZE];
647
648 error = wdt87xx_send_command(client, VND_SET_CHECKSUM_LENGTH, length);
649 if (error) {
650 dev_err(&client->dev, "failed to set checksum length\n");
651 return error;
652 }
653
654 error = wdt87xx_send_command(client, VND_SET_CHECKSUM_CALC, address);
655 if (error) {
656 dev_err(&client->dev, "failed to set checksum address\n");
657 return error;
658 }
659
660 /* Wait the operation to complete */
661 time_delay = DIV_ROUND_UP(length, 1024);
662 msleep(time_delay * 30);
663
664 memset(cmd_buf, 0, sizeof(cmd_buf));
665 cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_READ;
666 cmd_buf[CMD_TYPE_OFFSET] = VND_GET_CHECKSUM;
667 error = wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
668 if (error) {
669 dev_err(&client->dev, "failed to request checksum\n");
670 return error;
671 }
672
673 memset(pkt_buf, 0, sizeof(pkt_buf));
674 pkt_buf[CMD_REPORT_ID_OFFSET] = VND_READ_DATA;
675 error = wdt87xx_get_feature(client, pkt_buf, sizeof(pkt_buf));
676 if (error) {
677 dev_err(&client->dev, "failed to read checksum\n");
678 return error;
679 }
680
681 *checksum = get_unaligned_le16(&pkt_buf[CMD_DATA_OFFSET]);
682 return 0;
683}
684
685static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
686{
687 u32 start_addr = get_unaligned_le32(chunk + FW_CHUNK_TGT_START_OFFSET);
688 u32 size = get_unaligned_le32(chunk + FW_CHUNK_PAYLOAD_LEN_OFFSET);
689 const void *data = chunk + FW_CHUNK_PAYLOAD_OFFSET;
690 int error;
691 int err1;
692 int page_size;
693 int retry = 0;
694 u16 device_checksum, firmware_checksum;
695
696 dev_dbg(&client->dev, "start 4k page program\n");
697
698 error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_STOP);
699 if (error) {
700 dev_err(&client->dev, "stop report mode failed\n");
701 return error;
702 }
703
704 error = wdt87xx_send_command(client, VND_CMD_SFUNL, 0);
705 if (error) {
706 dev_err(&client->dev, "unlock failed\n");
707 goto out_enable_reporting;
708 }
709
710 mdelay(10);
711
712 while (size) {
713 dev_dbg(&client->dev, "%s: %x, %x\n", __func__,
714 start_addr, size);
715
716 page_size = min_t(u32, size, PG_SIZE);
717 size -= page_size;
718
719 for (retry = 0; retry < MAX_RETRIES; retry++) {
720 error = wdt87xx_send_command(client, VND_CMD_ERASE,
721 start_addr);
722 if (error) {
723 dev_err(&client->dev,
724 "erase failed at %#08x\n", start_addr);
725 break;
726 }
727
728 msleep(50);
729
730 error = wdt87xx_write_data(client, data, start_addr,
731 page_size);
732 if (error) {
733 dev_err(&client->dev,
734 "write failed at %#08x (%d bytes)\n",
735 start_addr, page_size);
736 break;
737 }
738
739 error = wdt87xx_get_checksum(client, &device_checksum,
740 start_addr, page_size);
741 if (error) {
742 dev_err(&client->dev,
743 "failed to retrieve checksum for %#08x (len: %d)\n",
744 start_addr, page_size);
745 break;
746 }
747
748 firmware_checksum =
749 wdt87xx_calculate_checksum(data, page_size);
750
751 if (device_checksum == firmware_checksum)
752 break;
753
754 dev_err(&client->dev,
755 "checksum fail: %d vs %d, retry %d\n",
756 device_checksum, firmware_checksum, retry);
757 }
758
759 if (retry == MAX_RETRIES) {
760 dev_err(&client->dev, "page write failed\n");
761 error = -EIO;
762 goto out_lock_device;
763 }
764
765 start_addr = start_addr + page_size;
766 data = data + page_size;
767 }
768
769out_lock_device:
770 err1 = wdt87xx_send_command(client, VND_CMD_SFLCK, 0);
771 if (err1)
772 dev_err(&client->dev, "lock failed\n");
773
774 mdelay(10);
775
776out_enable_reporting:
777 err1 = wdt87xx_send_command(client, VND_CMD_START, 0);
778 if (err1)
779 dev_err(&client->dev, "start to report failed\n");
780
781 return error ? error : err1;
782}
783
784static int wdt87xx_load_chunk(struct i2c_client *client,
785 const struct firmware *fw, u32 ck_id)
786{
787 const void *chunk;
788 int error;
789
790 chunk = wdt87xx_get_fw_chunk(fw, ck_id);
791 if (!chunk) {
792 dev_err(&client->dev, "unable to locate chunk (type %d)\n",
793 ck_id);
794 return -EINVAL;
795 }
796
797 error = wdt87xx_validate_fw_chunk(chunk, ck_id);
798 if (error) {
799 dev_err(&client->dev, "invalid chunk (type %d): %d\n",
800 ck_id, error);
801 return error;
802 }
803
804 error = wdt87xx_write_firmware(client, chunk);
805 if (error) {
806 dev_err(&client->dev,
807 "failed to write fw chunk (type %d): %d\n",
808 ck_id, error);
809 return error;
810 }
811
812 return 0;
813}
814
815static int wdt87xx_do_update_firmware(struct i2c_client *client,
816 const struct firmware *fw,
817 unsigned int chunk_id)
818{
819 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
820 int error;
821
822 error = wdt87xx_validate_firmware(wdt, fw);
823 if (error)
824 return error;
825
826 error = mutex_lock_interruptible(&wdt->fw_mutex);
827 if (error)
828 return error;
829
830 disable_irq(client->irq);
831
832 error = wdt87xx_load_chunk(client, fw, chunk_id);
833 if (error) {
834 dev_err(&client->dev,
835 "firmware load failed (type: %d): %d\n",
836 chunk_id, error);
837 goto out;
838 }
839
840 error = wdt87xx_sw_reset(client);
841 if (error) {
842 dev_err(&client->dev, "soft reset failed: %d\n", error);
843 goto out;
844 }
845
846 /* Refresh the parameters */
847 error = wdt87xx_get_sysparam(client, &wdt->param);
848 if (error)
849 dev_err(&client->dev,
850 "failed to refresh system paramaters: %d\n", error);
851out:
852 enable_irq(client->irq);
853 mutex_unlock(&wdt->fw_mutex);
854
855 return error ? error : 0;
856}
857
858static int wdt87xx_update_firmware(struct device *dev,
859 const char *fw_name, unsigned int chunk_id)
860{
861 struct i2c_client *client = to_i2c_client(dev);
862 const struct firmware *fw;
863 int error;
864
865 error = request_firmware(&fw, fw_name, dev);
866 if (error) {
867 dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
868 fw_name, error);
869 return error;
870 }
871
872 error = wdt87xx_do_update_firmware(client, fw, chunk_id);
873
874 release_firmware(fw);
875
876 return error ? error : 0;
877}
878
879static ssize_t config_csum_show(struct device *dev,
880 struct device_attribute *attr, char *buf)
881{
882 struct i2c_client *client = to_i2c_client(dev);
883 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
884 u32 cfg_csum;
885
886 cfg_csum = wdt->param.xmls_id1;
887 cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;
888
889 return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
890}
891
892static ssize_t fw_version_show(struct device *dev,
893 struct device_attribute *attr, char *buf)
894{
895 struct i2c_client *client = to_i2c_client(dev);
896 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
897
898 return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
899}
900
901static ssize_t plat_id_show(struct device *dev,
902 struct device_attribute *attr, char *buf)
903{
904 struct i2c_client *client = to_i2c_client(dev);
905 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
906
907 return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
908}
909
910static ssize_t update_config_store(struct device *dev,
911 struct device_attribute *attr,
912 const char *buf, size_t count)
913{
914 int error;
915
916 error = wdt87xx_update_firmware(dev, WDT87XX_CFG_NAME, CHUNK_ID_CNFG);
917
918 return error ? error : count;
919}
920
921static ssize_t update_fw_store(struct device *dev,
922 struct device_attribute *attr,
923 const char *buf, size_t count)
924{
925 int error;
926
927 error = wdt87xx_update_firmware(dev, WDT87XX_FW_NAME, CHUNK_ID_FRWR);
928
929 return error ? error : count;
930}
931
932static DEVICE_ATTR_RO(config_csum);
933static DEVICE_ATTR_RO(fw_version);
934static DEVICE_ATTR_RO(plat_id);
935static DEVICE_ATTR_WO(update_config);
936static DEVICE_ATTR_WO(update_fw);
937
938static struct attribute *wdt87xx_attrs[] = {
939 &dev_attr_config_csum.attr,
940 &dev_attr_fw_version.attr,
941 &dev_attr_plat_id.attr,
942 &dev_attr_update_config.attr,
943 &dev_attr_update_fw.attr,
944 NULL
945};
946
947static const struct attribute_group wdt87xx_attr_group = {
948 .attrs = wdt87xx_attrs,
949};
950
951static void wdt87xx_report_contact(struct input_dev *input,
952 struct wdt87xx_sys_param *param,
953 u8 *buf)
954{
955 int finger_id;
d55d0b56
HC
956 u32 x, y, w;
957 u8 p;
3e30c11c
HC
958
959 finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1;
960 if (finger_id < 0)
961 return;
962
963 /* Check if this is an active contact */
964 if (!(buf[FINGER_EV_V1_OFFSET_ID] & 0x1))
965 return;
966
967 w = buf[FINGER_EV_V1_OFFSET_W];
d55d0b56
HC
968 w *= param->scaling_factor;
969
3e30c11c
HC
970 p = buf[FINGER_EV_V1_OFFSET_P];
971
972 x = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_X);
973
974 y = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_Y);
975 y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w);
976
977 /* Refuse incorrect coordinates */
978 if (x > param->max_x || y > param->max_y)
979 return;
980
981 dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n",
982 finger_id, x, y);
983
984 input_mt_slot(input, finger_id);
985 input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
986 input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
987 input_report_abs(input, ABS_MT_PRESSURE, p);
988 input_report_abs(input, ABS_MT_POSITION_X, x);
989 input_report_abs(input, ABS_MT_POSITION_Y, y);
990}
991
992static irqreturn_t wdt87xx_ts_interrupt(int irq, void *dev_id)
993{
994 struct wdt87xx_data *wdt = dev_id;
995 struct i2c_client *client = wdt->client;
996 int i, fingers;
997 int error;
998 u8 raw_buf[WDT_V1_RAW_BUF_COUNT] = {0};
999
1000 error = i2c_master_recv(client, raw_buf, WDT_V1_RAW_BUF_COUNT);
1001 if (error < 0) {
1002 dev_err(&client->dev, "read v1 raw data failed: %d\n", error);
1003 goto irq_exit;
1004 }
1005
1006 fingers = raw_buf[TOUCH_PK_V1_OFFSET_FNGR_NUM];
1007 if (!fingers)
1008 goto irq_exit;
1009
1010 for (i = 0; i < WDT_MAX_FINGER; i++)
1011 wdt87xx_report_contact(wdt->input,
1012 &wdt->param,
1013 &raw_buf[TOUCH_PK_V1_OFFSET_EVENT +
1014 i * FINGER_EV_V1_SIZE]);
1015
1016 input_mt_sync_frame(wdt->input);
1017 input_sync(wdt->input);
1018
1019irq_exit:
1020 return IRQ_HANDLED;
1021}
1022
1023static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt)
1024{
1025 struct device *dev = &wdt->client->dev;
1026 struct input_dev *input;
1027 unsigned int res = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS, wdt->param.phy_w);
1028 int error;
1029
1030 input = devm_input_allocate_device(dev);
1031 if (!input) {
1032 dev_err(dev, "failed to allocate input device\n");
1033 return -ENOMEM;
1034 }
1035 wdt->input = input;
1036
1037 input->name = "WDT87xx Touchscreen";
1038 input->id.bustype = BUS_I2C;
d5ebe37e
HC
1039 input->id.vendor = wdt->param.vendor_id;
1040 input->id.product = wdt->param.product_id;
3e30c11c
HC
1041 input->phys = wdt->phys;
1042
1043 input_set_abs_params(input, ABS_MT_POSITION_X, 0,
1044 wdt->param.max_x, 0, 0);
1045 input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
1046 wdt->param.max_y, 0, 0);
1047 input_abs_set_res(input, ABS_MT_POSITION_X, res);
1048 input_abs_set_res(input, ABS_MT_POSITION_Y, res);
1049
d55d0b56
HC
1050 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
1051 0, wdt->param.max_x, 0, 0);
3e30c11c
HC
1052 input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
1053
1054 input_mt_init_slots(input, WDT_MAX_FINGER,
1055 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
1056
1057 error = input_register_device(input);
1058 if (error) {
1059 dev_err(dev, "failed to register input device: %d\n", error);
1060 return error;
1061 }
1062
1063 return 0;
1064}
1065
1066static int wdt87xx_ts_probe(struct i2c_client *client,
1067 const struct i2c_device_id *id)
1068{
1069 struct wdt87xx_data *wdt;
1070 int error;
1071
1072 dev_dbg(&client->dev, "adapter=%d, client irq: %d\n",
1073 client->adapter->nr, client->irq);
1074
1075 /* Check if the I2C function is ok in this adaptor */
1076 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
1077 return -ENXIO;
1078
1079 wdt = devm_kzalloc(&client->dev, sizeof(*wdt), GFP_KERNEL);
1080 if (!wdt)
1081 return -ENOMEM;
1082
1083 wdt->client = client;
1084 mutex_init(&wdt->fw_mutex);
1085 i2c_set_clientdata(client, wdt);
1086
1087 snprintf(wdt->phys, sizeof(wdt->phys), "i2c-%u-%04x/input0",
1088 client->adapter->nr, client->addr);
1089
1090 error = wdt87xx_get_sysparam(client, &wdt->param);
1091 if (error)
1092 return error;
1093
1094 error = wdt87xx_ts_create_input_device(wdt);
1095 if (error)
1096 return error;
1097
1098 error = devm_request_threaded_irq(&client->dev, client->irq,
1099 NULL, wdt87xx_ts_interrupt,
1100 IRQF_ONESHOT,
1101 client->name, wdt);
1102 if (error) {
1103 dev_err(&client->dev, "request irq failed: %d\n", error);
1104 return error;
1105 }
1106
1107 error = sysfs_create_group(&client->dev.kobj, &wdt87xx_attr_group);
1108 if (error) {
1109 dev_err(&client->dev, "create sysfs failed: %d\n", error);
1110 return error;
1111 }
1112
1113 return 0;
1114}
1115
1116static int wdt87xx_ts_remove(struct i2c_client *client)
1117{
1118 sysfs_remove_group(&client->dev.kobj, &wdt87xx_attr_group);
1119
1120 return 0;
1121}
1122
1123static int __maybe_unused wdt87xx_suspend(struct device *dev)
1124{
1125 struct i2c_client *client = to_i2c_client(dev);
1126 int error;
1127
1128 disable_irq(client->irq);
1129
1130 error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_IDLE);
1131 if (error) {
1132 enable_irq(client->irq);
1133 dev_err(&client->dev,
1134 "failed to stop device when suspending: %d\n",
1135 error);
1136 return error;
1137 }
1138
1139 return 0;
1140}
1141
1142static int __maybe_unused wdt87xx_resume(struct device *dev)
1143{
1144 struct i2c_client *client = to_i2c_client(dev);
1145 int error;
1146
1147 /*
1148 * The chip may have been reset while system is resuming,
1149 * give it some time to settle.
1150 */
1151 mdelay(100);
1152
1153 error = wdt87xx_send_command(client, VND_CMD_START, 0);
1154 if (error)
1155 dev_err(&client->dev,
1156 "failed to start device when resuming: %d\n",
1157 error);
1158
1159 enable_irq(client->irq);
1160
1161 return 0;
1162}
1163
1164static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops, wdt87xx_suspend, wdt87xx_resume);
1165
1166static const struct i2c_device_id wdt87xx_dev_id[] = {
1167 { WDT87XX_NAME, 0 },
1168 { }
1169};
1170MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);
1171
1172static const struct acpi_device_id wdt87xx_acpi_id[] = {
1173 { "WDHT0001", 0 },
1174 { }
1175};
1176MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);
1177
1178static struct i2c_driver wdt87xx_driver = {
1179 .probe = wdt87xx_ts_probe,
1180 .remove = wdt87xx_ts_remove,
1181 .id_table = wdt87xx_dev_id,
1182 .driver = {
1183 .name = WDT87XX_NAME,
1184 .pm = &wdt87xx_pm_ops,
1185 .acpi_match_table = ACPI_PTR(wdt87xx_acpi_id),
1186 },
1187};
1188module_i2c_driver(wdt87xx_driver);
1189
1190MODULE_AUTHOR("HN Chen <hn.chen@weidahitech.com>");
1191MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver");
1192MODULE_VERSION(WDT87XX_DRV_VER);
1193MODULE_LICENSE("GPL");