Linux Audio

Check our new training course

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