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