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