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