Input: wdt87xx_i2c - add a scaling factor for TOUCH_MAJOR event
[deliverable/linux.git] / drivers / input / touchscreen / wdt87xx_i2c.c
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"
26 #define WDT87XX_DRV_VER "0.9.6"
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
86 #define CTL_PARAM_OFFSET_FACTOR 32
87
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
93
94 #define VND_CMD_START 0x00
95 #define VND_CMD_STOP 0x01
96 #define VND_CMD_RESET 0x09
97
98 #define VND_CMD_ERASE 0x1A
99
100 #define VND_GET_CHECKSUM 0x66
101
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
106
107 #define VND_CMD_SFLCK 0xFC
108 #define VND_CMD_SFUNL 0xFD
109
110 #define CMD_SFLCK_KEY 0xC39B
111 #define CMD_SFUNL_KEY 0x95DA
112
113 #define STRIDX_PLATFORM_ID 0x80
114 #define STRIDX_PARAMETERS 0x81
115
116 #define CMD_BUF_SIZE 8
117 #define PKT_BUF_SIZE 64
118
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
126
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
133
134 #define CHUNK_ID_FRMT FOURCC_ID_FRMT
135 #define CHUNK_ID_FRWR FOURCC_ID_FRWR
136 #define CHUNK_ID_CNFG FOURCC_ID_CNFG
137
138 #define FW_FOURCC1_OFFSET 0
139 #define FW_SIZE_OFFSET 4
140 #define FW_FOURCC2_OFFSET 8
141 #define FW_PAYLOAD_OFFSET 40
142
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
151
152 /* Controller requires minimum 300us between commands */
153 #define WDT_COMMAND_DELAY_MS 2
154 #define WDT_FLASH_WRITE_DELAY_MS 4
155
156 struct wdt87xx_sys_param {
157 u16 fw_id;
158 u16 plat_id;
159 u16 xmls_id1;
160 u16 xmls_id2;
161 u16 phy_ch_x;
162 u16 phy_ch_y;
163 u16 phy_w;
164 u16 phy_h;
165 u16 scaling_factor;
166 u32 max_x;
167 u32 max_y;
168 };
169
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;
176 u8 phys[32];
177 };
178
179 static int wdt87xx_i2c_xfer(struct i2c_client *client,
180 void *txdata, size_t txlen,
181 void *rxdata, size_t rxlen)
182 {
183 struct i2c_msg msgs[] = {
184 {
185 .addr = client->addr,
186 .flags = 0,
187 .len = txlen,
188 .buf = txdata,
189 },
190 {
191 .addr = client->addr,
192 .flags = I2C_M_RD,
193 .len = rxlen,
194 .buf = rxdata,
195 },
196 };
197 int error;
198 int ret;
199
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",
204 __func__, error);
205 return error;
206 }
207
208 return 0;
209 }
210
211 static int wdt87xx_get_string(struct i2c_client *client, u8 str_idx,
212 u8 *buf, size_t len)
213 {
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;
217 int error;
218
219 if (rx_len > sizeof(rx_buf))
220 return -EINVAL;
221
222 error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
223 rx_buf, rx_len);
224 if (error) {
225 dev_err(&client->dev, "get string failed: %d\n", error);
226 return error;
227 }
228
229 if (rx_buf[1] != 0x03) {
230 dev_err(&client->dev, "unexpected response to get string: %d\n",
231 rx_buf[1]);
232 return -EINVAL;
233 }
234
235 rx_len = min_t(size_t, len, rx_buf[0]);
236 memcpy(buf, &rx_buf[2], rx_len);
237
238 mdelay(WDT_COMMAND_DELAY_MS);
239
240 return 0;
241 }
242
243 static int wdt87xx_get_feature(struct i2c_client *client,
244 u8 *buf, size_t buf_size)
245 {
246 u8 tx_buf[8];
247 u8 rx_buf[PKT_WRITE_SIZE];
248 size_t tx_len = 0;
249 size_t rx_len = buf_size + 2;
250 int error;
251
252 if (rx_len > sizeof(rx_buf))
253 return -EINVAL;
254
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];
262 } else {
263 tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
264 tx_buf[tx_len++] = 0x02;
265 }
266 tx_buf[tx_len++] = 0x23;
267 tx_buf[tx_len++] = 0x00;
268
269 error = wdt87xx_i2c_xfer(client, tx_buf, tx_len, rx_buf, rx_len);
270 if (error) {
271 dev_err(&client->dev, "get feature failed: %d\n", error);
272 return error;
273 }
274
275 rx_len = min_t(size_t, buf_size, get_unaligned_le16(rx_buf));
276 memcpy(buf, &rx_buf[2], rx_len);
277
278 mdelay(WDT_COMMAND_DELAY_MS);
279
280 return 0;
281 }
282
283 static int wdt87xx_set_feature(struct i2c_client *client,
284 const u8 *buf, size_t buf_size)
285 {
286 u8 tx_buf[PKT_WRITE_SIZE];
287 int tx_len = 0;
288 int error;
289
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];
297 } else {
298 tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
299 tx_buf[tx_len++] = 0x03;
300 }
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);
305
306 if (tx_len + buf_size > sizeof(tx_buf))
307 return -EINVAL;
308
309 memcpy(&tx_buf[tx_len], buf, buf_size);
310 tx_len += buf_size;
311
312 error = i2c_master_send(client, tx_buf, tx_len);
313 if (error < 0) {
314 dev_err(&client->dev, "set feature failed: %d\n", error);
315 return error;
316 }
317
318 mdelay(WDT_COMMAND_DELAY_MS);
319
320 return 0;
321 }
322
323 static int wdt87xx_send_command(struct i2c_client *client, int cmd, int value)
324 {
325 u8 cmd_buf[CMD_BUF_SIZE];
326
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]);
331
332 switch (cmd) {
333 case VND_CMD_START:
334 case VND_CMD_STOP:
335 case VND_CMD_RESET:
336 /* Mode selector */
337 put_unaligned_le32((value & 0xFF), &cmd_buf[CMD_LENGTH_OFFSET]);
338 break;
339
340 case VND_CMD_SFLCK:
341 put_unaligned_le16(CMD_SFLCK_KEY, &cmd_buf[CMD_KEY_OFFSET]);
342 break;
343
344 case VND_CMD_SFUNL:
345 put_unaligned_le16(CMD_SFUNL_KEY, &cmd_buf[CMD_KEY_OFFSET]);
346 break;
347
348 case VND_CMD_ERASE:
349 case VND_SET_CHECKSUM_CALC:
350 case VND_SET_CHECKSUM_LENGTH:
351 put_unaligned_le32(value, &cmd_buf[CMD_KEY_OFFSET]);
352 break;
353
354 default:
355 cmd_buf[CMD_REPORT_ID_OFFSET] = 0;
356 dev_err(&client->dev, "Invalid command: %d\n", cmd);
357 return -EINVAL;
358 }
359
360 return wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
361 }
362
363 static int wdt87xx_sw_reset(struct i2c_client *client)
364 {
365 int error;
366
367 dev_dbg(&client->dev, "resetting device now\n");
368
369 error = wdt87xx_send_command(client, VND_CMD_RESET, 0);
370 if (error) {
371 dev_err(&client->dev, "reset failed\n");
372 return error;
373 }
374
375 /* Wait the device to be ready */
376 msleep(200);
377
378 return 0;
379 }
380
381 static const void *wdt87xx_get_fw_chunk(const struct firmware *fw, u32 id)
382 {
383 size_t pos = FW_PAYLOAD_OFFSET;
384 u32 chunk_id, chunk_size;
385
386 while (pos < fw->size) {
387 chunk_id = get_unaligned_le32(fw->data +
388 pos + FW_CHUNK_ID_OFFSET);
389 if (chunk_id == id)
390 return fw->data + pos;
391
392 chunk_size = get_unaligned_le32(fw->data +
393 pos + FW_CHUNK_SIZE_OFFSET);
394 pos += chunk_size + 2 * sizeof(u32); /* chunk ID + size */
395 }
396
397 return NULL;
398 }
399
400 static int wdt87xx_get_sysparam(struct i2c_client *client,
401 struct wdt87xx_sys_param *param)
402 {
403 u8 buf[PKT_READ_SIZE];
404 int error;
405
406 error = wdt87xx_get_string(client, STRIDX_PARAMETERS, buf, 34);
407 if (error) {
408 dev_err(&client->dev, "failed to get parameters\n");
409 return error;
410 }
411
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;
418
419 /* Get the scaling factor of pixel to logical coordinate */
420 param->scaling_factor =
421 get_unaligned_le16(buf + CTL_PARAM_OFFSET_FACTOR);
422
423 param->max_x = MAX_UNIT_AXIS;
424 param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h,
425 param->phy_w);
426
427 error = wdt87xx_get_string(client, STRIDX_PLATFORM_ID, buf, 8);
428 if (error) {
429 dev_err(&client->dev, "failed to get platform id\n");
430 return error;
431 }
432
433 param->plat_id = buf[1];
434
435 buf[0] = 0xf2;
436 error = wdt87xx_get_feature(client, buf, 16);
437 if (error) {
438 dev_err(&client->dev, "failed to get firmware id\n");
439 return error;
440 }
441
442 if (buf[0] != 0xf2) {
443 dev_err(&client->dev, "wrong id of fw response: 0x%x\n",
444 buf[0]);
445 return -EINVAL;
446 }
447
448 param->fw_id = get_unaligned_le16(&buf[1]);
449
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);
454
455 return 0;
456 }
457
458 static int wdt87xx_validate_firmware(struct wdt87xx_data *wdt,
459 const struct firmware *fw)
460 {
461 const void *fw_chunk;
462 u32 data1, data2;
463 u32 size;
464 u8 fw_chip_id;
465 u8 chip_id;
466
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");
471 return -EINVAL;
472 }
473
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",
478 size, fw->size);
479 return -EINVAL;
480 }
481
482 /*
483 * Get the chip_id from the firmware. Make sure that it is the
484 * right controller to do the firmware and config update.
485 */
486 fw_chunk = wdt87xx_get_fw_chunk(fw, CHUNK_ID_FRWR);
487 if (!fw_chunk) {
488 dev_err(&wdt->client->dev,
489 "unable to locate firmware chunk\n");
490 return -EINVAL;
491 }
492
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;
496
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);
501 return -ENODEV;
502 }
503
504 return 0;
505 }
506
507 static int wdt87xx_validate_fw_chunk(const void *data, int id)
508 {
509 if (id == CHUNK_ID_FRWR) {
510 u32 fw_id;
511
512 fw_id = get_unaligned_le32(data + FW_CHUNK_PAYLOAD_OFFSET);
513 if (fw_id != WDT_FIRMWARE_ID)
514 return -EINVAL;
515 }
516
517 return 0;
518 }
519
520 static int wdt87xx_write_data(struct i2c_client *client, const char *data,
521 u32 address, int length)
522 {
523 u16 packet_size;
524 int count = 0;
525 int error;
526 u8 pkt_buf[PKT_BUF_SIZE];
527
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",
532 address, length);
533 return -EINVAL;
534 }
535
536 while (length) {
537 packet_size = min(length, PACKET_SIZE);
538
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);
544
545 error = wdt87xx_set_feature(client, pkt_buf, sizeof(pkt_buf));
546 if (error)
547 return error;
548
549 length -= packet_size;
550 data += packet_size;
551 address += packet_size;
552
553 /* Wait for the controller to finish the write */
554 mdelay(WDT_FLASH_WRITE_DELAY_MS);
555
556 if ((++count % 32) == 0) {
557 /* Delay for fw to clear watch dog */
558 msleep(20);
559 }
560 }
561
562 return 0;
563 }
564
565 static u16 misr(u16 cur_value, u8 new_value)
566 {
567 u32 a, b;
568 u32 bit0;
569 u32 y;
570
571 a = cur_value;
572 b = new_value;
573 bit0 = a ^ (b & 1);
574 bit0 ^= a >> 1;
575 bit0 ^= a >> 2;
576 bit0 ^= a >> 4;
577 bit0 ^= a >> 5;
578 bit0 ^= a >> 7;
579 bit0 ^= a >> 11;
580 bit0 ^= a >> 15;
581 y = (a << 1) ^ b;
582 y = (y & ~1) | (bit0 & 1);
583
584 return (u16)y;
585 }
586
587 static u16 wdt87xx_calculate_checksum(const u8 *data, size_t length)
588 {
589 u16 checksum = 0;
590 size_t i;
591
592 for (i = 0; i < length; i++)
593 checksum = misr(checksum, data[i]);
594
595 return checksum;
596 }
597
598 static int wdt87xx_get_checksum(struct i2c_client *client, u16 *checksum,
599 u32 address, int length)
600 {
601 int error;
602 int time_delay;
603 u8 pkt_buf[PKT_BUF_SIZE];
604 u8 cmd_buf[CMD_BUF_SIZE];
605
606 error = wdt87xx_send_command(client, VND_SET_CHECKSUM_LENGTH, length);
607 if (error) {
608 dev_err(&client->dev, "failed to set checksum length\n");
609 return error;
610 }
611
612 error = wdt87xx_send_command(client, VND_SET_CHECKSUM_CALC, address);
613 if (error) {
614 dev_err(&client->dev, "failed to set checksum address\n");
615 return error;
616 }
617
618 /* Wait the operation to complete */
619 time_delay = DIV_ROUND_UP(length, 1024);
620 msleep(time_delay * 30);
621
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));
626 if (error) {
627 dev_err(&client->dev, "failed to request checksum\n");
628 return error;
629 }
630
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));
634 if (error) {
635 dev_err(&client->dev, "failed to read checksum\n");
636 return error;
637 }
638
639 *checksum = get_unaligned_le16(&pkt_buf[CMD_DATA_OFFSET]);
640 return 0;
641 }
642
643 static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
644 {
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;
648 int error;
649 int err1;
650 int page_size;
651 int retry = 0;
652 u16 device_checksum, firmware_checksum;
653
654 dev_dbg(&client->dev, "start 4k page program\n");
655
656 error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_STOP);
657 if (error) {
658 dev_err(&client->dev, "stop report mode failed\n");
659 return error;
660 }
661
662 error = wdt87xx_send_command(client, VND_CMD_SFUNL, 0);
663 if (error) {
664 dev_err(&client->dev, "unlock failed\n");
665 goto out_enable_reporting;
666 }
667
668 mdelay(10);
669
670 while (size) {
671 dev_dbg(&client->dev, "%s: %x, %x\n", __func__,
672 start_addr, size);
673
674 page_size = min_t(u32, size, PG_SIZE);
675 size -= page_size;
676
677 for (retry = 0; retry < MAX_RETRIES; retry++) {
678 error = wdt87xx_send_command(client, VND_CMD_ERASE,
679 start_addr);
680 if (error) {
681 dev_err(&client->dev,
682 "erase failed at %#08x\n", start_addr);
683 break;
684 }
685
686 msleep(50);
687
688 error = wdt87xx_write_data(client, data, start_addr,
689 page_size);
690 if (error) {
691 dev_err(&client->dev,
692 "write failed at %#08x (%d bytes)\n",
693 start_addr, page_size);
694 break;
695 }
696
697 error = wdt87xx_get_checksum(client, &device_checksum,
698 start_addr, page_size);
699 if (error) {
700 dev_err(&client->dev,
701 "failed to retrieve checksum for %#08x (len: %d)\n",
702 start_addr, page_size);
703 break;
704 }
705
706 firmware_checksum =
707 wdt87xx_calculate_checksum(data, page_size);
708
709 if (device_checksum == firmware_checksum)
710 break;
711
712 dev_err(&client->dev,
713 "checksum fail: %d vs %d, retry %d\n",
714 device_checksum, firmware_checksum, retry);
715 }
716
717 if (retry == MAX_RETRIES) {
718 dev_err(&client->dev, "page write failed\n");
719 error = -EIO;
720 goto out_lock_device;
721 }
722
723 start_addr = start_addr + page_size;
724 data = data + page_size;
725 }
726
727 out_lock_device:
728 err1 = wdt87xx_send_command(client, VND_CMD_SFLCK, 0);
729 if (err1)
730 dev_err(&client->dev, "lock failed\n");
731
732 mdelay(10);
733
734 out_enable_reporting:
735 err1 = wdt87xx_send_command(client, VND_CMD_START, 0);
736 if (err1)
737 dev_err(&client->dev, "start to report failed\n");
738
739 return error ? error : err1;
740 }
741
742 static int wdt87xx_load_chunk(struct i2c_client *client,
743 const struct firmware *fw, u32 ck_id)
744 {
745 const void *chunk;
746 int error;
747
748 chunk = wdt87xx_get_fw_chunk(fw, ck_id);
749 if (!chunk) {
750 dev_err(&client->dev, "unable to locate chunk (type %d)\n",
751 ck_id);
752 return -EINVAL;
753 }
754
755 error = wdt87xx_validate_fw_chunk(chunk, ck_id);
756 if (error) {
757 dev_err(&client->dev, "invalid chunk (type %d): %d\n",
758 ck_id, error);
759 return error;
760 }
761
762 error = wdt87xx_write_firmware(client, chunk);
763 if (error) {
764 dev_err(&client->dev,
765 "failed to write fw chunk (type %d): %d\n",
766 ck_id, error);
767 return error;
768 }
769
770 return 0;
771 }
772
773 static int wdt87xx_do_update_firmware(struct i2c_client *client,
774 const struct firmware *fw,
775 unsigned int chunk_id)
776 {
777 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
778 int error;
779
780 error = wdt87xx_validate_firmware(wdt, fw);
781 if (error)
782 return error;
783
784 error = mutex_lock_interruptible(&wdt->fw_mutex);
785 if (error)
786 return error;
787
788 disable_irq(client->irq);
789
790 error = wdt87xx_load_chunk(client, fw, chunk_id);
791 if (error) {
792 dev_err(&client->dev,
793 "firmware load failed (type: %d): %d\n",
794 chunk_id, error);
795 goto out;
796 }
797
798 error = wdt87xx_sw_reset(client);
799 if (error) {
800 dev_err(&client->dev, "soft reset failed: %d\n", error);
801 goto out;
802 }
803
804 /* Refresh the parameters */
805 error = wdt87xx_get_sysparam(client, &wdt->param);
806 if (error)
807 dev_err(&client->dev,
808 "failed to refresh system paramaters: %d\n", error);
809 out:
810 enable_irq(client->irq);
811 mutex_unlock(&wdt->fw_mutex);
812
813 return error ? error : 0;
814 }
815
816 static int wdt87xx_update_firmware(struct device *dev,
817 const char *fw_name, unsigned int chunk_id)
818 {
819 struct i2c_client *client = to_i2c_client(dev);
820 const struct firmware *fw;
821 int error;
822
823 error = request_firmware(&fw, fw_name, dev);
824 if (error) {
825 dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
826 fw_name, error);
827 return error;
828 }
829
830 error = wdt87xx_do_update_firmware(client, fw, chunk_id);
831
832 release_firmware(fw);
833
834 return error ? error : 0;
835 }
836
837 static ssize_t config_csum_show(struct device *dev,
838 struct device_attribute *attr, char *buf)
839 {
840 struct i2c_client *client = to_i2c_client(dev);
841 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
842 u32 cfg_csum;
843
844 cfg_csum = wdt->param.xmls_id1;
845 cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;
846
847 return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
848 }
849
850 static ssize_t fw_version_show(struct device *dev,
851 struct device_attribute *attr, char *buf)
852 {
853 struct i2c_client *client = to_i2c_client(dev);
854 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
855
856 return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
857 }
858
859 static ssize_t plat_id_show(struct device *dev,
860 struct device_attribute *attr, char *buf)
861 {
862 struct i2c_client *client = to_i2c_client(dev);
863 struct wdt87xx_data *wdt = i2c_get_clientdata(client);
864
865 return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
866 }
867
868 static ssize_t update_config_store(struct device *dev,
869 struct device_attribute *attr,
870 const char *buf, size_t count)
871 {
872 int error;
873
874 error = wdt87xx_update_firmware(dev, WDT87XX_CFG_NAME, CHUNK_ID_CNFG);
875
876 return error ? error : count;
877 }
878
879 static ssize_t update_fw_store(struct device *dev,
880 struct device_attribute *attr,
881 const char *buf, size_t count)
882 {
883 int error;
884
885 error = wdt87xx_update_firmware(dev, WDT87XX_FW_NAME, CHUNK_ID_FRWR);
886
887 return error ? error : count;
888 }
889
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);
895
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,
902 NULL
903 };
904
905 static const struct attribute_group wdt87xx_attr_group = {
906 .attrs = wdt87xx_attrs,
907 };
908
909 static void wdt87xx_report_contact(struct input_dev *input,
910 struct wdt87xx_sys_param *param,
911 u8 *buf)
912 {
913 int finger_id;
914 u32 x, y, w;
915 u8 p;
916
917 finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1;
918 if (finger_id < 0)
919 return;
920
921 /* Check if this is an active contact */
922 if (!(buf[FINGER_EV_V1_OFFSET_ID] & 0x1))
923 return;
924
925 w = buf[FINGER_EV_V1_OFFSET_W];
926 w *= param->scaling_factor;
927
928 p = buf[FINGER_EV_V1_OFFSET_P];
929
930 x = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_X);
931
932 y = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_Y);
933 y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w);
934
935 /* Refuse incorrect coordinates */
936 if (x > param->max_x || y > param->max_y)
937 return;
938
939 dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n",
940 finger_id, x, y);
941
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);
948 }
949
950 static irqreturn_t wdt87xx_ts_interrupt(int irq, void *dev_id)
951 {
952 struct wdt87xx_data *wdt = dev_id;
953 struct i2c_client *client = wdt->client;
954 int i, fingers;
955 int error;
956 u8 raw_buf[WDT_V1_RAW_BUF_COUNT] = {0};
957
958 error = i2c_master_recv(client, raw_buf, WDT_V1_RAW_BUF_COUNT);
959 if (error < 0) {
960 dev_err(&client->dev, "read v1 raw data failed: %d\n", error);
961 goto irq_exit;
962 }
963
964 fingers = raw_buf[TOUCH_PK_V1_OFFSET_FNGR_NUM];
965 if (!fingers)
966 goto irq_exit;
967
968 for (i = 0; i < WDT_MAX_FINGER; i++)
969 wdt87xx_report_contact(wdt->input,
970 &wdt->param,
971 &raw_buf[TOUCH_PK_V1_OFFSET_EVENT +
972 i * FINGER_EV_V1_SIZE]);
973
974 input_mt_sync_frame(wdt->input);
975 input_sync(wdt->input);
976
977 irq_exit:
978 return IRQ_HANDLED;
979 }
980
981 static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt)
982 {
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);
986 int error;
987
988 input = devm_input_allocate_device(dev);
989 if (!input) {
990 dev_err(dev, "failed to allocate input device\n");
991 return -ENOMEM;
992 }
993 wdt->input = input;
994
995 input->name = "WDT87xx Touchscreen";
996 input->id.bustype = BUS_I2C;
997 input->phys = wdt->phys;
998
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);
1005
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);
1009
1010 input_mt_init_slots(input, WDT_MAX_FINGER,
1011 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
1012
1013 error = input_register_device(input);
1014 if (error) {
1015 dev_err(dev, "failed to register input device: %d\n", error);
1016 return error;
1017 }
1018
1019 return 0;
1020 }
1021
1022 static int wdt87xx_ts_probe(struct i2c_client *client,
1023 const struct i2c_device_id *id)
1024 {
1025 struct wdt87xx_data *wdt;
1026 int error;
1027
1028 dev_dbg(&client->dev, "adapter=%d, client irq: %d\n",
1029 client->adapter->nr, client->irq);
1030
1031 /* Check if the I2C function is ok in this adaptor */
1032 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
1033 return -ENXIO;
1034
1035 wdt = devm_kzalloc(&client->dev, sizeof(*wdt), GFP_KERNEL);
1036 if (!wdt)
1037 return -ENOMEM;
1038
1039 wdt->client = client;
1040 mutex_init(&wdt->fw_mutex);
1041 i2c_set_clientdata(client, wdt);
1042
1043 snprintf(wdt->phys, sizeof(wdt->phys), "i2c-%u-%04x/input0",
1044 client->adapter->nr, client->addr);
1045
1046 error = wdt87xx_get_sysparam(client, &wdt->param);
1047 if (error)
1048 return error;
1049
1050 error = wdt87xx_ts_create_input_device(wdt);
1051 if (error)
1052 return error;
1053
1054 error = devm_request_threaded_irq(&client->dev, client->irq,
1055 NULL, wdt87xx_ts_interrupt,
1056 IRQF_ONESHOT,
1057 client->name, wdt);
1058 if (error) {
1059 dev_err(&client->dev, "request irq failed: %d\n", error);
1060 return error;
1061 }
1062
1063 error = sysfs_create_group(&client->dev.kobj, &wdt87xx_attr_group);
1064 if (error) {
1065 dev_err(&client->dev, "create sysfs failed: %d\n", error);
1066 return error;
1067 }
1068
1069 return 0;
1070 }
1071
1072 static int wdt87xx_ts_remove(struct i2c_client *client)
1073 {
1074 sysfs_remove_group(&client->dev.kobj, &wdt87xx_attr_group);
1075
1076 return 0;
1077 }
1078
1079 static int __maybe_unused wdt87xx_suspend(struct device *dev)
1080 {
1081 struct i2c_client *client = to_i2c_client(dev);
1082 int error;
1083
1084 disable_irq(client->irq);
1085
1086 error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_IDLE);
1087 if (error) {
1088 enable_irq(client->irq);
1089 dev_err(&client->dev,
1090 "failed to stop device when suspending: %d\n",
1091 error);
1092 return error;
1093 }
1094
1095 return 0;
1096 }
1097
1098 static int __maybe_unused wdt87xx_resume(struct device *dev)
1099 {
1100 struct i2c_client *client = to_i2c_client(dev);
1101 int error;
1102
1103 /*
1104 * The chip may have been reset while system is resuming,
1105 * give it some time to settle.
1106 */
1107 mdelay(100);
1108
1109 error = wdt87xx_send_command(client, VND_CMD_START, 0);
1110 if (error)
1111 dev_err(&client->dev,
1112 "failed to start device when resuming: %d\n",
1113 error);
1114
1115 enable_irq(client->irq);
1116
1117 return 0;
1118 }
1119
1120 static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops, wdt87xx_suspend, wdt87xx_resume);
1121
1122 static const struct i2c_device_id wdt87xx_dev_id[] = {
1123 { WDT87XX_NAME, 0 },
1124 { }
1125 };
1126 MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);
1127
1128 static const struct acpi_device_id wdt87xx_acpi_id[] = {
1129 { "WDHT0001", 0 },
1130 { }
1131 };
1132 MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);
1133
1134 static struct i2c_driver wdt87xx_driver = {
1135 .probe = wdt87xx_ts_probe,
1136 .remove = wdt87xx_ts_remove,
1137 .id_table = wdt87xx_dev_id,
1138 .driver = {
1139 .name = WDT87XX_NAME,
1140 .pm = &wdt87xx_pm_ops,
1141 .acpi_match_table = ACPI_PTR(wdt87xx_acpi_id),
1142 },
1143 };
1144 module_i2c_driver(wdt87xx_driver);
1145
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");
This page took 0.082032 seconds and 5 git commands to generate.