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