5775d40b3d53994a754bd0f5a159adafbea65c3e
[releases.git] / cyapa_gen5.c
1 /*
2  * Cypress APA trackpad with I2C interface
3  *
4  * Author: Dudley Du <dudl@cypress.com>
5  *
6  * Copyright (C) 2014-2015 Cypress Semiconductor, Inc.
7  *
8  * This file is subject to the terms and conditions of the GNU General Public
9  * License.  See the file COPYING in the main directory of this archive for
10  * more details.
11  */
12
13 #include <linux/delay.h>
14 #include <linux/i2c.h>
15 #include <linux/input.h>
16 #include <linux/input/mt.h>
17 #include <linux/mutex.h>
18 #include <linux/completion.h>
19 #include <linux/slab.h>
20 #include <asm/unaligned.h>
21 #include <linux/crc-itu-t.h>
22 #include <linux/pm_runtime.h>
23 #include "cyapa.h"
24
25
26 /* Macro of TSG firmware image */
27 #define CYAPA_TSG_FLASH_MAP_BLOCK_SIZE      0x80
28 #define CYAPA_TSG_IMG_FW_HDR_SIZE           13
29 #define CYAPA_TSG_FW_ROW_SIZE               (CYAPA_TSG_FLASH_MAP_BLOCK_SIZE)
30 #define CYAPA_TSG_IMG_START_ROW_NUM         0x002e
31 #define CYAPA_TSG_IMG_END_ROW_NUM           0x01fe
32 #define CYAPA_TSG_IMG_APP_INTEGRITY_ROW_NUM 0x01ff
33 #define CYAPA_TSG_IMG_MAX_RECORDS           (CYAPA_TSG_IMG_END_ROW_NUM - \
34                                 CYAPA_TSG_IMG_START_ROW_NUM + 1 + 1)
35 #define CYAPA_TSG_IMG_READ_SIZE             (CYAPA_TSG_FLASH_MAP_BLOCK_SIZE / 2)
36 #define CYAPA_TSG_START_OF_APPLICATION      0x1700
37 #define CYAPA_TSG_APP_INTEGRITY_SIZE        60
38 #define CYAPA_TSG_FLASH_MAP_METADATA_SIZE   60
39 #define CYAPA_TSG_BL_KEY_SIZE               8
40
41 #define CYAPA_TSG_MAX_CMD_SIZE              256
42
43 /* Macro of PIP interface */
44 #define PIP_BL_INITIATE_RESP_LEN            11
45 #define PIP_BL_FAIL_EXIT_RESP_LEN           11
46 #define PIP_BL_FAIL_EXIT_STATUS_CODE        0x0c
47 #define PIP_BL_VERIFY_INTEGRITY_RESP_LEN    12
48 #define PIP_BL_INTEGRITY_CHEKC_PASS         0x00
49 #define PIP_BL_BLOCK_WRITE_RESP_LEN         11
50
51 #define PIP_TOUCH_REPORT_ID         0x01
52 #define PIP_BTN_REPORT_ID           0x03
53 #define PIP_WAKEUP_EVENT_REPORT_ID  0x04
54 #define PIP_PUSH_BTN_REPORT_ID      0x06
55 #define GEN5_OLD_PUSH_BTN_REPORT_ID 0x05  /* Special for old Gen5 TP. */
56 #define PIP_PROXIMITY_REPORT_ID     0x07
57
58 #define PIP_PROXIMITY_REPORT_SIZE       6
59 #define PIP_PROXIMITY_DISTANCE_OFFSET   0x05
60 #define PIP_PROXIMITY_DISTANCE_MASK     0x01
61
62 #define PIP_TOUCH_REPORT_HEAD_SIZE     7
63 #define PIP_TOUCH_REPORT_MAX_SIZE      127
64 #define PIP_BTN_REPORT_HEAD_SIZE       6
65 #define PIP_BTN_REPORT_MAX_SIZE        14
66 #define PIP_WAKEUP_EVENT_SIZE          4
67
68 #define PIP_NUMBER_OF_TOUCH_OFFSET  5
69 #define PIP_NUMBER_OF_TOUCH_MASK    0x1f
70 #define PIP_BUTTONS_OFFSET          5
71 #define PIP_BUTTONS_MASK            0x0f
72 #define PIP_GET_EVENT_ID(reg)       (((reg) >> 5) & 0x03)
73 #define PIP_GET_TOUCH_ID(reg)       ((reg) & 0x1f)
74 #define PIP_TOUCH_TYPE_FINGER       0x00
75 #define PIP_TOUCH_TYPE_PROXIMITY    0x01
76 #define PIP_TOUCH_TYPE_HOVER        0x02
77 #define PIP_GET_TOUCH_TYPE(reg)     ((reg) & 0x07)
78
79 #define RECORD_EVENT_NONE        0
80 #define RECORD_EVENT_TOUCHDOWN   1
81 #define RECORD_EVENT_DISPLACE    2
82 #define RECORD_EVENT_LIFTOFF     3
83
84 #define PIP_SENSING_MODE_MUTUAL_CAP_FINE   0x00
85 #define PIP_SENSING_MODE_SELF_CAP          0x02
86
87 #define PIP_SET_PROXIMITY       0x49
88
89 /* Macro of Gen5 */
90 #define GEN5_BL_MAX_OUTPUT_LENGTH     0x0100
91 #define GEN5_APP_MAX_OUTPUT_LENGTH    0x00fe
92
93 #define GEN5_POWER_STATE_ACTIVE              0x01
94 #define GEN5_POWER_STATE_LOOK_FOR_TOUCH      0x02
95 #define GEN5_POWER_STATE_READY               0x03
96 #define GEN5_POWER_STATE_IDLE                0x04
97 #define GEN5_POWER_STATE_BTN_ONLY            0x05
98 #define GEN5_POWER_STATE_OFF                 0x06
99
100 #define GEN5_POWER_READY_MAX_INTRVL_TIME  50   /* Unit: ms */
101 #define GEN5_POWER_IDLE_MAX_INTRVL_TIME   250  /* Unit: ms */
102
103 #define GEN5_CMD_GET_PARAMETER               0x05
104 #define GEN5_CMD_SET_PARAMETER               0x06
105 #define GEN5_PARAMETER_ACT_INTERVL_ID        0x4d
106 #define GEN5_PARAMETER_ACT_INTERVL_SIZE      1
107 #define GEN5_PARAMETER_ACT_LFT_INTERVL_ID    0x4f
108 #define GEN5_PARAMETER_ACT_LFT_INTERVL_SIZE  2
109 #define GEN5_PARAMETER_LP_INTRVL_ID          0x4c
110 #define GEN5_PARAMETER_LP_INTRVL_SIZE        2
111
112 #define GEN5_PARAMETER_DISABLE_PIP_REPORT    0x08
113
114 #define GEN5_BL_REPORT_DESCRIPTOR_SIZE            0x1d
115 #define GEN5_BL_REPORT_DESCRIPTOR_ID              0xfe
116 #define GEN5_APP_REPORT_DESCRIPTOR_SIZE           0xee
117 #define GEN5_APP_CONTRACT_REPORT_DESCRIPTOR_SIZE  0xfa
118 #define GEN5_APP_REPORT_DESCRIPTOR_ID             0xf6
119
120 #define GEN5_RETRIEVE_MUTUAL_PWC_DATA        0x00
121 #define GEN5_RETRIEVE_SELF_CAP_PWC_DATA      0x01
122
123 #define GEN5_RETRIEVE_DATA_ELEMENT_SIZE_MASK 0x07
124
125 #define GEN5_CMD_EXECUTE_PANEL_SCAN          0x2a
126 #define GEN5_CMD_RETRIEVE_PANEL_SCAN         0x2b
127 #define GEN5_PANEL_SCAN_MUTUAL_RAW_DATA      0x00
128 #define GEN5_PANEL_SCAN_MUTUAL_BASELINE      0x01
129 #define GEN5_PANEL_SCAN_MUTUAL_DIFFCOUNT     0x02
130 #define GEN5_PANEL_SCAN_SELF_RAW_DATA        0x03
131 #define GEN5_PANEL_SCAN_SELF_BASELINE        0x04
132 #define GEN5_PANEL_SCAN_SELF_DIFFCOUNT       0x05
133
134 /* The offset only valid for retrieve PWC and panel scan commands */
135 #define GEN5_RESP_DATA_STRUCTURE_OFFSET      10
136 #define GEN5_PWC_DATA_ELEMENT_SIZE_MASK      0x07
137
138
139 struct cyapa_pip_touch_record {
140         /*
141          * Bit 7 - 3: reserved
142          * Bit 2 - 0: touch type;
143          *            0 : standard finger;
144          *            1 : proximity (Start supported in Gen5 TP).
145          *            2 : finger hover (defined, but not used yet.)
146          *            3 - 15 : reserved.
147          */
148         u8 touch_type;
149
150         /*
151          * Bit 7: indicates touch liftoff status.
152          *              0 : touch is currently on the panel.
153          *              1 : touch record indicates a liftoff.
154          * Bit 6 - 5: indicates an event associated with this touch instance
155          *              0 : no event
156          *              1 : touchdown
157          *              2 : significant displacement (> active distance)
158          *              3 : liftoff (record reports last known coordinates)
159          * Bit 4 - 0: An arbitrary ID tag associated with a finger
160          *              to allow tracking a touch as it moves around the panel.
161          */
162         u8 touch_tip_event_id;
163
164         /* Bit 7 - 0 of X-axis coordinate of the touch in pixel. */
165         u8 x_lo;
166
167         /* Bit 15 - 8 of X-axis coordinate of the touch in pixel. */
168         u8 x_hi;
169
170         /* Bit 7 - 0 of Y-axis coordinate of the touch in pixel. */
171         u8 y_lo;
172
173         /* Bit 15 - 8 of Y-axis coordinate of the touch in pixel. */
174         u8 y_hi;
175
176         /*
177          * The meaning of this value is different when touch_type is different.
178          * For standard finger type:
179          *      Touch intensity in counts, pressure value.
180          * For proximity type (Start supported in Gen5 TP):
181          *      The distance, in surface units, between the contact and
182          *      the surface.
183          **/
184         u8 z;
185
186         /*
187          * The length of the major axis of the ellipse of contact between
188          * the finger and the panel (ABS_MT_TOUCH_MAJOR).
189          */
190         u8 major_axis_len;
191
192         /*
193          * The length of the minor axis of the ellipse of contact between
194          * the finger and the panel (ABS_MT_TOUCH_MINOR).
195          */
196         u8 minor_axis_len;
197
198         /*
199          * The length of the major axis of the approaching tool.
200          * (ABS_MT_WIDTH_MAJOR)
201          */
202         u8 major_tool_len;
203
204         /*
205          * The length of the minor axis of the approaching tool.
206          * (ABS_MT_WIDTH_MINOR)
207          */
208         u8 minor_tool_len;
209
210         /*
211          * The angle between the panel vertical axis and
212          * the major axis of the contact ellipse. This value is an 8-bit
213          * signed integer. The range is -127 to +127 (corresponding to
214          * -90 degree and +90 degree respectively).
215          * The positive direction is clockwise from the vertical axis.
216          * If the ellipse of contact degenerates into a circle,
217          * orientation is reported as 0.
218          */
219         u8 orientation;
220 } __packed;
221
222 struct cyapa_pip_report_data {
223         u8 report_head[PIP_TOUCH_REPORT_HEAD_SIZE];
224         struct cyapa_pip_touch_record touch_records[10];
225 } __packed;
226
227 struct cyapa_tsg_bin_image_head {
228         u8 head_size;  /* Unit: bytes, including itself. */
229         u8 ttda_driver_major_version;  /* Reserved as 0. */
230         u8 ttda_driver_minor_version;  /* Reserved as 0. */
231         u8 fw_major_version;
232         u8 fw_minor_version;
233         u8 fw_revision_control_number[8];
234         u8 silicon_id_hi;
235         u8 silicon_id_lo;
236         u8 chip_revision;
237         u8 family_id;
238         u8 bl_ver_maj;
239         u8 bl_ver_min;
240 } __packed;
241
242 struct cyapa_tsg_bin_image_data_record {
243         u8 flash_array_id;
244         __be16 row_number;
245         /* The number of bytes of flash data contained in this record. */
246         __be16 record_len;
247         /* The flash program data. */
248         u8 record_data[CYAPA_TSG_FW_ROW_SIZE];
249 } __packed;
250
251 struct cyapa_tsg_bin_image {
252         struct cyapa_tsg_bin_image_head image_head;
253         struct cyapa_tsg_bin_image_data_record records[0];
254 } __packed;
255
256 struct pip_bl_packet_start {
257         u8 sop;  /* Start of packet, must be 01h */
258         u8 cmd_code;
259         __le16 data_length;  /* Size of data parameter start from data[0] */
260 } __packed;
261
262 struct pip_bl_packet_end {
263         __le16 crc;
264         u8 eop;  /* End of packet, must be 17h */
265 } __packed;
266
267 struct pip_bl_cmd_head {
268         __le16 addr;   /* Output report register address, must be 0004h */
269         /* Size of packet not including output report register address */
270         __le16 length;
271         u8 report_id;  /* Bootloader output report id, must be 40h */
272         u8 rsvd;  /* Reserved, must be 0 */
273         struct pip_bl_packet_start packet_start;
274         u8 data[0];  /* Command data variable based on commands */
275 } __packed;
276
277 /* Initiate bootload command data structure. */
278 struct pip_bl_initiate_cmd_data {
279         /* Key must be "A5h 01h 02h 03h FFh FEh FDh 5Ah" */
280         u8 key[CYAPA_TSG_BL_KEY_SIZE];
281         u8 metadata_raw_parameter[CYAPA_TSG_FLASH_MAP_METADATA_SIZE];
282         __le16 metadata_crc;
283 } __packed;
284
285 struct tsg_bl_metadata_row_params {
286         __le16 size;
287         __le16 maximum_size;
288         __le32 app_start;
289         __le16 app_len;
290         __le16 app_crc;
291         __le32 app_entry;
292         __le32 upgrade_start;
293         __le16 upgrade_len;
294         __le16 entry_row_crc;
295         u8 padding[36];  /* Padding data must be 0 */
296         __le16 metadata_crc;  /* CRC starts at offset of 60 */
297 } __packed;
298
299 /* Bootload program and verify row command data structure */
300 struct tsg_bl_flash_row_head {
301         u8 flash_array_id;
302         __le16 flash_row_id;
303         u8 flash_data[0];
304 } __packed;
305
306 struct pip_app_cmd_head {
307         __le16 addr;   /* Output report register address, must be 0004h */
308         /* Size of packet not including output report register address */
309         __le16 length;
310         u8 report_id;  /* Application output report id, must be 2Fh */
311         u8 rsvd;  /* Reserved, must be 0 */
312         /*
313          * Bit 7: reserved, must be 0.
314          * Bit 6-0: command code.
315          */
316         u8 cmd_code;
317         u8 parameter_data[0];  /* Parameter data variable based on cmd_code */
318 } __packed;
319
320 /* Application get/set parameter command data structure */
321 struct gen5_app_set_parameter_data {
322         u8 parameter_id;
323         u8 parameter_size;
324         __le32 value;
325 } __packed;
326
327 struct gen5_app_get_parameter_data {
328         u8 parameter_id;
329 } __packed;
330
331 struct gen5_retrieve_panel_scan_data {
332         __le16 read_offset;
333         __le16 read_elements;
334         u8 data_id;
335 } __packed;
336
337 u8 pip_read_sys_info[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x02 };
338 u8 pip_bl_read_app_info[] = { 0x04, 0x00, 0x0b, 0x00, 0x40, 0x00,
339                 0x01, 0x3c, 0x00, 0x00, 0xb0, 0x42, 0x17
340         };
341
342 static u8 cyapa_pip_bl_cmd_key[] = { 0xa5, 0x01, 0x02, 0x03,
343         0xff, 0xfe, 0xfd, 0x5a };
344
345 static int cyapa_pip_event_process(struct cyapa *cyapa,
346                                    struct cyapa_pip_report_data *report_data);
347
348 int cyapa_pip_cmd_state_initialize(struct cyapa *cyapa)
349 {
350         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
351
352         init_completion(&pip->cmd_ready);
353         atomic_set(&pip->cmd_issued, 0);
354         mutex_init(&pip->cmd_lock);
355
356         mutex_init(&pip->pm_stage_lock);
357         pip->pm_stage = CYAPA_PM_DEACTIVE;
358
359         pip->resp_sort_func = NULL;
360         pip->in_progress_cmd = PIP_INVALID_CMD;
361         pip->resp_data = NULL;
362         pip->resp_len = NULL;
363
364         cyapa->dev_pwr_mode = UNINIT_PWR_MODE;
365         cyapa->dev_sleep_time = UNINIT_SLEEP_TIME;
366
367         return 0;
368 }
369
370 /* Return negative errno, or else the number of bytes read. */
371 ssize_t cyapa_i2c_pip_read(struct cyapa *cyapa, u8 *buf, size_t size)
372 {
373         int ret;
374
375         if (size == 0)
376                 return 0;
377
378         if (!buf || size > CYAPA_REG_MAP_SIZE)
379                 return -EINVAL;
380
381         ret = i2c_master_recv(cyapa->client, buf, size);
382
383         if (ret != size)
384                 return (ret < 0) ? ret : -EIO;
385         return size;
386 }
387
388 /**
389  * Return a negative errno code else zero on success.
390  */
391 ssize_t cyapa_i2c_pip_write(struct cyapa *cyapa, u8 *buf, size_t size)
392 {
393         int ret;
394
395         if (!buf || !size)
396                 return -EINVAL;
397
398         ret = i2c_master_send(cyapa->client, buf, size);
399
400         if (ret != size)
401                 return (ret < 0) ? ret : -EIO;
402
403         return 0;
404 }
405
406 static void cyapa_set_pip_pm_state(struct cyapa *cyapa,
407                                    enum cyapa_pm_stage pm_stage)
408 {
409         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
410
411         mutex_lock(&pip->pm_stage_lock);
412         pip->pm_stage = pm_stage;
413         mutex_unlock(&pip->pm_stage_lock);
414 }
415
416 static void cyapa_reset_pip_pm_state(struct cyapa *cyapa)
417 {
418         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
419
420         /* Indicates the pip->pm_stage is not valid. */
421         mutex_lock(&pip->pm_stage_lock);
422         pip->pm_stage = CYAPA_PM_DEACTIVE;
423         mutex_unlock(&pip->pm_stage_lock);
424 }
425
426 static enum cyapa_pm_stage cyapa_get_pip_pm_state(struct cyapa *cyapa)
427 {
428         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
429         enum cyapa_pm_stage pm_stage;
430
431         mutex_lock(&pip->pm_stage_lock);
432         pm_stage = pip->pm_stage;
433         mutex_unlock(&pip->pm_stage_lock);
434
435         return pm_stage;
436 }
437
438 /**
439  * This function is aimed to dump all not read data in Gen5 trackpad
440  * before send any command, otherwise, the interrupt line will be blocked.
441  */
442 int cyapa_empty_pip_output_data(struct cyapa *cyapa,
443                 u8 *buf, int *len, cb_sort func)
444 {
445         struct input_dev *input = cyapa->input;
446         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
447         enum cyapa_pm_stage pm_stage = cyapa_get_pip_pm_state(cyapa);
448         int length;
449         int report_count;
450         int empty_count;
451         int buf_len;
452         int error;
453
454         buf_len = 0;
455         if (len) {
456                 buf_len = (*len < CYAPA_REG_MAP_SIZE) ?
457                                 *len : CYAPA_REG_MAP_SIZE;
458                 *len = 0;
459         }
460
461         report_count = 8;  /* max 7 pending data before command response data */
462         empty_count = 0;
463         do {
464                 /*
465                  * Depending on testing in cyapa driver, there are max 5 "02 00"
466                  * packets between two valid buffered data report in firmware.
467                  * So in order to dump all buffered data out and
468                  * make interrupt line release for reassert again,
469                  * we must set the empty_count check value bigger than 5 to
470                  * make it work. Otherwise, in some situation,
471                  * the interrupt line may unable to reactive again,
472                  * which will cause trackpad device unable to
473                  * report data any more.
474                  * for example, it may happen in EFT and ESD testing.
475                  */
476                 if (empty_count > 5)
477                         return 0;
478
479                 error = cyapa_i2c_pip_read(cyapa, pip->empty_buf,
480                                 PIP_RESP_LENGTH_SIZE);
481                 if (error < 0)
482                         return error;
483
484                 length = get_unaligned_le16(pip->empty_buf);
485                 if (length == PIP_RESP_LENGTH_SIZE) {
486                         empty_count++;
487                         continue;
488                 } else if (length > CYAPA_REG_MAP_SIZE) {
489                         /* Should not happen */
490                         return -EINVAL;
491                 } else if (length == 0) {
492                         /* Application or bootloader launch data polled out. */
493                         length = PIP_RESP_LENGTH_SIZE;
494                         if (buf && buf_len && func &&
495                                 func(cyapa, pip->empty_buf, length)) {
496                                 length = min(buf_len, length);
497                                 memcpy(buf, pip->empty_buf, length);
498                                 *len = length;
499                                 /* Response found, success. */
500                                 return 0;
501                         }
502                         continue;
503                 }
504
505                 error = cyapa_i2c_pip_read(cyapa, pip->empty_buf, length);
506                 if (error < 0)
507                         return error;
508
509                 report_count--;
510                 empty_count = 0;
511                 length = get_unaligned_le16(pip->empty_buf);
512                 if (length <= PIP_RESP_LENGTH_SIZE) {
513                         empty_count++;
514                 } else if (buf && buf_len && func &&
515                         func(cyapa, pip->empty_buf, length)) {
516                         length = min(buf_len, length);
517                         memcpy(buf, pip->empty_buf, length);
518                         *len = length;
519                         /* Response found, success. */
520                         return 0;
521                 } else if (cyapa->operational && input && input->users &&
522                            (pm_stage == CYAPA_PM_RUNTIME_RESUME ||
523                             pm_stage == CYAPA_PM_RUNTIME_SUSPEND)) {
524                         /* Parse the data and report it if it's valid. */
525                         cyapa_pip_event_process(cyapa,
526                                (struct cyapa_pip_report_data *)pip->empty_buf);
527                 }
528
529                 error = -EINVAL;
530         } while (report_count);
531
532         return error;
533 }
534
535 static int cyapa_do_i2c_pip_cmd_irq_sync(
536                 struct cyapa *cyapa,
537                 u8 *cmd, size_t cmd_len,
538                 unsigned long timeout)
539 {
540         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
541         int error;
542
543         /* Wait for interrupt to set ready completion */
544         init_completion(&pip->cmd_ready);
545
546         atomic_inc(&pip->cmd_issued);
547         error = cyapa_i2c_pip_write(cyapa, cmd, cmd_len);
548         if (error) {
549                 atomic_dec(&pip->cmd_issued);
550                 return (error < 0) ? error : -EIO;
551         }
552
553         /* Wait for interrupt to indicate command is completed. */
554         timeout = wait_for_completion_timeout(&pip->cmd_ready,
555                                 msecs_to_jiffies(timeout));
556         if (timeout == 0) {
557                 atomic_dec(&pip->cmd_issued);
558                 return -ETIMEDOUT;
559         }
560
561         return 0;
562 }
563
564 static int cyapa_do_i2c_pip_cmd_polling(
565                 struct cyapa *cyapa,
566                 u8 *cmd, size_t cmd_len,
567                 u8 *resp_data, int *resp_len,
568                 unsigned long timeout,
569                 cb_sort func)
570 {
571         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
572         int tries;
573         int length;
574         int error;
575
576         atomic_inc(&pip->cmd_issued);
577         error = cyapa_i2c_pip_write(cyapa, cmd, cmd_len);
578         if (error) {
579                 atomic_dec(&pip->cmd_issued);
580                 return error < 0 ? error : -EIO;
581         }
582
583         length = resp_len ? *resp_len : 0;
584         if (resp_data && resp_len && length != 0 && func) {
585                 tries = timeout / 5;
586                 do {
587                         usleep_range(3000, 5000);
588                         *resp_len = length;
589                         error = cyapa_empty_pip_output_data(cyapa,
590                                         resp_data, resp_len, func);
591                         if (error || *resp_len == 0)
592                                 continue;
593                         else
594                                 break;
595                 } while (--tries > 0);
596                 if ((error || *resp_len == 0) || tries <= 0)
597                         error = error ? error : -ETIMEDOUT;
598         }
599
600         atomic_dec(&pip->cmd_issued);
601         return error;
602 }
603
604 int cyapa_i2c_pip_cmd_irq_sync(
605                 struct cyapa *cyapa,
606                 u8 *cmd, int cmd_len,
607                 u8 *resp_data, int *resp_len,
608                 unsigned long timeout,
609                 cb_sort func,
610                 bool irq_mode)
611 {
612         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
613         int error;
614
615         if (!cmd || !cmd_len)
616                 return -EINVAL;
617
618         /* Commands must be serialized. */
619         error = mutex_lock_interruptible(&pip->cmd_lock);
620         if (error)
621                 return error;
622
623         pip->resp_sort_func = func;
624         pip->resp_data = resp_data;
625         pip->resp_len = resp_len;
626
627         if (cmd_len >= PIP_MIN_APP_CMD_LENGTH &&
628                         cmd[4] == PIP_APP_CMD_REPORT_ID) {
629                 /* Application command */
630                 pip->in_progress_cmd = cmd[6] & 0x7f;
631         } else if (cmd_len >= PIP_MIN_BL_CMD_LENGTH &&
632                         cmd[4] == PIP_BL_CMD_REPORT_ID) {
633                 /* Bootloader command */
634                 pip->in_progress_cmd = cmd[7];
635         }
636
637         /* Send command data, wait and read output response data's length. */
638         if (irq_mode) {
639                 pip->is_irq_mode = true;
640                 error = cyapa_do_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
641                                                         timeout);
642                 if (error == -ETIMEDOUT && resp_data &&
643                                 resp_len && *resp_len != 0 && func) {
644                         /*
645                          * For some old version, there was no interrupt for
646                          * the command response data, so need to poll here
647                          * to try to get the response data.
648                          */
649                         error = cyapa_empty_pip_output_data(cyapa,
650                                         resp_data, resp_len, func);
651                         if (error || *resp_len == 0)
652                                 error = error ? error : -ETIMEDOUT;
653                 }
654         } else {
655                 pip->is_irq_mode = false;
656                 error = cyapa_do_i2c_pip_cmd_polling(cyapa, cmd, cmd_len,
657                                 resp_data, resp_len, timeout, func);
658         }
659
660         pip->resp_sort_func = NULL;
661         pip->resp_data = NULL;
662         pip->resp_len = NULL;
663         pip->in_progress_cmd = PIP_INVALID_CMD;
664
665         mutex_unlock(&pip->cmd_lock);
666         return error;
667 }
668
669 bool cyapa_sort_tsg_pip_bl_resp_data(struct cyapa *cyapa,
670                 u8 *data, int len)
671 {
672         if (!data || len < PIP_MIN_BL_RESP_LENGTH)
673                 return false;
674
675         /* Bootloader input report id 30h */
676         if (data[PIP_RESP_REPORT_ID_OFFSET] == PIP_BL_RESP_REPORT_ID &&
677                         data[PIP_RESP_RSVD_OFFSET] == PIP_RESP_RSVD_KEY &&
678                         data[PIP_RESP_BL_SOP_OFFSET] == PIP_SOP_KEY)
679                 return true;
680
681         return false;
682 }
683
684 bool cyapa_sort_tsg_pip_app_resp_data(struct cyapa *cyapa,
685                 u8 *data, int len)
686 {
687         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
688         int resp_len;
689
690         if (!data || len < PIP_MIN_APP_RESP_LENGTH)
691                 return false;
692
693         if (data[PIP_RESP_REPORT_ID_OFFSET] == PIP_APP_RESP_REPORT_ID &&
694                         data[PIP_RESP_RSVD_OFFSET] == PIP_RESP_RSVD_KEY) {
695                 resp_len = get_unaligned_le16(&data[PIP_RESP_LENGTH_OFFSET]);
696                 if (GET_PIP_CMD_CODE(data[PIP_RESP_APP_CMD_OFFSET]) == 0x00 &&
697                         resp_len == PIP_UNSUPPORTED_CMD_RESP_LENGTH &&
698                         data[5] == pip->in_progress_cmd) {
699                         /* Unsupported command code */
700                         return false;
701                 } else if (GET_PIP_CMD_CODE(data[PIP_RESP_APP_CMD_OFFSET]) ==
702                                 pip->in_progress_cmd) {
703                         /* Correct command response received */
704                         return true;
705                 }
706         }
707
708         return false;
709 }
710
711 static bool cyapa_sort_pip_application_launch_data(struct cyapa *cyapa,
712                 u8 *buf, int len)
713 {
714         if (buf == NULL || len < PIP_RESP_LENGTH_SIZE)
715                 return false;
716
717         /*
718          * After reset or power on, trackpad device always sets to 0x00 0x00
719          * to indicate a reset or power on event.
720          */
721         if (buf[0] == 0 && buf[1] == 0)
722                 return true;
723
724         return false;
725 }
726
727 static bool cyapa_sort_gen5_hid_descriptor_data(struct cyapa *cyapa,
728                 u8 *buf, int len)
729 {
730         int resp_len;
731         int max_output_len;
732
733         /* Check hid descriptor. */
734         if (len != PIP_HID_DESCRIPTOR_SIZE)
735                 return false;
736
737         resp_len = get_unaligned_le16(&buf[PIP_RESP_LENGTH_OFFSET]);
738         max_output_len = get_unaligned_le16(&buf[16]);
739         if (resp_len == PIP_HID_DESCRIPTOR_SIZE) {
740                 if (buf[PIP_RESP_REPORT_ID_OFFSET] == PIP_HID_BL_REPORT_ID &&
741                                 max_output_len == GEN5_BL_MAX_OUTPUT_LENGTH) {
742                         /* BL mode HID Descriptor */
743                         return true;
744                 } else if ((buf[PIP_RESP_REPORT_ID_OFFSET] ==
745                                 PIP_HID_APP_REPORT_ID) &&
746                                 max_output_len == GEN5_APP_MAX_OUTPUT_LENGTH) {
747                         /* APP mode HID Descriptor */
748                         return true;
749                 }
750         }
751
752         return false;
753 }
754
755 static bool cyapa_sort_pip_deep_sleep_data(struct cyapa *cyapa,
756                 u8 *buf, int len)
757 {
758         if (len == PIP_DEEP_SLEEP_RESP_LENGTH &&
759                 buf[PIP_RESP_REPORT_ID_OFFSET] ==
760                         PIP_APP_DEEP_SLEEP_REPORT_ID &&
761                 (buf[4] & PIP_DEEP_SLEEP_OPCODE_MASK) ==
762                         PIP_DEEP_SLEEP_OPCODE)
763                 return true;
764         return false;
765 }
766
767 static int gen5_idle_state_parse(struct cyapa *cyapa)
768 {
769         u8 resp_data[PIP_HID_DESCRIPTOR_SIZE];
770         int max_output_len;
771         int length;
772         u8 cmd[2];
773         int ret;
774         int error;
775
776         /*
777          * Dump all buffered data firstly for the situation
778          * when the trackpad is just power on the cyapa go here.
779          */
780         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
781
782         memset(resp_data, 0, sizeof(resp_data));
783         ret = cyapa_i2c_pip_read(cyapa, resp_data, 3);
784         if (ret != 3)
785                 return ret < 0 ? ret : -EIO;
786
787         length = get_unaligned_le16(&resp_data[PIP_RESP_LENGTH_OFFSET]);
788         if (length == PIP_RESP_LENGTH_SIZE) {
789                 /* Normal state of Gen5 with no data to response */
790                 cyapa->gen = CYAPA_GEN5;
791
792                 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
793
794                 /* Read description from trackpad device */
795                 cmd[0] = 0x01;
796                 cmd[1] = 0x00;
797                 length = PIP_HID_DESCRIPTOR_SIZE;
798                 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
799                                 cmd, PIP_RESP_LENGTH_SIZE,
800                                 resp_data, &length,
801                                 300,
802                                 cyapa_sort_gen5_hid_descriptor_data,
803                                 false);
804                 if (error)
805                         return error;
806
807                 length = get_unaligned_le16(
808                                 &resp_data[PIP_RESP_LENGTH_OFFSET]);
809                 max_output_len = get_unaligned_le16(&resp_data[16]);
810                 if ((length == PIP_HID_DESCRIPTOR_SIZE ||
811                                 length == PIP_RESP_LENGTH_SIZE) &&
812                         (resp_data[PIP_RESP_REPORT_ID_OFFSET] ==
813                                 PIP_HID_BL_REPORT_ID) &&
814                         max_output_len == GEN5_BL_MAX_OUTPUT_LENGTH) {
815                         /* BL mode HID Description read */
816                         cyapa->state = CYAPA_STATE_GEN5_BL;
817                 } else if ((length == PIP_HID_DESCRIPTOR_SIZE ||
818                                 length == PIP_RESP_LENGTH_SIZE) &&
819                         (resp_data[PIP_RESP_REPORT_ID_OFFSET] ==
820                                 PIP_HID_APP_REPORT_ID) &&
821                         max_output_len == GEN5_APP_MAX_OUTPUT_LENGTH) {
822                         /* APP mode HID Description read */
823                         cyapa->state = CYAPA_STATE_GEN5_APP;
824                 } else {
825                         /* Should not happen!!! */
826                         cyapa->state = CYAPA_STATE_NO_DEVICE;
827                 }
828         }
829
830         return 0;
831 }
832
833 static int gen5_hid_description_header_parse(struct cyapa *cyapa, u8 *reg_data)
834 {
835         int length;
836         u8 resp_data[32];
837         int max_output_len;
838         int ret;
839
840         /* 0x20 0x00 0xF7 is Gen5 Application HID Description Header;
841          * 0x20 0x00 0xFF is Gen5 Bootloader HID Description Header.
842          *
843          * Must read HID Description content through out,
844          * otherwise Gen5 trackpad cannot response next command
845          * or report any touch or button data.
846          */
847         ret = cyapa_i2c_pip_read(cyapa, resp_data,
848                         PIP_HID_DESCRIPTOR_SIZE);
849         if (ret != PIP_HID_DESCRIPTOR_SIZE)
850                 return ret < 0 ? ret : -EIO;
851         length = get_unaligned_le16(&resp_data[PIP_RESP_LENGTH_OFFSET]);
852         max_output_len = get_unaligned_le16(&resp_data[16]);
853         if (length == PIP_RESP_LENGTH_SIZE) {
854                 if (reg_data[PIP_RESP_REPORT_ID_OFFSET] ==
855                                 PIP_HID_BL_REPORT_ID) {
856                         /*
857                          * BL mode HID Description has been previously
858                          * read out.
859                          */
860                         cyapa->gen = CYAPA_GEN5;
861                         cyapa->state = CYAPA_STATE_GEN5_BL;
862                 } else {
863                         /*
864                          * APP mode HID Description has been previously
865                          * read out.
866                          */
867                         cyapa->gen = CYAPA_GEN5;
868                         cyapa->state = CYAPA_STATE_GEN5_APP;
869                 }
870         } else if (length == PIP_HID_DESCRIPTOR_SIZE &&
871                         resp_data[2] == PIP_HID_BL_REPORT_ID &&
872                         max_output_len == GEN5_BL_MAX_OUTPUT_LENGTH) {
873                 /* BL mode HID Description read. */
874                 cyapa->gen = CYAPA_GEN5;
875                 cyapa->state = CYAPA_STATE_GEN5_BL;
876         } else if (length == PIP_HID_DESCRIPTOR_SIZE &&
877                         (resp_data[PIP_RESP_REPORT_ID_OFFSET] ==
878                                 PIP_HID_APP_REPORT_ID) &&
879                         max_output_len == GEN5_APP_MAX_OUTPUT_LENGTH) {
880                 /* APP mode HID Description read. */
881                 cyapa->gen = CYAPA_GEN5;
882                 cyapa->state = CYAPA_STATE_GEN5_APP;
883         } else {
884                 /* Should not happen!!! */
885                 cyapa->state = CYAPA_STATE_NO_DEVICE;
886         }
887
888         return 0;
889 }
890
891 static int gen5_report_data_header_parse(struct cyapa *cyapa, u8 *reg_data)
892 {
893         int length;
894
895         length = get_unaligned_le16(&reg_data[PIP_RESP_LENGTH_OFFSET]);
896         switch (reg_data[PIP_RESP_REPORT_ID_OFFSET]) {
897         case PIP_TOUCH_REPORT_ID:
898                 if (length < PIP_TOUCH_REPORT_HEAD_SIZE ||
899                         length > PIP_TOUCH_REPORT_MAX_SIZE)
900                         return -EINVAL;
901                 break;
902         case PIP_BTN_REPORT_ID:
903         case GEN5_OLD_PUSH_BTN_REPORT_ID:
904         case PIP_PUSH_BTN_REPORT_ID:
905                 if (length < PIP_BTN_REPORT_HEAD_SIZE ||
906                         length > PIP_BTN_REPORT_MAX_SIZE)
907                         return -EINVAL;
908                 break;
909         case PIP_WAKEUP_EVENT_REPORT_ID:
910                 if (length != PIP_WAKEUP_EVENT_SIZE)
911                         return -EINVAL;
912                 break;
913         default:
914                 return -EINVAL;
915         }
916
917         cyapa->gen = CYAPA_GEN5;
918         cyapa->state = CYAPA_STATE_GEN5_APP;
919         return 0;
920 }
921
922 static int gen5_cmd_resp_header_parse(struct cyapa *cyapa, u8 *reg_data)
923 {
924         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
925         int length;
926         int ret;
927
928         /*
929          * Must read report data through out,
930          * otherwise Gen5 trackpad cannot response next command
931          * or report any touch or button data.
932          */
933         length = get_unaligned_le16(&reg_data[PIP_RESP_LENGTH_OFFSET]);
934         ret = cyapa_i2c_pip_read(cyapa, pip->empty_buf, length);
935         if (ret != length)
936                 return ret < 0 ? ret : -EIO;
937
938         if (length == PIP_RESP_LENGTH_SIZE) {
939                 /* Previous command has read the data through out. */
940                 if (reg_data[PIP_RESP_REPORT_ID_OFFSET] ==
941                                 PIP_BL_RESP_REPORT_ID) {
942                         /* Gen5 BL command response data detected */
943                         cyapa->gen = CYAPA_GEN5;
944                         cyapa->state = CYAPA_STATE_GEN5_BL;
945                 } else {
946                         /* Gen5 APP command response data detected */
947                         cyapa->gen = CYAPA_GEN5;
948                         cyapa->state = CYAPA_STATE_GEN5_APP;
949                 }
950         } else if ((pip->empty_buf[PIP_RESP_REPORT_ID_OFFSET] ==
951                                 PIP_BL_RESP_REPORT_ID) &&
952                         (pip->empty_buf[PIP_RESP_RSVD_OFFSET] ==
953                                 PIP_RESP_RSVD_KEY) &&
954                         (pip->empty_buf[PIP_RESP_BL_SOP_OFFSET] ==
955                                 PIP_SOP_KEY) &&
956                         (pip->empty_buf[length - 1] ==
957                                 PIP_EOP_KEY)) {
958                 /* Gen5 BL command response data detected */
959                 cyapa->gen = CYAPA_GEN5;
960                 cyapa->state = CYAPA_STATE_GEN5_BL;
961         } else if (pip->empty_buf[PIP_RESP_REPORT_ID_OFFSET] ==
962                                 PIP_APP_RESP_REPORT_ID &&
963                         pip->empty_buf[PIP_RESP_RSVD_OFFSET] ==
964                                 PIP_RESP_RSVD_KEY) {
965                 /* Gen5 APP command response data detected */
966                 cyapa->gen = CYAPA_GEN5;
967                 cyapa->state = CYAPA_STATE_GEN5_APP;
968         } else {
969                 /* Should not happen!!! */
970                 cyapa->state = CYAPA_STATE_NO_DEVICE;
971         }
972
973         return 0;
974 }
975
976 static int cyapa_gen5_state_parse(struct cyapa *cyapa, u8 *reg_data, int len)
977 {
978         int length;
979
980         if (!reg_data || len < 3)
981                 return -EINVAL;
982
983         cyapa->state = CYAPA_STATE_NO_DEVICE;
984
985         /* Parse based on Gen5 characteristic registers and bits */
986         length = get_unaligned_le16(&reg_data[PIP_RESP_LENGTH_OFFSET]);
987         if (length == 0 || length == PIP_RESP_LENGTH_SIZE) {
988                 gen5_idle_state_parse(cyapa);
989         } else if (length == PIP_HID_DESCRIPTOR_SIZE &&
990                         (reg_data[2] == PIP_HID_BL_REPORT_ID ||
991                                 reg_data[2] == PIP_HID_APP_REPORT_ID)) {
992                 gen5_hid_description_header_parse(cyapa, reg_data);
993         } else if ((length == GEN5_APP_REPORT_DESCRIPTOR_SIZE ||
994                         length == GEN5_APP_CONTRACT_REPORT_DESCRIPTOR_SIZE) &&
995                         reg_data[2] == GEN5_APP_REPORT_DESCRIPTOR_ID) {
996                 /* 0xEE 0x00 0xF6 is Gen5 APP report description header. */
997                 cyapa->gen = CYAPA_GEN5;
998                 cyapa->state = CYAPA_STATE_GEN5_APP;
999         } else if (length == GEN5_BL_REPORT_DESCRIPTOR_SIZE &&
1000                         reg_data[2] == GEN5_BL_REPORT_DESCRIPTOR_ID) {
1001                 /* 0x1D 0x00 0xFE is Gen5 BL report descriptor header. */
1002                 cyapa->gen = CYAPA_GEN5;
1003                 cyapa->state = CYAPA_STATE_GEN5_BL;
1004         } else if (reg_data[2] == PIP_TOUCH_REPORT_ID ||
1005                         reg_data[2] == PIP_BTN_REPORT_ID ||
1006                         reg_data[2] == GEN5_OLD_PUSH_BTN_REPORT_ID ||
1007                         reg_data[2] == PIP_PUSH_BTN_REPORT_ID ||
1008                         reg_data[2] == PIP_WAKEUP_EVENT_REPORT_ID) {
1009                 gen5_report_data_header_parse(cyapa, reg_data);
1010         } else if (reg_data[2] == PIP_BL_RESP_REPORT_ID ||
1011                         reg_data[2] == PIP_APP_RESP_REPORT_ID) {
1012                 gen5_cmd_resp_header_parse(cyapa, reg_data);
1013         }
1014
1015         if (cyapa->gen == CYAPA_GEN5) {
1016                 /*
1017                  * Must read the content (e.g.: report description and so on)
1018                  * from trackpad device throughout. Otherwise,
1019                  * Gen5 trackpad cannot response to next command or
1020                  * report any touch or button data later.
1021                  */
1022                 cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1023
1024                 if (cyapa->state == CYAPA_STATE_GEN5_APP ||
1025                         cyapa->state == CYAPA_STATE_GEN5_BL)
1026                         return 0;
1027         }
1028
1029         return -EAGAIN;
1030 }
1031
1032 static struct cyapa_tsg_bin_image_data_record *
1033 cyapa_get_image_record_data_num(const struct firmware *fw,
1034                 int *record_num)
1035 {
1036         int head_size;
1037
1038         head_size = fw->data[0] + 1;
1039         *record_num = (fw->size - head_size) /
1040                         sizeof(struct cyapa_tsg_bin_image_data_record);
1041         return (struct cyapa_tsg_bin_image_data_record *)&fw->data[head_size];
1042 }
1043
1044 int cyapa_pip_bl_initiate(struct cyapa *cyapa, const struct firmware *fw)
1045 {
1046         struct cyapa_tsg_bin_image_data_record *image_records;
1047         struct pip_bl_cmd_head *bl_cmd_head;
1048         struct pip_bl_packet_start *bl_packet_start;
1049         struct pip_bl_initiate_cmd_data *cmd_data;
1050         struct pip_bl_packet_end *bl_packet_end;
1051         u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1052         int cmd_len;
1053         u16 cmd_data_len;
1054         u16 cmd_crc = 0;
1055         u16 meta_data_crc = 0;
1056         u8 resp_data[11];
1057         int resp_len;
1058         int records_num;
1059         u8 *data;
1060         int error;
1061
1062         /* Try to dump all buffered report data before any send command. */
1063         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1064
1065         memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1066         bl_cmd_head = (struct pip_bl_cmd_head *)cmd;
1067         cmd_data_len = CYAPA_TSG_BL_KEY_SIZE + CYAPA_TSG_FLASH_MAP_BLOCK_SIZE;
1068         cmd_len = sizeof(struct pip_bl_cmd_head) + cmd_data_len +
1069                   sizeof(struct pip_bl_packet_end);
1070
1071         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &bl_cmd_head->addr);
1072         put_unaligned_le16(cmd_len - 2, &bl_cmd_head->length);
1073         bl_cmd_head->report_id = PIP_BL_CMD_REPORT_ID;
1074
1075         bl_packet_start = &bl_cmd_head->packet_start;
1076         bl_packet_start->sop = PIP_SOP_KEY;
1077         bl_packet_start->cmd_code = PIP_BL_CMD_INITIATE_BL;
1078         /* 8 key bytes and 128 bytes block size */
1079         put_unaligned_le16(cmd_data_len, &bl_packet_start->data_length);
1080
1081         cmd_data = (struct pip_bl_initiate_cmd_data *)bl_cmd_head->data;
1082         memcpy(cmd_data->key, cyapa_pip_bl_cmd_key, CYAPA_TSG_BL_KEY_SIZE);
1083
1084         image_records = cyapa_get_image_record_data_num(fw, &records_num);
1085
1086         /* APP_INTEGRITY row is always the last row block */
1087         data = image_records[records_num - 1].record_data;
1088         memcpy(cmd_data->metadata_raw_parameter, data,
1089                 CYAPA_TSG_FLASH_MAP_METADATA_SIZE);
1090
1091         meta_data_crc = crc_itu_t(0xffff, cmd_data->metadata_raw_parameter,
1092                                 CYAPA_TSG_FLASH_MAP_METADATA_SIZE);
1093         put_unaligned_le16(meta_data_crc, &cmd_data->metadata_crc);
1094
1095         bl_packet_end = (struct pip_bl_packet_end *)(bl_cmd_head->data +
1096                                 cmd_data_len);
1097         cmd_crc = crc_itu_t(0xffff, (u8 *)bl_packet_start,
1098                 sizeof(struct pip_bl_packet_start) + cmd_data_len);
1099         put_unaligned_le16(cmd_crc, &bl_packet_end->crc);
1100         bl_packet_end->eop = PIP_EOP_KEY;
1101
1102         resp_len = sizeof(resp_data);
1103         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1104                         cmd, cmd_len,
1105                         resp_data, &resp_len, 12000,
1106                         cyapa_sort_tsg_pip_bl_resp_data, true);
1107         if (error || resp_len != PIP_BL_INITIATE_RESP_LEN ||
1108                         resp_data[2] != PIP_BL_RESP_REPORT_ID ||
1109                         !PIP_CMD_COMPLETE_SUCCESS(resp_data))
1110                 return error ? error : -EAGAIN;
1111
1112         return 0;
1113 }
1114
1115 static bool cyapa_sort_pip_bl_exit_data(struct cyapa *cyapa, u8 *buf, int len)
1116 {
1117         if (buf == NULL || len < PIP_RESP_LENGTH_SIZE)
1118                 return false;
1119
1120         if (buf[0] == 0 && buf[1] == 0)
1121                 return true;
1122
1123         /* Exit bootloader failed for some reason. */
1124         if (len == PIP_BL_FAIL_EXIT_RESP_LEN &&
1125                         buf[PIP_RESP_REPORT_ID_OFFSET] ==
1126                                 PIP_BL_RESP_REPORT_ID &&
1127                         buf[PIP_RESP_RSVD_OFFSET] == PIP_RESP_RSVD_KEY &&
1128                         buf[PIP_RESP_BL_SOP_OFFSET] == PIP_SOP_KEY &&
1129                         buf[10] == PIP_EOP_KEY)
1130                 return true;
1131
1132         return false;
1133 }
1134
1135 int cyapa_pip_bl_exit(struct cyapa *cyapa)
1136 {
1137
1138         u8 bl_gen5_bl_exit[] = { 0x04, 0x00,
1139                 0x0B, 0x00, 0x40, 0x00, 0x01, 0x3b, 0x00, 0x00,
1140                 0x20, 0xc7, 0x17
1141         };
1142         u8 resp_data[11];
1143         int resp_len;
1144         int error;
1145
1146         resp_len = sizeof(resp_data);
1147         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1148                         bl_gen5_bl_exit, sizeof(bl_gen5_bl_exit),
1149                         resp_data, &resp_len,
1150                         5000, cyapa_sort_pip_bl_exit_data, false);
1151         if (error)
1152                 return error;
1153
1154         if (resp_len == PIP_BL_FAIL_EXIT_RESP_LEN ||
1155                         resp_data[PIP_RESP_REPORT_ID_OFFSET] ==
1156                                 PIP_BL_RESP_REPORT_ID)
1157                 return -EAGAIN;
1158
1159         if (resp_data[0] == 0x00 && resp_data[1] == 0x00)
1160                 return 0;
1161
1162         return -ENODEV;
1163 }
1164
1165 int cyapa_pip_bl_enter(struct cyapa *cyapa)
1166 {
1167         u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2F, 0x00, 0x01 };
1168         u8 resp_data[2];
1169         int resp_len;
1170         int error;
1171
1172         error = cyapa_poll_state(cyapa, 500);
1173         if (error < 0)
1174                 return error;
1175
1176         /* Already in bootloader mode, Skipping exit. */
1177         if (cyapa_is_pip_bl_mode(cyapa))
1178                 return 0;
1179         else if (!cyapa_is_pip_app_mode(cyapa))
1180                 return -EINVAL;
1181
1182         /* Try to dump all buffered report data before any send command. */
1183         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1184
1185         /*
1186          * Send bootloader enter command to trackpad device,
1187          * after enter bootloader, the response data is two bytes of 0x00 0x00.
1188          */
1189         resp_len = sizeof(resp_data);
1190         memset(resp_data, 0, resp_len);
1191         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1192                         cmd, sizeof(cmd),
1193                         resp_data, &resp_len,
1194                         5000, cyapa_sort_pip_application_launch_data,
1195                         true);
1196         if (error || resp_data[0] != 0x00 || resp_data[1] != 0x00)
1197                 return error < 0 ? error : -EAGAIN;
1198
1199         cyapa->operational = false;
1200         if (cyapa->gen == CYAPA_GEN5)
1201                 cyapa->state = CYAPA_STATE_GEN5_BL;
1202         else if (cyapa->gen == CYAPA_GEN6)
1203                 cyapa->state = CYAPA_STATE_GEN6_BL;
1204         return 0;
1205 }
1206
1207 static int cyapa_pip_fw_head_check(struct cyapa *cyapa,
1208                 struct cyapa_tsg_bin_image_head *image_head)
1209 {
1210         if (image_head->head_size != 0x0C && image_head->head_size != 0x12)
1211                 return -EINVAL;
1212
1213         switch (cyapa->gen) {
1214         case CYAPA_GEN6:
1215                 if (image_head->family_id != 0x9B ||
1216                     image_head->silicon_id_hi != 0x0B)
1217                         return -EINVAL;
1218                 break;
1219         case CYAPA_GEN5:
1220                 /* Gen5 without proximity support. */
1221                 if (cyapa->platform_ver < 2) {
1222                         if (image_head->head_size == 0x0C)
1223                                 break;
1224                         return -EINVAL;
1225                 }
1226
1227                 if (image_head->family_id != 0x91 ||
1228                     image_head->silicon_id_hi != 0x02)
1229                         return -EINVAL;
1230                 break;
1231         default:
1232                 return -EINVAL;
1233         }
1234
1235         return 0;
1236 }
1237
1238 int cyapa_pip_check_fw(struct cyapa *cyapa, const struct firmware *fw)
1239 {
1240         struct device *dev = &cyapa->client->dev;
1241         struct cyapa_tsg_bin_image_data_record *image_records;
1242         const struct cyapa_tsg_bin_image_data_record *app_integrity;
1243         const struct tsg_bl_metadata_row_params *metadata;
1244         int flash_records_count;
1245         u32 fw_app_start, fw_upgrade_start;
1246         u16 fw_app_len, fw_upgrade_len;
1247         u16 app_crc;
1248         u16 app_integrity_crc;
1249         int i;
1250
1251         /* Verify the firmware image not miss-used for Gen5 and Gen6. */
1252         if (cyapa_pip_fw_head_check(cyapa,
1253                 (struct cyapa_tsg_bin_image_head *)fw->data)) {
1254                 dev_err(dev, "%s: firmware image not match TP device.\n",
1255                              __func__);
1256                 return -EINVAL;
1257         }
1258
1259         image_records =
1260                 cyapa_get_image_record_data_num(fw, &flash_records_count);
1261
1262         /*
1263          * APP_INTEGRITY row is always the last row block,
1264          * and the row id must be 0x01ff.
1265          */
1266         app_integrity = &image_records[flash_records_count - 1];
1267
1268         if (app_integrity->flash_array_id != 0x00 ||
1269             get_unaligned_be16(&app_integrity->row_number) != 0x01ff) {
1270                 dev_err(dev, "%s: invalid app_integrity data.\n", __func__);
1271                 return -EINVAL;
1272         }
1273
1274         metadata = (const void *)app_integrity->record_data;
1275
1276         /* Verify app_integrity crc */
1277         app_integrity_crc = crc_itu_t(0xffff, app_integrity->record_data,
1278                                       CYAPA_TSG_APP_INTEGRITY_SIZE);
1279         if (app_integrity_crc != get_unaligned_le16(&metadata->metadata_crc)) {
1280                 dev_err(dev, "%s: invalid app_integrity crc.\n", __func__);
1281                 return -EINVAL;
1282         }
1283
1284         fw_app_start = get_unaligned_le32(&metadata->app_start);
1285         fw_app_len = get_unaligned_le16(&metadata->app_len);
1286         fw_upgrade_start = get_unaligned_le32(&metadata->upgrade_start);
1287         fw_upgrade_len = get_unaligned_le16(&metadata->upgrade_len);
1288
1289         if (fw_app_start % CYAPA_TSG_FW_ROW_SIZE ||
1290             fw_app_len % CYAPA_TSG_FW_ROW_SIZE ||
1291             fw_upgrade_start % CYAPA_TSG_FW_ROW_SIZE ||
1292             fw_upgrade_len % CYAPA_TSG_FW_ROW_SIZE) {
1293                 dev_err(dev, "%s: invalid image alignment.\n", __func__);
1294                 return -EINVAL;
1295         }
1296
1297         /* Verify application image CRC. */
1298         app_crc = 0xffffU;
1299         for (i = 0; i < fw_app_len / CYAPA_TSG_FW_ROW_SIZE; i++) {
1300                 const u8 *data = image_records[i].record_data;
1301
1302                 app_crc = crc_itu_t(app_crc, data, CYAPA_TSG_FW_ROW_SIZE);
1303         }
1304
1305         if (app_crc != get_unaligned_le16(&metadata->app_crc)) {
1306                 dev_err(dev, "%s: invalid firmware app crc check.\n", __func__);
1307                 return -EINVAL;
1308         }
1309
1310         return 0;
1311 }
1312
1313 static int cyapa_pip_write_fw_block(struct cyapa *cyapa,
1314                 struct cyapa_tsg_bin_image_data_record *flash_record)
1315 {
1316         struct pip_bl_cmd_head *bl_cmd_head;
1317         struct pip_bl_packet_start *bl_packet_start;
1318         struct tsg_bl_flash_row_head *flash_row_head;
1319         struct pip_bl_packet_end *bl_packet_end;
1320         u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1321         u16 cmd_len;
1322         u8 flash_array_id;
1323         u16 flash_row_id;
1324         u16 record_len;
1325         u8 *record_data;
1326         u16 data_len;
1327         u16 crc;
1328         u8 resp_data[11];
1329         int resp_len;
1330         int error;
1331
1332         flash_array_id = flash_record->flash_array_id;
1333         flash_row_id = get_unaligned_be16(&flash_record->row_number);
1334         record_len = get_unaligned_be16(&flash_record->record_len);
1335         record_data = flash_record->record_data;
1336
1337         memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1338         bl_cmd_head = (struct pip_bl_cmd_head *)cmd;
1339         bl_packet_start = &bl_cmd_head->packet_start;
1340         cmd_len = sizeof(struct pip_bl_cmd_head) +
1341                   sizeof(struct tsg_bl_flash_row_head) +
1342                   CYAPA_TSG_FLASH_MAP_BLOCK_SIZE +
1343                   sizeof(struct pip_bl_packet_end);
1344
1345         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &bl_cmd_head->addr);
1346         /* Don't include 2 bytes register address */
1347         put_unaligned_le16(cmd_len - 2, &bl_cmd_head->length);
1348         bl_cmd_head->report_id = PIP_BL_CMD_REPORT_ID;
1349         bl_packet_start->sop = PIP_SOP_KEY;
1350         bl_packet_start->cmd_code = PIP_BL_CMD_PROGRAM_VERIFY_ROW;
1351
1352         /* 1 (Flash Array ID) + 2 (Flash Row ID) + 128 (flash data) */
1353         data_len = sizeof(struct tsg_bl_flash_row_head) + record_len;
1354         put_unaligned_le16(data_len, &bl_packet_start->data_length);
1355
1356         flash_row_head = (struct tsg_bl_flash_row_head *)bl_cmd_head->data;
1357         flash_row_head->flash_array_id = flash_array_id;
1358         put_unaligned_le16(flash_row_id, &flash_row_head->flash_row_id);
1359         memcpy(flash_row_head->flash_data, record_data, record_len);
1360
1361         bl_packet_end = (struct pip_bl_packet_end *)(bl_cmd_head->data +
1362                                                       data_len);
1363         crc = crc_itu_t(0xffff, (u8 *)bl_packet_start,
1364                 sizeof(struct pip_bl_packet_start) + data_len);
1365         put_unaligned_le16(crc, &bl_packet_end->crc);
1366         bl_packet_end->eop = PIP_EOP_KEY;
1367
1368         resp_len = sizeof(resp_data);
1369         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
1370                         resp_data, &resp_len,
1371                         500, cyapa_sort_tsg_pip_bl_resp_data, true);
1372         if (error || resp_len != PIP_BL_BLOCK_WRITE_RESP_LEN ||
1373                         resp_data[2] != PIP_BL_RESP_REPORT_ID ||
1374                         !PIP_CMD_COMPLETE_SUCCESS(resp_data))
1375                 return error < 0 ? error : -EAGAIN;
1376
1377         return 0;
1378 }
1379
1380 int cyapa_pip_do_fw_update(struct cyapa *cyapa,
1381                 const struct firmware *fw)
1382 {
1383         struct device *dev = &cyapa->client->dev;
1384         struct cyapa_tsg_bin_image_data_record *image_records;
1385         int flash_records_count;
1386         int i;
1387         int error;
1388
1389         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1390
1391         image_records =
1392                 cyapa_get_image_record_data_num(fw, &flash_records_count);
1393
1394         /*
1395          * The last flash row 0x01ff has been written through bl_initiate
1396          * command, so DO NOT write flash 0x01ff to trackpad device.
1397          */
1398         for (i = 0; i < (flash_records_count - 1); i++) {
1399                 error = cyapa_pip_write_fw_block(cyapa, &image_records[i]);
1400                 if (error) {
1401                         dev_err(dev, "%s: Gen5 FW update aborted: %d\n",
1402                                 __func__, error);
1403                         return error;
1404                 }
1405         }
1406
1407         return 0;
1408 }
1409
1410 static int cyapa_gen5_change_power_state(struct cyapa *cyapa, u8 power_state)
1411 {
1412         u8 cmd[8] = { 0x04, 0x00, 0x06, 0x00, 0x2f, 0x00, 0x08, 0x01 };
1413         u8 resp_data[6];
1414         int resp_len;
1415         int error;
1416
1417         cmd[7] = power_state;
1418         resp_len = sizeof(resp_data);
1419         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1420                         resp_data, &resp_len,
1421                         500, cyapa_sort_tsg_pip_app_resp_data, false);
1422         if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x08) ||
1423                         !PIP_CMD_COMPLETE_SUCCESS(resp_data))
1424                 return error < 0 ? error : -EINVAL;
1425
1426         return 0;
1427 }
1428
1429 static int cyapa_gen5_set_interval_time(struct cyapa *cyapa,
1430                 u8 parameter_id, u16 interval_time)
1431 {
1432         struct pip_app_cmd_head *app_cmd_head;
1433         struct gen5_app_set_parameter_data *parameter_data;
1434         u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1435         int cmd_len;
1436         u8 resp_data[7];
1437         int resp_len;
1438         u8 parameter_size;
1439         int error;
1440
1441         memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1442         app_cmd_head = (struct pip_app_cmd_head *)cmd;
1443         parameter_data = (struct gen5_app_set_parameter_data *)
1444                          app_cmd_head->parameter_data;
1445         cmd_len = sizeof(struct pip_app_cmd_head) +
1446                   sizeof(struct gen5_app_set_parameter_data);
1447
1448         switch (parameter_id) {
1449         case GEN5_PARAMETER_ACT_INTERVL_ID:
1450                 parameter_size = GEN5_PARAMETER_ACT_INTERVL_SIZE;
1451                 break;
1452         case GEN5_PARAMETER_ACT_LFT_INTERVL_ID:
1453                 parameter_size = GEN5_PARAMETER_ACT_LFT_INTERVL_SIZE;
1454                 break;
1455         case GEN5_PARAMETER_LP_INTRVL_ID:
1456                 parameter_size = GEN5_PARAMETER_LP_INTRVL_SIZE;
1457                 break;
1458         default:
1459                 return -EINVAL;
1460         }
1461
1462         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
1463         /*
1464          * Don't include unused parameter value bytes and
1465          * 2 bytes register address.
1466          */
1467         put_unaligned_le16(cmd_len - (4 - parameter_size) - 2,
1468                            &app_cmd_head->length);
1469         app_cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
1470         app_cmd_head->cmd_code = GEN5_CMD_SET_PARAMETER;
1471         parameter_data->parameter_id = parameter_id;
1472         parameter_data->parameter_size = parameter_size;
1473         put_unaligned_le32((u32)interval_time, &parameter_data->value);
1474         resp_len = sizeof(resp_data);
1475         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
1476                         resp_data, &resp_len,
1477                         500, cyapa_sort_tsg_pip_app_resp_data, false);
1478         if (error || resp_data[5] != parameter_id ||
1479                 resp_data[6] != parameter_size ||
1480                 !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_SET_PARAMETER))
1481                 return error < 0 ? error : -EINVAL;
1482
1483         return 0;
1484 }
1485
1486 static int cyapa_gen5_get_interval_time(struct cyapa *cyapa,
1487                 u8 parameter_id, u16 *interval_time)
1488 {
1489         struct pip_app_cmd_head *app_cmd_head;
1490         struct gen5_app_get_parameter_data *parameter_data;
1491         u8 cmd[CYAPA_TSG_MAX_CMD_SIZE];
1492         int cmd_len;
1493         u8 resp_data[11];
1494         int resp_len;
1495         u8 parameter_size;
1496         u16 mask, i;
1497         int error;
1498
1499         memset(cmd, 0, CYAPA_TSG_MAX_CMD_SIZE);
1500         app_cmd_head = (struct pip_app_cmd_head *)cmd;
1501         parameter_data = (struct gen5_app_get_parameter_data *)
1502                          app_cmd_head->parameter_data;
1503         cmd_len = sizeof(struct pip_app_cmd_head) +
1504                   sizeof(struct gen5_app_get_parameter_data);
1505
1506         *interval_time = 0;
1507         switch (parameter_id) {
1508         case GEN5_PARAMETER_ACT_INTERVL_ID:
1509                 parameter_size = GEN5_PARAMETER_ACT_INTERVL_SIZE;
1510                 break;
1511         case GEN5_PARAMETER_ACT_LFT_INTERVL_ID:
1512                 parameter_size = GEN5_PARAMETER_ACT_LFT_INTERVL_SIZE;
1513                 break;
1514         case GEN5_PARAMETER_LP_INTRVL_ID:
1515                 parameter_size = GEN5_PARAMETER_LP_INTRVL_SIZE;
1516                 break;
1517         default:
1518                 return -EINVAL;
1519         }
1520
1521         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
1522         /* Don't include 2 bytes register address */
1523         put_unaligned_le16(cmd_len - 2, &app_cmd_head->length);
1524         app_cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
1525         app_cmd_head->cmd_code = GEN5_CMD_GET_PARAMETER;
1526         parameter_data->parameter_id = parameter_id;
1527
1528         resp_len = sizeof(resp_data);
1529         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, cmd_len,
1530                         resp_data, &resp_len,
1531                         500, cyapa_sort_tsg_pip_app_resp_data, false);
1532         if (error || resp_data[5] != parameter_id || resp_data[6] == 0 ||
1533                 !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_GET_PARAMETER))
1534                 return error < 0 ? error : -EINVAL;
1535
1536         mask = 0;
1537         for (i = 0; i < parameter_size; i++)
1538                 mask |= (0xff << (i * 8));
1539         *interval_time = get_unaligned_le16(&resp_data[7]) & mask;
1540
1541         return 0;
1542 }
1543
1544 static int cyapa_gen5_disable_pip_report(struct cyapa *cyapa)
1545 {
1546         struct pip_app_cmd_head *app_cmd_head;
1547         u8 cmd[10];
1548         u8 resp_data[7];
1549         int resp_len;
1550         int error;
1551
1552         memset(cmd, 0, sizeof(cmd));
1553         app_cmd_head = (struct pip_app_cmd_head *)cmd;
1554
1555         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
1556         put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
1557         app_cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
1558         app_cmd_head->cmd_code = GEN5_CMD_SET_PARAMETER;
1559         app_cmd_head->parameter_data[0] = GEN5_PARAMETER_DISABLE_PIP_REPORT;
1560         app_cmd_head->parameter_data[1] = 0x01;
1561         app_cmd_head->parameter_data[2] = 0x01;
1562         resp_len = sizeof(resp_data);
1563         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1564                         resp_data, &resp_len,
1565                         500, cyapa_sort_tsg_pip_app_resp_data, false);
1566         if (error || resp_data[5] != GEN5_PARAMETER_DISABLE_PIP_REPORT ||
1567                 !VALID_CMD_RESP_HEADER(resp_data, GEN5_CMD_SET_PARAMETER) ||
1568                 resp_data[6] != 0x01)
1569                 return error < 0 ? error : -EINVAL;
1570
1571         return 0;
1572 }
1573
1574 int cyapa_pip_set_proximity(struct cyapa *cyapa, bool enable)
1575 {
1576         u8 cmd[] = { 0x04, 0x00, 0x06, 0x00, 0x2f, 0x00, PIP_SET_PROXIMITY,
1577                      (u8)!!enable
1578         };
1579         u8 resp_data[6];
1580         int resp_len;
1581         int error;
1582
1583         resp_len = sizeof(resp_data);
1584         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1585                         resp_data, &resp_len,
1586                         500, cyapa_sort_tsg_pip_app_resp_data, false);
1587         if (error || !VALID_CMD_RESP_HEADER(resp_data, PIP_SET_PROXIMITY) ||
1588                         !PIP_CMD_COMPLETE_SUCCESS(resp_data)) {
1589                 error = (error == -ETIMEDOUT) ? -EOPNOTSUPP : error;
1590                 return error < 0 ? error : -EINVAL;
1591         }
1592
1593         return 0;
1594 }
1595
1596 int cyapa_pip_deep_sleep(struct cyapa *cyapa, u8 state)
1597 {
1598         u8 cmd[] = { 0x05, 0x00, 0x00, 0x08};
1599         u8 resp_data[5];
1600         int resp_len;
1601         int error;
1602
1603         cmd[2] = state & PIP_DEEP_SLEEP_STATE_MASK;
1604         resp_len = sizeof(resp_data);
1605         error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
1606                         resp_data, &resp_len,
1607                         500, cyapa_sort_pip_deep_sleep_data, false);
1608         if (error || ((resp_data[3] & PIP_DEEP_SLEEP_STATE_MASK) != state))
1609                 return -EINVAL;
1610
1611         return 0;
1612 }
1613
1614 static int cyapa_gen5_set_power_mode(struct cyapa *cyapa,
1615                 u8 power_mode, u16 sleep_time, enum cyapa_pm_stage pm_stage)
1616 {
1617         struct device *dev = &cyapa->client->dev;
1618         u8 power_state;
1619         int error = 0;
1620
1621         if (cyapa->state != CYAPA_STATE_GEN5_APP)
1622                 return 0;
1623
1624         cyapa_set_pip_pm_state(cyapa, pm_stage);
1625
1626         if (PIP_DEV_GET_PWR_STATE(cyapa) == UNINIT_PWR_MODE) {
1627                 /*
1628                  * Assume TP in deep sleep mode when driver is loaded,
1629                  * avoid driver unload and reload command IO issue caused by TP
1630                  * has been set into deep sleep mode when unloading.
1631                  */
1632                 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
1633         }
1634
1635         if (PIP_DEV_UNINIT_SLEEP_TIME(cyapa) &&
1636                         PIP_DEV_GET_PWR_STATE(cyapa) != PWR_MODE_OFF)
1637                 if (cyapa_gen5_get_interval_time(cyapa,
1638                                 GEN5_PARAMETER_LP_INTRVL_ID,
1639                                 &cyapa->dev_sleep_time) != 0)
1640                         PIP_DEV_SET_SLEEP_TIME(cyapa, UNINIT_SLEEP_TIME);
1641
1642         if (PIP_DEV_GET_PWR_STATE(cyapa) == power_mode) {
1643                 if (power_mode == PWR_MODE_OFF ||
1644                         power_mode == PWR_MODE_FULL_ACTIVE ||
1645                         power_mode == PWR_MODE_BTN_ONLY ||
1646                         PIP_DEV_GET_SLEEP_TIME(cyapa) == sleep_time) {
1647                         /* Has in correct power mode state, early return. */
1648                         goto out;
1649                 }
1650         }
1651
1652         if (power_mode == PWR_MODE_OFF) {
1653                 error = cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_OFF);
1654                 if (error) {
1655                         dev_err(dev, "enter deep sleep fail: %d\n", error);
1656                         goto out;
1657                 }
1658
1659                 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
1660                 goto out;
1661         }
1662
1663         /*
1664          * When trackpad in power off mode, it cannot change to other power
1665          * state directly, must be wake up from sleep firstly, then
1666          * continue to do next power sate change.
1667          */
1668         if (PIP_DEV_GET_PWR_STATE(cyapa) == PWR_MODE_OFF) {
1669                 error = cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_ON);
1670                 if (error) {
1671                         dev_err(dev, "deep sleep wake fail: %d\n", error);
1672                         goto out;
1673                 }
1674         }
1675
1676         if (power_mode == PWR_MODE_FULL_ACTIVE) {
1677                 error = cyapa_gen5_change_power_state(cyapa,
1678                                 GEN5_POWER_STATE_ACTIVE);
1679                 if (error) {
1680                         dev_err(dev, "change to active fail: %d\n", error);
1681                         goto out;
1682                 }
1683
1684                 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_FULL_ACTIVE);
1685         } else if (power_mode == PWR_MODE_BTN_ONLY) {
1686                 error = cyapa_gen5_change_power_state(cyapa,
1687                                 GEN5_POWER_STATE_BTN_ONLY);
1688                 if (error) {
1689                         dev_err(dev, "fail to button only mode: %d\n", error);
1690                         goto out;
1691                 }
1692
1693                 PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_BTN_ONLY);
1694         } else {
1695                 /*
1696                  * Continue to change power mode even failed to set
1697                  * interval time, it won't affect the power mode change.
1698                  * except the sleep interval time is not correct.
1699                  */
1700                 if (PIP_DEV_UNINIT_SLEEP_TIME(cyapa) ||
1701                                 sleep_time != PIP_DEV_GET_SLEEP_TIME(cyapa))
1702                         if (cyapa_gen5_set_interval_time(cyapa,
1703                                         GEN5_PARAMETER_LP_INTRVL_ID,
1704                                         sleep_time) == 0)
1705                                 PIP_DEV_SET_SLEEP_TIME(cyapa, sleep_time);
1706
1707                 if (sleep_time <= GEN5_POWER_READY_MAX_INTRVL_TIME)
1708                         power_state = GEN5_POWER_STATE_READY;
1709                 else
1710                         power_state = GEN5_POWER_STATE_IDLE;
1711                 error = cyapa_gen5_change_power_state(cyapa, power_state);
1712                 if (error) {
1713                         dev_err(dev, "set power state to 0x%02x failed: %d\n",
1714                                 power_state, error);
1715                         goto out;
1716                 }
1717
1718                 /*
1719                  * Disable pip report for a little time, firmware will
1720                  * re-enable it automatically. It's used to fix the issue
1721                  * that trackpad unable to report signal to wake system up
1722                  * in the special situation that system is in suspending, and
1723                  * at the same time, user touch trackpad to wake system up.
1724                  * This function can avoid the data to be buffered when system
1725                  * is suspending which may cause interrupt line unable to be
1726                  * asserted again.
1727                  */
1728                 if (pm_stage == CYAPA_PM_SUSPEND)
1729                         cyapa_gen5_disable_pip_report(cyapa);
1730
1731                 PIP_DEV_SET_PWR_STATE(cyapa,
1732                         cyapa_sleep_time_to_pwr_cmd(sleep_time));
1733         }
1734
1735 out:
1736         cyapa_reset_pip_pm_state(cyapa);
1737         return error;
1738 }
1739
1740 int cyapa_pip_resume_scanning(struct cyapa *cyapa)
1741 {
1742         u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x04 };
1743         u8 resp_data[6];
1744         int resp_len;
1745         int error;
1746
1747         /* Try to dump all buffered data before doing command. */
1748         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1749
1750         resp_len = sizeof(resp_data);
1751         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1752                         cmd, sizeof(cmd),
1753                         resp_data, &resp_len,
1754                         500, cyapa_sort_tsg_pip_app_resp_data, true);
1755         if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x04))
1756                 return -EINVAL;
1757
1758         /* Try to dump all buffered data when resuming scanning. */
1759         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1760
1761         return 0;
1762 }
1763
1764 int cyapa_pip_suspend_scanning(struct cyapa *cyapa)
1765 {
1766         u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x03 };
1767         u8 resp_data[6];
1768         int resp_len;
1769         int error;
1770
1771         /* Try to dump all buffered data before doing command. */
1772         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1773
1774         resp_len = sizeof(resp_data);
1775         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1776                         cmd, sizeof(cmd),
1777                         resp_data, &resp_len,
1778                         500, cyapa_sort_tsg_pip_app_resp_data, true);
1779         if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x03))
1780                 return -EINVAL;
1781
1782         /* Try to dump all buffered data when suspending scanning. */
1783         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1784
1785         return 0;
1786 }
1787
1788 static int cyapa_pip_calibrate_pwcs(struct cyapa *cyapa,
1789                 u8 calibrate_sensing_mode_type)
1790 {
1791         struct pip_app_cmd_head *app_cmd_head;
1792         u8 cmd[8];
1793         u8 resp_data[6];
1794         int resp_len;
1795         int error;
1796
1797         /* Try to dump all buffered data before doing command. */
1798         cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);
1799
1800         memset(cmd, 0, sizeof(cmd));
1801         app_cmd_head = (struct pip_app_cmd_head *)cmd;
1802         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
1803         put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
1804         app_cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
1805         app_cmd_head->cmd_code = PIP_CMD_CALIBRATE;
1806         app_cmd_head->parameter_data[0] = calibrate_sensing_mode_type;
1807         resp_len = sizeof(resp_data);
1808         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
1809                         cmd, sizeof(cmd),
1810                         resp_data, &resp_len,
1811                         5000, cyapa_sort_tsg_pip_app_resp_data, true);
1812         if (error || !VALID_CMD_RESP_HEADER(resp_data, PIP_CMD_CALIBRATE) ||
1813                         !PIP_CMD_COMPLETE_SUCCESS(resp_data))
1814                 return error < 0 ? error : -EAGAIN;
1815
1816         return 0;
1817 }
1818
1819 ssize_t cyapa_pip_do_calibrate(struct device *dev,
1820                                      struct device_attribute *attr,
1821                                      const char *buf, size_t count)
1822 {
1823         struct cyapa *cyapa = dev_get_drvdata(dev);
1824         int error, calibrate_error;
1825
1826         /* 1. Suspend Scanning*/
1827         error = cyapa_pip_suspend_scanning(cyapa);
1828         if (error)
1829                 return error;
1830
1831         /* 2. Do mutual capacitance fine calibrate. */
1832         calibrate_error = cyapa_pip_calibrate_pwcs(cyapa,
1833                                 PIP_SENSING_MODE_MUTUAL_CAP_FINE);
1834         if (calibrate_error)
1835                 goto resume_scanning;
1836
1837         /* 3. Do self capacitance calibrate. */
1838         calibrate_error = cyapa_pip_calibrate_pwcs(cyapa,
1839                                 PIP_SENSING_MODE_SELF_CAP);
1840         if (calibrate_error)
1841                 goto resume_scanning;
1842
1843 resume_scanning:
1844         /* 4. Resume Scanning*/
1845         error = cyapa_pip_resume_scanning(cyapa);
1846         if (error || calibrate_error)
1847                 return error ? error : calibrate_error;
1848
1849         return count;
1850 }
1851
1852 static s32 twos_complement_to_s32(s32 value, int num_bits)
1853 {
1854         if (value >> (num_bits - 1))
1855                 value |=  -1 << num_bits;
1856         return value;
1857 }
1858
1859 static s32 cyapa_parse_structure_data(u8 data_format, u8 *buf, int buf_len)
1860 {
1861         int data_size;
1862         bool big_endian;
1863         bool unsigned_type;
1864         s32 value;
1865
1866         data_size = (data_format & 0x07);
1867         big_endian = ((data_format & 0x10) == 0x00);
1868         unsigned_type = ((data_format & 0x20) == 0x00);
1869
1870         if (buf_len < data_size)
1871                 return 0;
1872
1873         switch (data_size) {
1874         case 1:
1875                 value  = buf[0];
1876                 break;
1877         case 2:
1878                 if (big_endian)
1879                         value = get_unaligned_be16(buf);
1880                 else
1881                         value = get_unaligned_le16(buf);
1882                 break;
1883         case 4:
1884                 if (big_endian)
1885                         value = get_unaligned_be32(buf);
1886                 else
1887                         value = get_unaligned_le32(buf);
1888                 break;
1889         default:
1890                 /* Should not happen, just as default case here. */
1891                 value = 0;
1892                 break;
1893         }
1894
1895         if (!unsigned_type)
1896                 value = twos_complement_to_s32(value, data_size * 8);
1897
1898         return value;
1899 }
1900
1901 static void cyapa_gen5_guess_electrodes(struct cyapa *cyapa,
1902                 int *electrodes_rx, int *electrodes_tx)
1903 {
1904         if (cyapa->electrodes_rx != 0) {
1905                 *electrodes_rx = cyapa->electrodes_rx;
1906                 *electrodes_tx = (cyapa->electrodes_x == *electrodes_rx) ?
1907                                 cyapa->electrodes_y : cyapa->electrodes_x;
1908         } else {
1909                 *electrodes_tx = min(cyapa->electrodes_x, cyapa->electrodes_y);
1910                 *electrodes_rx = max(cyapa->electrodes_x, cyapa->electrodes_y);
1911         }
1912 }
1913
1914 /*
1915  * Read all the global mutual or self idac data or mutual or self local PWC
1916  * data based on the @idac_data_type.
1917  * If the input value of @data_size is 0, then means read global mutual or
1918  * self idac data. For read global mutual idac data, @idac_max, @idac_min and
1919  * @idac_ave are in order used to return the max value of global mutual idac
1920  * data, the min value of global mutual idac and the average value of the
1921  * global mutual idac data. For read global self idac data, @idac_max is used
1922  * to return the global self cap idac data in Rx direction, @idac_min is used
1923  * to return the global self cap idac data in Tx direction. @idac_ave is not
1924  * used.
1925  * If the input value of @data_size is not 0, than means read the mutual or
1926  * self local PWC data. The @idac_max, @idac_min and @idac_ave are used to
1927  * return the max, min and average value of the mutual or self local PWC data.
1928  * Note, in order to read mutual local PWC data, must read invoke this function
1929  * to read the mutual global idac data firstly to set the correct Rx number
1930  * value, otherwise, the read mutual idac and PWC data may not correct.
1931  */
1932 static int cyapa_gen5_read_idac_data(struct cyapa *cyapa,
1933                 u8 cmd_code, u8 idac_data_type, int *data_size,
1934                 int *idac_max, int *idac_min, int *idac_ave)
1935 {
1936         struct pip_app_cmd_head *cmd_head;
1937         u8 cmd[12];
1938         u8 resp_data[256];
1939         int resp_len;
1940         int read_len;
1941         int value;
1942         u16 offset;
1943         int read_elements;
1944         bool read_global_idac;
1945         int sum, count, max_element_cnt;
1946         int tmp_max, tmp_min, tmp_ave, tmp_sum, tmp_count;
1947         int electrodes_rx, electrodes_tx;
1948         int i;
1949         int error;
1950
1951         if (cmd_code != PIP_RETRIEVE_DATA_STRUCTURE ||
1952                 (idac_data_type != GEN5_RETRIEVE_MUTUAL_PWC_DATA &&
1953                 idac_data_type != GEN5_RETRIEVE_SELF_CAP_PWC_DATA) ||
1954                 !data_size || !idac_max || !idac_min || !idac_ave)
1955                 return -EINVAL;
1956
1957         *idac_max = INT_MIN;
1958         *idac_min = INT_MAX;
1959         sum = count = tmp_count = 0;
1960         electrodes_rx = electrodes_tx = 0;
1961         if (*data_size == 0) {
1962                 /*
1963                  * Read global idac values firstly.
1964                  * Currently, no idac data exceed 4 bytes.
1965                  */
1966                 read_global_idac = true;
1967                 offset = 0;
1968                 *data_size = 4;
1969                 tmp_max = INT_MIN;
1970                 tmp_min = INT_MAX;
1971                 tmp_ave = tmp_sum = tmp_count = 0;
1972
1973                 if (idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA) {
1974                         if (cyapa->aligned_electrodes_rx == 0) {
1975                                 cyapa_gen5_guess_electrodes(cyapa,
1976                                         &electrodes_rx, &electrodes_tx);
1977                                 cyapa->aligned_electrodes_rx =
1978                                         (electrodes_rx + 3) & ~3u;
1979                         }
1980                         max_element_cnt =
1981                                 (cyapa->aligned_electrodes_rx + 7) & ~7u;
1982                 } else {
1983                         max_element_cnt = 2;
1984                 }
1985         } else {
1986                 read_global_idac = false;
1987                 if (*data_size > 4)
1988                         *data_size = 4;
1989                 /* Calculate the start offset in bytes of local PWC data. */
1990                 if (idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA) {
1991                         offset = cyapa->aligned_electrodes_rx * (*data_size);
1992                         if (cyapa->electrodes_rx == cyapa->electrodes_x)
1993                                 electrodes_tx = cyapa->electrodes_y;
1994                         else
1995                                 electrodes_tx = cyapa->electrodes_x;
1996                         max_element_cnt = ((cyapa->aligned_electrodes_rx + 7) &
1997                                                 ~7u) * electrodes_tx;
1998                 } else {
1999                         offset = 2;
2000                         max_element_cnt = cyapa->electrodes_x +
2001                                                 cyapa->electrodes_y;
2002                         max_element_cnt = (max_element_cnt + 3) & ~3u;
2003                 }
2004         }
2005
2006         memset(cmd, 0, sizeof(cmd));
2007         cmd_head = (struct pip_app_cmd_head *)cmd;
2008         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &cmd_head->addr);
2009         put_unaligned_le16(sizeof(cmd) - 2, &cmd_head->length);
2010         cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
2011         cmd_head->cmd_code = cmd_code;
2012         do {
2013                 read_elements = (256 - GEN5_RESP_DATA_STRUCTURE_OFFSET) /
2014                                 (*data_size);
2015                 read_elements = min(read_elements, max_element_cnt - count);
2016                 read_len = read_elements * (*data_size);
2017
2018                 put_unaligned_le16(offset, &cmd_head->parameter_data[0]);
2019                 put_unaligned_le16(read_len, &cmd_head->parameter_data[2]);
2020                 cmd_head->parameter_data[4] = idac_data_type;
2021                 resp_len = GEN5_RESP_DATA_STRUCTURE_OFFSET + read_len;
2022                 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2023                                 cmd, sizeof(cmd),
2024                                 resp_data, &resp_len,
2025                                 500, cyapa_sort_tsg_pip_app_resp_data,
2026                                 true);
2027                 if (error || resp_len < GEN5_RESP_DATA_STRUCTURE_OFFSET ||
2028                                 !VALID_CMD_RESP_HEADER(resp_data, cmd_code) ||
2029                                 !PIP_CMD_COMPLETE_SUCCESS(resp_data) ||
2030                                 resp_data[6] != idac_data_type)
2031                         return (error < 0) ? error : -EAGAIN;
2032                 read_len = get_unaligned_le16(&resp_data[7]);
2033                 if (read_len == 0)
2034                         break;
2035
2036                 *data_size = (resp_data[9] & GEN5_PWC_DATA_ELEMENT_SIZE_MASK);
2037                 if (read_len < *data_size)
2038                         return -EINVAL;
2039
2040                 if (read_global_idac &&
2041                         idac_data_type == GEN5_RETRIEVE_SELF_CAP_PWC_DATA) {
2042                         /* Rx's self global idac data. */
2043                         *idac_max = cyapa_parse_structure_data(
2044                                 resp_data[9],
2045                                 &resp_data[GEN5_RESP_DATA_STRUCTURE_OFFSET],
2046                                 *data_size);
2047                         /* Tx's self global idac data. */
2048                         *idac_min = cyapa_parse_structure_data(
2049                                 resp_data[9],
2050                                 &resp_data[GEN5_RESP_DATA_STRUCTURE_OFFSET +
2051                                            *data_size],
2052                                 *data_size);
2053                         break;
2054                 }
2055
2056                 /* Read mutual global idac or local mutual/self PWC data. */
2057                 offset += read_len;
2058                 for (i = 10; i < (read_len + GEN5_RESP_DATA_STRUCTURE_OFFSET);
2059                                 i += *data_size) {
2060                         value = cyapa_parse_structure_data(resp_data[9],
2061                                         &resp_data[i], *data_size);
2062                         *idac_min = min(value, *idac_min);
2063                         *idac_max = max(value, *idac_max);
2064
2065                         if (idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA &&
2066                                 tmp_count < cyapa->aligned_electrodes_rx &&
2067                                 read_global_idac) {
2068                                 /*
2069                                  * The value gap between global and local mutual
2070                                  * idac data must bigger than 50%.
2071                                  * Normally, global value bigger than 50,
2072                                  * local values less than 10.
2073                                  */
2074                                 if (!tmp_ave || value > tmp_ave / 2) {
2075                                         tmp_min = min(value, tmp_min);
2076                                         tmp_max = max(value, tmp_max);
2077                                         tmp_sum += value;
2078                                         tmp_count++;
2079
2080                                         tmp_ave = tmp_sum / tmp_count;
2081                                 }
2082                         }
2083
2084                         sum += value;
2085                         count++;
2086
2087                         if (count >= max_element_cnt)
2088                                 goto out;
2089                 }
2090         } while (true);
2091
2092 out:
2093         *idac_ave = count ? (sum / count) : 0;
2094
2095         if (read_global_idac &&
2096                 idac_data_type == GEN5_RETRIEVE_MUTUAL_PWC_DATA) {
2097                 if (tmp_count == 0)
2098                         return 0;
2099
2100                 if (tmp_count == cyapa->aligned_electrodes_rx) {
2101                         cyapa->electrodes_rx = cyapa->electrodes_rx ?
2102                                 cyapa->electrodes_rx : electrodes_rx;
2103                 } else if (tmp_count == electrodes_rx) {
2104                         cyapa->electrodes_rx = cyapa->electrodes_rx ?
2105                                 cyapa->electrodes_rx : electrodes_rx;
2106                         cyapa->aligned_electrodes_rx = electrodes_rx;
2107                 } else {
2108                         cyapa->electrodes_rx = cyapa->electrodes_rx ?
2109                                 cyapa->electrodes_rx : electrodes_tx;
2110                         cyapa->aligned_electrodes_rx = tmp_count;
2111                 }
2112
2113                 *idac_min = tmp_min;
2114                 *idac_max = tmp_max;
2115                 *idac_ave = tmp_ave;
2116         }
2117
2118         return 0;
2119 }
2120
2121 static int cyapa_gen5_read_mutual_idac_data(struct cyapa *cyapa,
2122         int *gidac_mutual_max, int *gidac_mutual_min, int *gidac_mutual_ave,
2123         int *lidac_mutual_max, int *lidac_mutual_min, int *lidac_mutual_ave)
2124 {
2125         int data_size;
2126         int error;
2127
2128         *gidac_mutual_max = *gidac_mutual_min = *gidac_mutual_ave = 0;
2129         *lidac_mutual_max = *lidac_mutual_min = *lidac_mutual_ave = 0;
2130
2131         data_size = 0;
2132         error = cyapa_gen5_read_idac_data(cyapa,
2133                 PIP_RETRIEVE_DATA_STRUCTURE,
2134                 GEN5_RETRIEVE_MUTUAL_PWC_DATA,
2135                 &data_size,
2136                 gidac_mutual_max, gidac_mutual_min, gidac_mutual_ave);
2137         if (error)
2138                 return error;
2139
2140         error = cyapa_gen5_read_idac_data(cyapa,
2141                 PIP_RETRIEVE_DATA_STRUCTURE,
2142                 GEN5_RETRIEVE_MUTUAL_PWC_DATA,
2143                 &data_size,
2144                 lidac_mutual_max, lidac_mutual_min, lidac_mutual_ave);
2145         return error;
2146 }
2147
2148 static int cyapa_gen5_read_self_idac_data(struct cyapa *cyapa,
2149                 int *gidac_self_rx, int *gidac_self_tx,
2150                 int *lidac_self_max, int *lidac_self_min, int *lidac_self_ave)
2151 {
2152         int data_size;
2153         int error;
2154
2155         *gidac_self_rx = *gidac_self_tx = 0;
2156         *lidac_self_max = *lidac_self_min = *lidac_self_ave = 0;
2157
2158         data_size = 0;
2159         error = cyapa_gen5_read_idac_data(cyapa,
2160                 PIP_RETRIEVE_DATA_STRUCTURE,
2161                 GEN5_RETRIEVE_SELF_CAP_PWC_DATA,
2162                 &data_size,
2163                 lidac_self_max, lidac_self_min, lidac_self_ave);
2164         if (error)
2165                 return error;
2166         *gidac_self_rx = *lidac_self_max;
2167         *gidac_self_tx = *lidac_self_min;
2168
2169         error = cyapa_gen5_read_idac_data(cyapa,
2170                 PIP_RETRIEVE_DATA_STRUCTURE,
2171                 GEN5_RETRIEVE_SELF_CAP_PWC_DATA,
2172                 &data_size,
2173                 lidac_self_max, lidac_self_min, lidac_self_ave);
2174         return error;
2175 }
2176
2177 static ssize_t cyapa_gen5_execute_panel_scan(struct cyapa *cyapa)
2178 {
2179         struct pip_app_cmd_head *app_cmd_head;
2180         u8 cmd[7];
2181         u8 resp_data[6];
2182         int resp_len;
2183         int error;
2184
2185         memset(cmd, 0, sizeof(cmd));
2186         app_cmd_head = (struct pip_app_cmd_head *)cmd;
2187         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
2188         put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
2189         app_cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
2190         app_cmd_head->cmd_code = GEN5_CMD_EXECUTE_PANEL_SCAN;
2191         resp_len = sizeof(resp_data);
2192         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2193                         cmd, sizeof(cmd),
2194                         resp_data, &resp_len,
2195                         500, cyapa_sort_tsg_pip_app_resp_data, true);
2196         if (error || resp_len != sizeof(resp_data) ||
2197                         !VALID_CMD_RESP_HEADER(resp_data,
2198                                 GEN5_CMD_EXECUTE_PANEL_SCAN) ||
2199                         !PIP_CMD_COMPLETE_SUCCESS(resp_data))
2200                 return error ? error : -EAGAIN;
2201
2202         return 0;
2203 }
2204
2205 static int cyapa_gen5_read_panel_scan_raw_data(struct cyapa *cyapa,
2206                 u8 cmd_code, u8 raw_data_type, int raw_data_max_num,
2207                 int *raw_data_max, int *raw_data_min, int *raw_data_ave,
2208                 u8 *buffer)
2209 {
2210         struct pip_app_cmd_head *app_cmd_head;
2211         struct gen5_retrieve_panel_scan_data *panel_sacn_data;
2212         u8 cmd[12];
2213         u8 resp_data[256];  /* Max bytes can transfer one time. */
2214         int resp_len;
2215         int read_elements;
2216         int read_len;
2217         u16 offset;
2218         s32 value;
2219         int sum, count;
2220         int data_size;
2221         s32 *intp;
2222         int i;
2223         int error;
2224
2225         if (cmd_code != GEN5_CMD_RETRIEVE_PANEL_SCAN ||
2226                 (raw_data_type > GEN5_PANEL_SCAN_SELF_DIFFCOUNT) ||
2227                 !raw_data_max || !raw_data_min || !raw_data_ave)
2228                 return -EINVAL;
2229
2230         intp = (s32 *)buffer;
2231         *raw_data_max = INT_MIN;
2232         *raw_data_min = INT_MAX;
2233         sum = count = 0;
2234         offset = 0;
2235         /* Assume max element size is 4 currently. */
2236         read_elements = (256 - GEN5_RESP_DATA_STRUCTURE_OFFSET) / 4;
2237         read_len = read_elements * 4;
2238         app_cmd_head = (struct pip_app_cmd_head *)cmd;
2239         put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &app_cmd_head->addr);
2240         put_unaligned_le16(sizeof(cmd) - 2, &app_cmd_head->length);
2241         app_cmd_head->report_id = PIP_APP_CMD_REPORT_ID;
2242         app_cmd_head->cmd_code = cmd_code;
2243         panel_sacn_data = (struct gen5_retrieve_panel_scan_data *)
2244                         app_cmd_head->parameter_data;
2245         do {
2246                 put_unaligned_le16(offset, &panel_sacn_data->read_offset);
2247                 put_unaligned_le16(read_elements,
2248                         &panel_sacn_data->read_elements);
2249                 panel_sacn_data->data_id = raw_data_type;
2250
2251                 resp_len = GEN5_RESP_DATA_STRUCTURE_OFFSET + read_len;
2252                 error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2253                         cmd, sizeof(cmd),
2254                         resp_data, &resp_len,
2255                         500, cyapa_sort_tsg_pip_app_resp_data, true);
2256                 if (error || resp_len < GEN5_RESP_DATA_STRUCTURE_OFFSET ||
2257                                 !VALID_CMD_RESP_HEADER(resp_data, cmd_code) ||
2258                                 !PIP_CMD_COMPLETE_SUCCESS(resp_data) ||
2259                                 resp_data[6] != raw_data_type)
2260                         return error ? error : -EAGAIN;
2261
2262                 read_elements = get_unaligned_le16(&resp_data[7]);
2263                 if (read_elements == 0)
2264                         break;
2265
2266                 data_size = (resp_data[9] & GEN5_PWC_DATA_ELEMENT_SIZE_MASK);
2267                 offset += read_elements;
2268                 if (read_elements) {
2269                         for (i = GEN5_RESP_DATA_STRUCTURE_OFFSET;
2270                              i < (read_elements * data_size +
2271                                         GEN5_RESP_DATA_STRUCTURE_OFFSET);
2272                              i += data_size) {
2273                                 value = cyapa_parse_structure_data(resp_data[9],
2274                                                 &resp_data[i], data_size);
2275                                 *raw_data_min = min(value, *raw_data_min);
2276                                 *raw_data_max = max(value, *raw_data_max);
2277
2278                                 if (intp)
2279                                         put_unaligned_le32(value, &intp[count]);
2280
2281                                 sum += value;
2282                                 count++;
2283
2284                         }
2285                 }
2286
2287                 if (count >= raw_data_max_num)
2288                         break;
2289
2290                 read_elements = (sizeof(resp_data) -
2291                                 GEN5_RESP_DATA_STRUCTURE_OFFSET) / data_size;
2292                 read_len = read_elements * data_size;
2293         } while (true);
2294
2295         *raw_data_ave = count ? (sum / count) : 0;
2296
2297         return 0;
2298 }
2299
2300 static ssize_t cyapa_gen5_show_baseline(struct device *dev,
2301                                    struct device_attribute *attr, char *buf)
2302 {
2303         struct cyapa *cyapa = dev_get_drvdata(dev);
2304         int gidac_mutual_max, gidac_mutual_min, gidac_mutual_ave;
2305         int lidac_mutual_max, lidac_mutual_min, lidac_mutual_ave;
2306         int gidac_self_rx, gidac_self_tx;
2307         int lidac_self_max, lidac_self_min, lidac_self_ave;
2308         int raw_cap_mutual_max, raw_cap_mutual_min, raw_cap_mutual_ave;
2309         int raw_cap_self_max, raw_cap_self_min, raw_cap_self_ave;
2310         int mutual_diffdata_max, mutual_diffdata_min, mutual_diffdata_ave;
2311         int self_diffdata_max, self_diffdata_min, self_diffdata_ave;
2312         int mutual_baseline_max, mutual_baseline_min, mutual_baseline_ave;
2313         int self_baseline_max, self_baseline_min, self_baseline_ave;
2314         int error, resume_error;
2315         int size;
2316
2317         if (!cyapa_is_pip_app_mode(cyapa))
2318                 return -EBUSY;
2319
2320         /* 1. Suspend Scanning*/
2321         error = cyapa_pip_suspend_scanning(cyapa);
2322         if (error)
2323                 return error;
2324
2325         /* 2.  Read global and local mutual IDAC data. */
2326         gidac_self_rx = gidac_self_tx = 0;
2327         error = cyapa_gen5_read_mutual_idac_data(cyapa,
2328                                 &gidac_mutual_max, &gidac_mutual_min,
2329                                 &gidac_mutual_ave, &lidac_mutual_max,
2330                                 &lidac_mutual_min, &lidac_mutual_ave);
2331         if (error)
2332                 goto resume_scanning;
2333
2334         /* 3.  Read global and local self IDAC data. */
2335         error = cyapa_gen5_read_self_idac_data(cyapa,
2336                                 &gidac_self_rx, &gidac_self_tx,
2337                                 &lidac_self_max, &lidac_self_min,
2338                                 &lidac_self_ave);
2339         if (error)
2340                 goto resume_scanning;
2341
2342         /* 4. Execute panel scan. It must be executed before read data. */
2343         error = cyapa_gen5_execute_panel_scan(cyapa);
2344         if (error)
2345                 goto resume_scanning;
2346
2347         /* 5. Retrieve panel scan, mutual cap raw data. */
2348         error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2349                                 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2350                                 GEN5_PANEL_SCAN_MUTUAL_RAW_DATA,
2351                                 cyapa->electrodes_x * cyapa->electrodes_y,
2352                                 &raw_cap_mutual_max, &raw_cap_mutual_min,
2353                                 &raw_cap_mutual_ave,
2354                                 NULL);
2355         if (error)
2356                 goto resume_scanning;
2357
2358         /* 6. Retrieve panel scan, self cap raw data. */
2359         error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2360                                 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2361                                 GEN5_PANEL_SCAN_SELF_RAW_DATA,
2362                                 cyapa->electrodes_x + cyapa->electrodes_y,
2363                                 &raw_cap_self_max, &raw_cap_self_min,
2364                                 &raw_cap_self_ave,
2365                                 NULL);
2366         if (error)
2367                 goto resume_scanning;
2368
2369         /* 7. Retrieve panel scan, mutual cap diffcount raw data. */
2370         error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2371                                 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2372                                 GEN5_PANEL_SCAN_MUTUAL_DIFFCOUNT,
2373                                 cyapa->electrodes_x * cyapa->electrodes_y,
2374                                 &mutual_diffdata_max, &mutual_diffdata_min,
2375                                 &mutual_diffdata_ave,
2376                                 NULL);
2377         if (error)
2378                 goto resume_scanning;
2379
2380         /* 8. Retrieve panel scan, self cap diffcount raw data. */
2381         error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2382                                 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2383                                 GEN5_PANEL_SCAN_SELF_DIFFCOUNT,
2384                                 cyapa->electrodes_x + cyapa->electrodes_y,
2385                                 &self_diffdata_max, &self_diffdata_min,
2386                                 &self_diffdata_ave,
2387                                 NULL);
2388         if (error)
2389                 goto resume_scanning;
2390
2391         /* 9. Retrieve panel scan, mutual cap baseline raw data. */
2392         error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2393                                 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2394                                 GEN5_PANEL_SCAN_MUTUAL_BASELINE,
2395                                 cyapa->electrodes_x * cyapa->electrodes_y,
2396                                 &mutual_baseline_max, &mutual_baseline_min,
2397                                 &mutual_baseline_ave,
2398                                 NULL);
2399         if (error)
2400                 goto resume_scanning;
2401
2402         /* 10. Retrieve panel scan, self cap baseline raw data. */
2403         error = cyapa_gen5_read_panel_scan_raw_data(cyapa,
2404                                 GEN5_CMD_RETRIEVE_PANEL_SCAN,
2405                                 GEN5_PANEL_SCAN_SELF_BASELINE,
2406                                 cyapa->electrodes_x + cyapa->electrodes_y,
2407                                 &self_baseline_max, &self_baseline_min,
2408                                 &self_baseline_ave,
2409                                 NULL);
2410         if (error)
2411                 goto resume_scanning;
2412
2413 resume_scanning:
2414         /* 11. Resume Scanning*/
2415         resume_error = cyapa_pip_resume_scanning(cyapa);
2416         if (resume_error || error)
2417                 return resume_error ? resume_error : error;
2418
2419         /* 12. Output data strings */
2420         size = scnprintf(buf, PAGE_SIZE, "%d %d %d %d %d %d %d %d %d %d %d ",
2421                 gidac_mutual_min, gidac_mutual_max, gidac_mutual_ave,
2422                 lidac_mutual_min, lidac_mutual_max, lidac_mutual_ave,
2423                 gidac_self_rx, gidac_self_tx,
2424                 lidac_self_min, lidac_self_max, lidac_self_ave);
2425         size += scnprintf(buf + size, PAGE_SIZE - size,
2426                 "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
2427                 raw_cap_mutual_min, raw_cap_mutual_max, raw_cap_mutual_ave,
2428                 raw_cap_self_min, raw_cap_self_max, raw_cap_self_ave,
2429                 mutual_diffdata_min, mutual_diffdata_max, mutual_diffdata_ave,
2430                 self_diffdata_min, self_diffdata_max, self_diffdata_ave,
2431                 mutual_baseline_min, mutual_baseline_max, mutual_baseline_ave,
2432                 self_baseline_min, self_baseline_max, self_baseline_ave);
2433         return size;
2434 }
2435
2436 bool cyapa_pip_sort_system_info_data(struct cyapa *cyapa,
2437                 u8 *buf, int len)
2438 {
2439         /* Check the report id and command code */
2440         if (VALID_CMD_RESP_HEADER(buf, 0x02))
2441                 return true;
2442
2443         return false;
2444 }
2445
2446 static int cyapa_gen5_bl_query_data(struct cyapa *cyapa)
2447 {
2448         u8 resp_data[PIP_BL_APP_INFO_RESP_LENGTH];
2449         int resp_len;
2450         int error;
2451
2452         resp_len = sizeof(resp_data);
2453         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2454                         pip_bl_read_app_info, PIP_BL_READ_APP_INFO_CMD_LENGTH,
2455                         resp_data, &resp_len,
2456                         500, cyapa_sort_tsg_pip_bl_resp_data, false);
2457         if (error || resp_len < PIP_BL_APP_INFO_RESP_LENGTH ||
2458                 !PIP_CMD_COMPLETE_SUCCESS(resp_data))
2459                 return error ? error : -EIO;
2460
2461         memcpy(&cyapa->product_id[0], &resp_data[8], 5);
2462         cyapa->product_id[5] = '-';
2463         memcpy(&cyapa->product_id[6], &resp_data[13], 6);
2464         cyapa->product_id[12] = '-';
2465         memcpy(&cyapa->product_id[13], &resp_data[19], 2);
2466         cyapa->product_id[15] = '\0';
2467
2468         cyapa->fw_maj_ver = resp_data[22];
2469         cyapa->fw_min_ver = resp_data[23];
2470
2471         cyapa->platform_ver = (resp_data[26] >> PIP_BL_PLATFORM_VER_SHIFT) &
2472                               PIP_BL_PLATFORM_VER_MASK;
2473
2474         return 0;
2475 }
2476
2477 static int cyapa_gen5_get_query_data(struct cyapa *cyapa)
2478 {
2479         u8 resp_data[PIP_READ_SYS_INFO_RESP_LENGTH];
2480         int resp_len;
2481         u16 product_family;
2482         int error;
2483
2484         resp_len = sizeof(resp_data);
2485         error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
2486                         pip_read_sys_info, PIP_READ_SYS_INFO_CMD_LENGTH,
2487                         resp_data, &resp_len,
2488                         2000, cyapa_pip_sort_system_info_data, false);
2489         if (error || resp_len < sizeof(resp_data))
2490                 return error ? error : -EIO;
2491
2492         product_family = get_unaligned_le16(&resp_data[7]);
2493         if ((product_family & PIP_PRODUCT_FAMILY_MASK) !=
2494                 PIP_PRODUCT_FAMILY_TRACKPAD)
2495                 return -EINVAL;
2496
2497         cyapa->platform_ver = (resp_data[49] >> PIP_BL_PLATFORM_VER_SHIFT) &
2498                               PIP_BL_PLATFORM_VER_MASK;
2499         if (cyapa->gen == CYAPA_GEN5 && cyapa->platform_ver < 2) {
2500                 /* Gen5 firmware that does not support proximity. */
2501                 cyapa->fw_maj_ver = resp_data[15];
2502                 cyapa->fw_min_ver = resp_data[16];
2503         } else {
2504                 cyapa->fw_maj_ver = resp_data[9];
2505                 cyapa->fw_min_ver = resp_data[10];
2506         }
2507
2508         cyapa->electrodes_x = resp_data[52];
2509         cyapa->electrodes_y = resp_data[53];
2510
2511         cyapa->physical_size_x =  get_unaligned_le16(&resp_data[54]) / 100;
2512         cyapa->physical_size_y = get_unaligned_le16(&resp_data[56]) / 100;
2513
2514         cyapa->max_abs_x = get_unaligned_le16(&resp_data[58]);
2515         cyapa->max_abs_y = get_unaligned_le16(&resp_data[60]);
2516
2517         cyapa->max_z = get_unaligned_le16(&resp_data[62]);
2518
2519         cyapa->x_origin = resp_data[64] & 0x01;
2520         cyapa->y_origin = resp_data[65] & 0x01;
2521
2522         cyapa->btn_capability = (resp_data[70] << 3) & CAPABILITY_BTN_MASK;
2523
2524         memcpy(&cyapa->product_id[0], &resp_data[33], 5);
2525         cyapa->product_id[5] = '-';
2526         memcpy(&cyapa->product_id[6], &resp_data[38], 6);
2527         cyapa->product_id[12] = '-';
2528         memcpy(&cyapa->product_id[13], &resp_data[44], 2);
2529         cyapa->product_id[15] = '\0';
2530
2531         if (!cyapa->electrodes_x || !cyapa->electrodes_y ||
2532                 !cyapa->physical_size_x || !cyapa->physical_size_y ||
2533                 !cyapa->max_abs_x || !cyapa->max_abs_y || !cyapa->max_z)
2534                 return -EINVAL;
2535
2536         return 0;
2537 }
2538
2539 static int cyapa_gen5_do_operational_check(struct cyapa *cyapa)
2540 {
2541         struct device *dev = &cyapa->client->dev;
2542         int error;
2543
2544         if (cyapa->gen != CYAPA_GEN5)
2545                 return -ENODEV;
2546
2547         switch (cyapa->state) {
2548         case CYAPA_STATE_GEN5_BL:
2549                 error = cyapa_pip_bl_exit(cyapa);
2550                 if (error) {
2551                         /* Try to update trackpad product information. */
2552                         cyapa_gen5_bl_query_data(cyapa);
2553                         goto out;
2554                 }
2555
2556                 cyapa->state = CYAPA_STATE_GEN5_APP;
2557
2558         case CYAPA_STATE_GEN5_APP:
2559                 /*
2560                  * If trackpad device in deep sleep mode,
2561                  * the app command will fail.
2562                  * So always try to reset trackpad device to full active when
2563                  * the device state is required.
2564                  */
2565                 error = cyapa_gen5_set_power_mode(cyapa,
2566                                 PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
2567                 if (error)
2568                         dev_warn(dev, "%s: failed to set power active mode.\n",
2569                                 __func__);
2570
2571                 /* By default, the trackpad proximity function is enabled. */
2572                 if (cyapa->platform_ver >= 2) {
2573                         error = cyapa_pip_set_proximity(cyapa, true);
2574                         if (error)
2575                                 dev_warn(dev,
2576                                         "%s: failed to enable proximity.\n",
2577                                         __func__);
2578                 }
2579
2580                 /* Get trackpad product information. */
2581                 error = cyapa_gen5_get_query_data(cyapa);
2582                 if (error)
2583                         goto out;
2584                 /* Only support product ID starting with CYTRA */
2585                 if (memcmp(cyapa->product_id, product_id,
2586                                 strlen(product_id)) != 0) {
2587                         dev_err(dev, "%s: unknown product ID (%s)\n",
2588                                 __func__, cyapa->product_id);
2589                         error = -EINVAL;
2590                 }
2591                 break;
2592         default:
2593                 error = -EINVAL;
2594         }
2595
2596 out:
2597         return error;
2598 }
2599
2600 /*
2601  * Return false, do not continue process
2602  * Return true, continue process.
2603  */
2604 bool cyapa_pip_irq_cmd_handler(struct cyapa *cyapa)
2605 {
2606         struct cyapa_pip_cmd_states *pip = &cyapa->cmd_states.pip;
2607         int length;
2608
2609         if (atomic_read(&pip->cmd_issued)) {
2610                 /* Polling command response data. */
2611                 if (pip->is_irq_mode == false)
2612                         return false;
2613
2614                 /*
2615                  * Read out all none command response data.
2616                  * these output data may caused by user put finger on
2617                  * trackpad when host waiting the command response.
2618                  */
2619                 cyapa_i2c_pip_read(cyapa, pip->irq_cmd_buf,
2620                         PIP_RESP_LENGTH_SIZE);
2621                 length = get_unaligned_le16(pip->irq_cmd_buf);
2622                 length = (length <= PIP_RESP_LENGTH_SIZE) ?
2623                                 PIP_RESP_LENGTH_SIZE : length;
2624                 if (length > PIP_RESP_LENGTH_SIZE)
2625                         cyapa_i2c_pip_read(cyapa,
2626                                 pip->irq_cmd_buf, length);
2627                 if (!(pip->resp_sort_func &&
2628                         pip->resp_sort_func(cyapa,
2629                                 pip->irq_cmd_buf, length))) {
2630                         /*
2631                          * Cover the Gen5 V1 firmware issue.
2632                          * The issue is no interrupt would be asserted from
2633                          * trackpad device to host for the command response
2634                          * ready event. Because when there was a finger touch
2635                          * on trackpad device, and the firmware output queue
2636                          * won't be empty (always with touch report data), so
2637                          * the interrupt signal won't be asserted again until
2638                          * the output queue was previous emptied.
2639                          * This issue would happen in the scenario that
2640                          * user always has his/her fingers touched on the
2641                          * trackpad device during system booting/rebooting.
2642                          */
2643                         length = 0;
2644                         if (pip->resp_len)
2645                                 length = *pip->resp_len;
2646                         cyapa_empty_pip_output_data(cyapa,
2647                                         pip->resp_data,
2648                                         &length,
2649                                         pip->resp_sort_func);
2650                         if (pip->resp_len && length != 0) {
2651                                 *pip->resp_len = length;
2652                                 atomic_dec(&pip->cmd_issued);
2653                                 complete(&pip->cmd_ready);
2654                         }
2655                         return false;
2656                 }
2657
2658                 if (pip->resp_data && pip->resp_len) {
2659                         *pip->resp_len = (*pip->resp_len < length) ?
2660                                 *pip->resp_len : length;
2661                         memcpy(pip->resp_data, pip->irq_cmd_buf,
2662                                 *pip->resp_len);
2663                 }
2664                 atomic_dec(&pip->cmd_issued);
2665                 complete(&pip->cmd_ready);
2666                 return false;
2667         }
2668
2669         return true;
2670 }
2671
2672 static void cyapa_pip_report_buttons(struct cyapa *cyapa,
2673                 const struct cyapa_pip_report_data *report_data)
2674 {
2675         struct input_dev *input = cyapa->input;
2676         u8 buttons = report_data->report_head[PIP_BUTTONS_OFFSET];
2677
2678         buttons = (buttons << CAPABILITY_BTN_SHIFT) & CAPABILITY_BTN_MASK;
2679
2680         if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK) {
2681                 input_report_key(input, BTN_LEFT,
2682                         !!(buttons & CAPABILITY_LEFT_BTN_MASK));
2683         }
2684         if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK) {
2685                 input_report_key(input, BTN_MIDDLE,
2686                         !!(buttons & CAPABILITY_MIDDLE_BTN_MASK));
2687         }
2688         if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK) {
2689                 input_report_key(input, BTN_RIGHT,
2690                         !!(buttons & CAPABILITY_RIGHT_BTN_MASK));
2691         }
2692
2693         input_sync(input);
2694 }
2695
2696 static void cyapa_pip_report_proximity(struct cyapa *cyapa,
2697                 const struct cyapa_pip_report_data *report_data)
2698 {
2699         struct input_dev *input = cyapa->input;
2700         u8 distance = report_data->report_head[PIP_PROXIMITY_DISTANCE_OFFSET] &
2701                         PIP_PROXIMITY_DISTANCE_MASK;
2702
2703         input_report_abs(input, ABS_DISTANCE, distance);
2704         input_sync(input);
2705 }
2706
2707 static void cyapa_pip_report_slot_data(struct cyapa *cyapa,
2708                 const struct cyapa_pip_touch_record *touch)
2709 {
2710         struct input_dev *input = cyapa->input;
2711         u8 event_id = PIP_GET_EVENT_ID(touch->touch_tip_event_id);
2712         int slot = PIP_GET_TOUCH_ID(touch->touch_tip_event_id);
2713         int x, y;
2714
2715         if (event_id == RECORD_EVENT_LIFTOFF)
2716                 return;
2717
2718         input_mt_slot(input, slot);
2719         input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
2720         x = (touch->x_hi << 8) | touch->x_lo;
2721         if (cyapa->x_origin)
2722                 x = cyapa->max_abs_x - x;
2723         y = (touch->y_hi << 8) | touch->y_lo;
2724         if (cyapa->y_origin)
2725                 y = cyapa->max_abs_y - y;
2726         input_report_abs(input, ABS_MT_POSITION_X, x);
2727         input_report_abs(input, ABS_MT_POSITION_Y, y);
2728         input_report_abs(input, ABS_DISTANCE, 0);
2729         input_report_abs(input, ABS_MT_PRESSURE,
2730                 touch->z);
2731         input_report_abs(input, ABS_MT_TOUCH_MAJOR,
2732                 touch->major_axis_len);
2733         input_report_abs(input, ABS_MT_TOUCH_MINOR,
2734                 touch->minor_axis_len);
2735
2736         input_report_abs(input, ABS_MT_WIDTH_MAJOR,
2737                 touch->major_tool_len);
2738         input_report_abs(input, ABS_MT_WIDTH_MINOR,
2739                 touch->minor_tool_len);
2740
2741         input_report_abs(input, ABS_MT_ORIENTATION,
2742                 touch->orientation);
2743 }
2744
2745 static void cyapa_pip_report_touches(struct cyapa *cyapa,
2746                 const struct cyapa_pip_report_data *report_data)
2747 {
2748         struct input_dev *input = cyapa->input;
2749         unsigned int touch_num;
2750         int i;
2751
2752         touch_num = report_data->report_head[PIP_NUMBER_OF_TOUCH_OFFSET] &
2753                         PIP_NUMBER_OF_TOUCH_MASK;
2754
2755         for (i = 0; i < touch_num; i++)
2756                 cyapa_pip_report_slot_data(cyapa,
2757                         &report_data->touch_records[i]);
2758
2759         input_mt_sync_frame(input);
2760         input_sync(input);
2761 }
2762
2763 int cyapa_pip_irq_handler(struct cyapa *cyapa)
2764 {
2765         struct device *dev = &cyapa->client->dev;
2766         struct cyapa_pip_report_data report_data;
2767         unsigned int report_len;
2768         int ret;
2769
2770         if (!cyapa_is_pip_app_mode(cyapa)) {
2771                 dev_err(dev, "invalid device state, gen=%d, state=0x%02x\n",
2772                         cyapa->gen, cyapa->state);
2773                 return -EINVAL;
2774         }
2775
2776         ret = cyapa_i2c_pip_read(cyapa, (u8 *)&report_data,
2777                         PIP_RESP_LENGTH_SIZE);
2778         if (ret != PIP_RESP_LENGTH_SIZE) {
2779                 dev_err(dev, "failed to read length bytes, (%d)\n", ret);
2780                 return -EINVAL;
2781         }
2782
2783         report_len = get_unaligned_le16(
2784                         &report_data.report_head[PIP_RESP_LENGTH_OFFSET]);
2785         if (report_len < PIP_RESP_LENGTH_SIZE) {
2786                 /* Invalid length or internal reset happened. */
2787                 dev_err(dev, "invalid report_len=%d. bytes: %02x %02x\n",
2788                         report_len, report_data.report_head[0],
2789                         report_data.report_head[1]);
2790                 return -EINVAL;
2791         }
2792
2793         /* Idle, no data for report. */
2794         if (report_len == PIP_RESP_LENGTH_SIZE)
2795                 return 0;
2796
2797         ret = cyapa_i2c_pip_read(cyapa, (u8 *)&report_data, report_len);
2798         if (ret != report_len) {
2799                 dev_err(dev, "failed to read %d bytes report data, (%d)\n",
2800                         report_len, ret);
2801                 return -EINVAL;
2802         }
2803
2804         return cyapa_pip_event_process(cyapa, &report_data);
2805 }
2806
2807 static int cyapa_pip_event_process(struct cyapa *cyapa,
2808                                    struct cyapa_pip_report_data *report_data)
2809 {
2810         struct device *dev = &cyapa->client->dev;
2811         unsigned int report_len;
2812         u8 report_id;
2813
2814         report_len = get_unaligned_le16(
2815                         &report_data->report_head[PIP_RESP_LENGTH_OFFSET]);
2816         /* Idle, no data for report. */
2817         if (report_len == PIP_RESP_LENGTH_SIZE)
2818                 return 0;
2819
2820         report_id = report_data->report_head[PIP_RESP_REPORT_ID_OFFSET];
2821         if (report_id == PIP_WAKEUP_EVENT_REPORT_ID &&
2822                         report_len == PIP_WAKEUP_EVENT_SIZE) {
2823                 /*
2824                  * Device wake event from deep sleep mode for touch.
2825                  * This interrupt event is used to wake system up.
2826                  *
2827                  * Note:
2828                  * It will introduce about 20~40 ms additional delay
2829                  * time in receiving for first valid touch report data.
2830                  * The time is used to execute device runtime resume
2831                  * process.
2832                  */
2833                 pm_runtime_get_sync(dev);
2834                 pm_runtime_mark_last_busy(dev);
2835                 pm_runtime_put_sync_autosuspend(dev);
2836                 return 0;
2837         } else if (report_id != PIP_TOUCH_REPORT_ID &&
2838                         report_id != PIP_BTN_REPORT_ID &&
2839                         report_id != GEN5_OLD_PUSH_BTN_REPORT_ID &&
2840                         report_id != PIP_PUSH_BTN_REPORT_ID &&
2841                         report_id != PIP_PROXIMITY_REPORT_ID) {
2842                 /* Running in BL mode or unknown response data read. */
2843                 dev_err(dev, "invalid report_id=0x%02x\n", report_id);
2844                 return -EINVAL;
2845         }
2846
2847         if (report_id == PIP_TOUCH_REPORT_ID &&
2848                 (report_len < PIP_TOUCH_REPORT_HEAD_SIZE ||
2849                         report_len > PIP_TOUCH_REPORT_MAX_SIZE)) {
2850                 /* Invalid report data length for finger packet. */
2851                 dev_err(dev, "invalid touch packet length=%d\n", report_len);
2852                 return 0;
2853         }
2854
2855         if ((report_id == PIP_BTN_REPORT_ID ||
2856                         report_id == GEN5_OLD_PUSH_BTN_REPORT_ID ||
2857                         report_id == PIP_PUSH_BTN_REPORT_ID) &&
2858                 (report_len < PIP_BTN_REPORT_HEAD_SIZE ||
2859                         report_len > PIP_BTN_REPORT_MAX_SIZE)) {
2860                 /* Invalid report data length of button packet. */
2861                 dev_err(dev, "invalid button packet length=%d\n", report_len);
2862                 return 0;
2863         }
2864
2865         if (report_id == PIP_PROXIMITY_REPORT_ID &&
2866                         report_len != PIP_PROXIMITY_REPORT_SIZE) {
2867                 /* Invalid report data length of proximity packet. */
2868                 dev_err(dev, "invalid proximity data, length=%d\n", report_len);
2869                 return 0;
2870         }
2871
2872         if (report_id == PIP_TOUCH_REPORT_ID)
2873                 cyapa_pip_report_touches(cyapa, report_data);
2874         else if (report_id == PIP_PROXIMITY_REPORT_ID)
2875                 cyapa_pip_report_proximity(cyapa, report_data);
2876         else
2877                 cyapa_pip_report_buttons(cyapa, report_data);
2878
2879         return 0;
2880 }
2881
2882 int cyapa_pip_bl_activate(struct cyapa *cyapa) { return 0; }
2883 int cyapa_pip_bl_deactivate(struct cyapa *cyapa) { return 0; }
2884
2885
2886 const struct cyapa_dev_ops cyapa_gen5_ops = {
2887         .check_fw = cyapa_pip_check_fw,
2888         .bl_enter = cyapa_pip_bl_enter,
2889         .bl_initiate = cyapa_pip_bl_initiate,
2890         .update_fw = cyapa_pip_do_fw_update,
2891         .bl_activate = cyapa_pip_bl_activate,
2892         .bl_deactivate = cyapa_pip_bl_deactivate,
2893
2894         .show_baseline = cyapa_gen5_show_baseline,
2895         .calibrate_store = cyapa_pip_do_calibrate,
2896
2897         .initialize = cyapa_pip_cmd_state_initialize,
2898
2899         .state_parse = cyapa_gen5_state_parse,
2900         .operational_check = cyapa_gen5_do_operational_check,
2901
2902         .irq_handler = cyapa_pip_irq_handler,
2903         .irq_cmd_handler = cyapa_pip_irq_cmd_handler,
2904         .sort_empty_output_data = cyapa_empty_pip_output_data,
2905         .set_power_mode = cyapa_gen5_set_power_mode,
2906
2907         .set_proximity = cyapa_pip_set_proximity,
2908 };