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