/*
 * Cypress APA trackpad with I2C interface
 *
 * Author: Dudley Du <dudl@cypress.com>
 *
 * Copyright (C) 2015 Cypress Semiconductor, Inc.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 */

#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/mutex.h>
#include <linux/completion.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include <linux/crc-itu-t.h>
#include "cyapa.h"


#define GEN6_ENABLE_CMD_IRQ	0x41
#define GEN6_DISABLE_CMD_IRQ	0x42
#define GEN6_ENABLE_DEV_IRQ	0x43
#define GEN6_DISABLE_DEV_IRQ	0x44

#define GEN6_POWER_MODE_ACTIVE		0x01
#define GEN6_POWER_MODE_LP_MODE1	0x02
#define GEN6_POWER_MODE_LP_MODE2	0x03
#define GEN6_POWER_MODE_BTN_ONLY	0x04

#define GEN6_SET_POWER_MODE_INTERVAL	0x47
#define GEN6_GET_POWER_MODE_INTERVAL	0x48

#define GEN6_MAX_RX_NUM 14
#define GEN6_RETRIEVE_DATA_ID_RX_ATTENURATOR_IDAC	0x00
#define GEN6_RETRIEVE_DATA_ID_ATTENURATOR_TRIM		0x12


struct pip_app_cmd_head {
	__le16 addr;
	__le16 length;
	u8 report_id;
	u8 resv;  /* Reserved, must be 0 */
	u8 cmd_code;  /* bit7: resv, set to 0; bit6~0: command code.*/
} __packed;

struct pip_app_resp_head {
	__le16 length;
	u8 report_id;
	u8 resv;  /* Reserved, must be 0 */
	u8 cmd_code;  /* bit7: TGL; bit6~0: command code.*/
	/*
	 * The value of data_status can be the first byte of data or
	 * the command status or the unsupported command code depending on the
	 * requested command code.
	*/
	u8 data_status;
} __packed;

struct pip_fixed_info {
	u8 silicon_id_high;
	u8 silicon_id_low;
	u8 family_id;
};

static u8 pip_get_bl_info[] = {
	0x04, 0x00, 0x0B, 0x00, 0x40, 0x00, 0x01, 0x38,
	0x00, 0x00, 0x70, 0x9E, 0x17
};

static bool cyapa_sort_pip_hid_descriptor_data(struct cyapa *cyapa,
		u8 *buf, int len)
{
	if (len != PIP_HID_DESCRIPTOR_SIZE)
		return false;

	if (buf[PIP_RESP_REPORT_ID_OFFSET] == PIP_HID_APP_REPORT_ID ||
		buf[PIP_RESP_REPORT_ID_OFFSET] == PIP_HID_BL_REPORT_ID)
		return true;

	return false;
}

static int cyapa_get_pip_fixed_info(struct cyapa *cyapa,
		struct pip_fixed_info *pip_info, bool is_bootloader)
{
	u8 resp_data[PIP_READ_SYS_INFO_RESP_LENGTH];
	int resp_len;
	u16 product_family;
	int error;

	if (is_bootloader) {
		/* Read Bootloader Information to determine Gen5 or Gen6. */
		resp_len = sizeof(resp_data);
		error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
				pip_get_bl_info, sizeof(pip_get_bl_info),
				resp_data, &resp_len,
				2000, cyapa_sort_tsg_pip_bl_resp_data,
				false);
		if (error || resp_len < PIP_BL_GET_INFO_RESP_LENGTH)
			return error ? error : -EIO;

		pip_info->family_id = resp_data[8];
		pip_info->silicon_id_low = resp_data[10];
		pip_info->silicon_id_high = resp_data[11];

		return 0;
	}

	/* Get App System Information to determine Gen5 or Gen6. */
	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
			pip_read_sys_info, PIP_READ_SYS_INFO_CMD_LENGTH,
			resp_data, &resp_len,
			2000, cyapa_pip_sort_system_info_data, false);
	if (error || resp_len < PIP_READ_SYS_INFO_RESP_LENGTH)
		return error ? error : -EIO;

	product_family = get_unaligned_le16(&resp_data[7]);
	if ((product_family & PIP_PRODUCT_FAMILY_MASK) !=
		PIP_PRODUCT_FAMILY_TRACKPAD)
		return -EINVAL;

	pip_info->family_id = resp_data[19];
	pip_info->silicon_id_low = resp_data[21];
	pip_info->silicon_id_high = resp_data[22];

	return 0;

}

int cyapa_pip_state_parse(struct cyapa *cyapa, u8 *reg_data, int len)
{
	u8 cmd[] = { 0x01, 0x00};
	struct pip_fixed_info pip_info;
	u8 resp_data[PIP_HID_DESCRIPTOR_SIZE];
	int resp_len;
	bool is_bootloader;
	int error;

	cyapa->state = CYAPA_STATE_NO_DEVICE;

	/* Try to wake from it deep sleep state if it is. */
	cyapa_pip_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_ON);

	/* Empty the buffer queue to get fresh data with later commands. */
	cyapa_empty_pip_output_data(cyapa, NULL, NULL, NULL);

	/*
	 * Read description info from trackpad device to determine running in
	 * APP mode or Bootloader mode.
	 */
	resp_len = PIP_HID_DESCRIPTOR_SIZE;
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
			cmd, sizeof(cmd),
			resp_data, &resp_len,
			300,
			cyapa_sort_pip_hid_descriptor_data,
			false);
	if (error)
		return error;

	if (resp_data[PIP_RESP_REPORT_ID_OFFSET] == PIP_HID_BL_REPORT_ID)
		is_bootloader = true;
	else if (resp_data[PIP_RESP_REPORT_ID_OFFSET] == PIP_HID_APP_REPORT_ID)
		is_bootloader = false;
	else
		return -EAGAIN;

	/* Get PIP fixed information to determine Gen5 or Gen6. */
	memset(&pip_info, 0, sizeof(struct pip_fixed_info));
	error = cyapa_get_pip_fixed_info(cyapa, &pip_info, is_bootloader);
	if (error)
		return error;

	if (pip_info.family_id == 0x9B && pip_info.silicon_id_high == 0x0B) {
		cyapa->gen = CYAPA_GEN6;
		cyapa->state = is_bootloader ? CYAPA_STATE_GEN6_BL
					     : CYAPA_STATE_GEN6_APP;
	} else if (pip_info.family_id == 0x91 &&
		   pip_info.silicon_id_high == 0x02) {
		cyapa->gen = CYAPA_GEN5;
		cyapa->state = is_bootloader ? CYAPA_STATE_GEN5_BL
					     : CYAPA_STATE_GEN5_APP;
	}

	return 0;
}

static int cyapa_gen6_read_sys_info(struct cyapa *cyapa)
{
	u8 resp_data[PIP_READ_SYS_INFO_RESP_LENGTH];
	int resp_len;
	u16 product_family;
	u8 rotat_align;
	int error;

	/* Get App System Information to determine Gen5 or Gen6. */
	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
			pip_read_sys_info, PIP_READ_SYS_INFO_CMD_LENGTH,
			resp_data, &resp_len,
			2000, cyapa_pip_sort_system_info_data, false);
	if (error || resp_len < sizeof(resp_data))
		return error ? error : -EIO;

	product_family = get_unaligned_le16(&resp_data[7]);
	if ((product_family & PIP_PRODUCT_FAMILY_MASK) !=
		PIP_PRODUCT_FAMILY_TRACKPAD)
		return -EINVAL;

	cyapa->platform_ver = (resp_data[67] >> PIP_BL_PLATFORM_VER_SHIFT) &
			      PIP_BL_PLATFORM_VER_MASK;
	cyapa->fw_maj_ver = resp_data[9];
	cyapa->fw_min_ver = resp_data[10];

	cyapa->electrodes_x = resp_data[33];
	cyapa->electrodes_y = resp_data[34];

	cyapa->physical_size_x =  get_unaligned_le16(&resp_data[35]) / 100;
	cyapa->physical_size_y = get_unaligned_le16(&resp_data[37]) / 100;

	cyapa->max_abs_x = get_unaligned_le16(&resp_data[39]);
	cyapa->max_abs_y = get_unaligned_le16(&resp_data[41]);

	cyapa->max_z = get_unaligned_le16(&resp_data[43]);

	cyapa->x_origin = resp_data[45] & 0x01;
	cyapa->y_origin = resp_data[46] & 0x01;

	cyapa->btn_capability = (resp_data[70] << 3) & CAPABILITY_BTN_MASK;

	memcpy(&cyapa->product_id[0], &resp_data[51], 5);
	cyapa->product_id[5] = '-';
	memcpy(&cyapa->product_id[6], &resp_data[56], 6);
	cyapa->product_id[12] = '-';
	memcpy(&cyapa->product_id[13], &resp_data[62], 2);
	cyapa->product_id[15] = '\0';

	/* Get the number of Rx electrodes. */
	rotat_align = resp_data[68];
	cyapa->electrodes_rx =
		rotat_align ? cyapa->electrodes_y : cyapa->electrodes_x;
	cyapa->aligned_electrodes_rx = (cyapa->electrodes_rx + 3) & ~3u;

	if (!cyapa->electrodes_x || !cyapa->electrodes_y ||
		!cyapa->physical_size_x || !cyapa->physical_size_y ||
		!cyapa->max_abs_x || !cyapa->max_abs_y || !cyapa->max_z)
		return -EINVAL;

	return 0;
}

static int cyapa_gen6_bl_read_app_info(struct cyapa *cyapa)
{
	u8 resp_data[PIP_BL_APP_INFO_RESP_LENGTH];
	int resp_len;
	int error;

	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
			pip_bl_read_app_info, PIP_BL_READ_APP_INFO_CMD_LENGTH,
			resp_data, &resp_len,
			500, cyapa_sort_tsg_pip_bl_resp_data, false);
	if (error || resp_len < PIP_BL_APP_INFO_RESP_LENGTH ||
		!PIP_CMD_COMPLETE_SUCCESS(resp_data))
		return error ? error : -EIO;

	cyapa->fw_maj_ver = resp_data[8];
	cyapa->fw_min_ver = resp_data[9];

	cyapa->platform_ver = (resp_data[12] >> PIP_BL_PLATFORM_VER_SHIFT) &
			      PIP_BL_PLATFORM_VER_MASK;

	memcpy(&cyapa->product_id[0], &resp_data[13], 5);
	cyapa->product_id[5] = '-';
	memcpy(&cyapa->product_id[6], &resp_data[18], 6);
	cyapa->product_id[12] = '-';
	memcpy(&cyapa->product_id[13], &resp_data[24], 2);
	cyapa->product_id[15] = '\0';

	return 0;

}

static int cyapa_gen6_config_dev_irq(struct cyapa *cyapa, u8 cmd_code)
{
	u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, cmd_code };
	u8 resp_data[6];
	int resp_len;
	int error;

	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
			resp_data, &resp_len,
			500, cyapa_sort_tsg_pip_app_resp_data, false);
	if (error || !VALID_CMD_RESP_HEADER(resp_data, cmd_code) ||
			!PIP_CMD_COMPLETE_SUCCESS(resp_data)
			)
		return error < 0 ? error : -EINVAL;

	return 0;
}

static int cyapa_gen6_set_proximity(struct cyapa *cyapa, bool enable)
{
	int error;

	cyapa_gen6_config_dev_irq(cyapa, GEN6_DISABLE_CMD_IRQ);
	error = cyapa_pip_set_proximity(cyapa, enable);
	cyapa_gen6_config_dev_irq(cyapa, GEN6_ENABLE_CMD_IRQ);

	return error;
}

static int cyapa_gen6_change_power_state(struct cyapa *cyapa, u8 power_mode)
{
	u8 cmd[] = { 0x04, 0x00, 0x06, 0x00, 0x2f, 0x00, 0x46, power_mode };
	u8 resp_data[6];
	int resp_len;
	int error;

	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
			resp_data, &resp_len,
			500, cyapa_sort_tsg_pip_app_resp_data, false);
	if (error || !VALID_CMD_RESP_HEADER(resp_data, 0x46))
		return error < 0 ? error : -EINVAL;

	/* New power state applied in device not match the set power state. */
	if (resp_data[5] != power_mode)
		return -EAGAIN;

	return 0;
}

static int cyapa_gen6_set_interval_setting(struct cyapa *cyapa,
		struct gen6_interval_setting *interval_setting)
{
	struct gen6_set_interval_cmd {
		__le16 addr;
		__le16 length;
		u8 report_id;
		u8 rsvd;  /* Reserved, must be 0 */
		u8 cmd_code;
		__le16 active_interval;
		__le16 lp1_interval;
		__le16 lp2_interval;
	} __packed set_interval_cmd;
	u8 resp_data[11];
	int resp_len;
	int error;

	memset(&set_interval_cmd, 0, sizeof(set_interval_cmd));
	put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &set_interval_cmd.addr);
	put_unaligned_le16(sizeof(set_interval_cmd) - 2,
			   &set_interval_cmd.length);
	set_interval_cmd.report_id = PIP_APP_CMD_REPORT_ID;
	set_interval_cmd.cmd_code = GEN6_SET_POWER_MODE_INTERVAL;
	put_unaligned_le16(interval_setting->active_interval,
			   &set_interval_cmd.active_interval);
	put_unaligned_le16(interval_setting->lp1_interval,
			   &set_interval_cmd.lp1_interval);
	put_unaligned_le16(interval_setting->lp2_interval,
			   &set_interval_cmd.lp2_interval);

	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
			(u8 *)&set_interval_cmd, sizeof(set_interval_cmd),
			resp_data, &resp_len,
			500, cyapa_sort_tsg_pip_app_resp_data, false);
	if (error ||
		!VALID_CMD_RESP_HEADER(resp_data, GEN6_SET_POWER_MODE_INTERVAL))
		return error < 0 ? error : -EINVAL;

	/* Get the real set intervals from response. */
	interval_setting->active_interval = get_unaligned_le16(&resp_data[5]);
	interval_setting->lp1_interval = get_unaligned_le16(&resp_data[7]);
	interval_setting->lp2_interval = get_unaligned_le16(&resp_data[9]);

	return 0;
}

static int cyapa_gen6_get_interval_setting(struct cyapa *cyapa,
		struct gen6_interval_setting *interval_setting)
{
	u8 cmd[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00,
		     GEN6_GET_POWER_MODE_INTERVAL };
	u8 resp_data[11];
	int resp_len;
	int error;

	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa, cmd, sizeof(cmd),
			resp_data, &resp_len,
			500, cyapa_sort_tsg_pip_app_resp_data, false);
	if (error ||
		!VALID_CMD_RESP_HEADER(resp_data, GEN6_GET_POWER_MODE_INTERVAL))
		return error < 0 ? error : -EINVAL;

	interval_setting->active_interval = get_unaligned_le16(&resp_data[5]);
	interval_setting->lp1_interval = get_unaligned_le16(&resp_data[7]);
	interval_setting->lp2_interval = get_unaligned_le16(&resp_data[9]);

	return 0;
}

static int cyapa_gen6_deep_sleep(struct cyapa *cyapa, u8 state)
{
	u8 ping[] = { 0x04, 0x00, 0x05, 0x00, 0x2f, 0x00, 0x00 };

	if (state == PIP_DEEP_SLEEP_STATE_ON)
		/*
		 * Send ping command to notify device prepare for wake up
		 * when it's in deep sleep mode. At this time, device will
		 * response nothing except an I2C NAK.
		 */
		cyapa_i2c_pip_write(cyapa, ping, sizeof(ping));

	return cyapa_pip_deep_sleep(cyapa, state);
}

static int cyapa_gen6_set_power_mode(struct cyapa *cyapa,
		u8 power_mode, u16 sleep_time, enum cyapa_pm_stage pm_stage)
{
	struct device *dev = &cyapa->client->dev;
	struct gen6_interval_setting *interval_setting =
			&cyapa->gen6_interval_setting;
	u8 lp_mode;
	int error;

	if (cyapa->state != CYAPA_STATE_GEN6_APP)
		return 0;

	if (PIP_DEV_GET_PWR_STATE(cyapa) == UNINIT_PWR_MODE) {
		/*
		 * Assume TP in deep sleep mode when driver is loaded,
		 * avoid driver unload and reload command IO issue caused by TP
		 * has been set into deep sleep mode when unloading.
		 */
		PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
	}

	if (PIP_DEV_UNINIT_SLEEP_TIME(cyapa) &&
		PIP_DEV_GET_PWR_STATE(cyapa) != PWR_MODE_OFF)
		PIP_DEV_SET_SLEEP_TIME(cyapa, UNINIT_SLEEP_TIME);

	if (PIP_DEV_GET_PWR_STATE(cyapa) == power_mode) {
		if (power_mode == PWR_MODE_OFF ||
			power_mode == PWR_MODE_FULL_ACTIVE ||
			power_mode == PWR_MODE_BTN_ONLY ||
			PIP_DEV_GET_SLEEP_TIME(cyapa) == sleep_time) {
			/* Has in correct power mode state, early return. */
			return 0;
		}
	}

	if (power_mode == PWR_MODE_OFF) {
		cyapa_gen6_config_dev_irq(cyapa, GEN6_DISABLE_CMD_IRQ);

		error = cyapa_gen6_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_OFF);
		if (error) {
			dev_err(dev, "enter deep sleep fail: %d\n", error);
			return error;
		}

		PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_OFF);
		return 0;
	}

	/*
	 * When trackpad in power off mode, it cannot change to other power
	 * state directly, must be wake up from sleep firstly, then
	 * continue to do next power sate change.
	 */
	if (PIP_DEV_GET_PWR_STATE(cyapa) == PWR_MODE_OFF) {
		error = cyapa_gen6_deep_sleep(cyapa, PIP_DEEP_SLEEP_STATE_ON);
		if (error) {
			dev_err(dev, "deep sleep wake fail: %d\n", error);
			return error;
		}
	}

	/*
	 * Disable device assert interrupts for command response to avoid
	 * disturbing system suspending or hibernating process.
	 */
	cyapa_gen6_config_dev_irq(cyapa, GEN6_DISABLE_CMD_IRQ);

	if (power_mode == PWR_MODE_FULL_ACTIVE) {
		error = cyapa_gen6_change_power_state(cyapa,
				GEN6_POWER_MODE_ACTIVE);
		if (error) {
			dev_err(dev, "change to active fail: %d\n", error);
			goto out;
		}

		PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_FULL_ACTIVE);

		/* Sync the interval setting from device. */
		cyapa_gen6_get_interval_setting(cyapa, interval_setting);

	} else if (power_mode == PWR_MODE_BTN_ONLY) {
		error = cyapa_gen6_change_power_state(cyapa,
				GEN6_POWER_MODE_BTN_ONLY);
		if (error) {
			dev_err(dev, "fail to button only mode: %d\n", error);
			goto out;
		}

		PIP_DEV_SET_PWR_STATE(cyapa, PWR_MODE_BTN_ONLY);
	} else {
		/*
		 * Gen6 internally supports to 2 low power scan interval time,
		 * so can help to switch power mode quickly.
		 * such as runtime suspend and system suspend.
		 */
		if (interval_setting->lp1_interval == sleep_time) {
			lp_mode = GEN6_POWER_MODE_LP_MODE1;
		} else if (interval_setting->lp2_interval == sleep_time) {
			lp_mode = GEN6_POWER_MODE_LP_MODE2;
		} else {
			if (interval_setting->lp1_interval == 0) {
				interval_setting->lp1_interval = sleep_time;
				lp_mode = GEN6_POWER_MODE_LP_MODE1;
			} else {
				interval_setting->lp2_interval = sleep_time;
				lp_mode = GEN6_POWER_MODE_LP_MODE2;
			}
			cyapa_gen6_set_interval_setting(cyapa,
							interval_setting);
		}

		error = cyapa_gen6_change_power_state(cyapa, lp_mode);
		if (error) {
			dev_err(dev, "set power state to 0x%02x failed: %d\n",
				lp_mode, error);
			goto out;
		}

		PIP_DEV_SET_SLEEP_TIME(cyapa, sleep_time);
		PIP_DEV_SET_PWR_STATE(cyapa,
			cyapa_sleep_time_to_pwr_cmd(sleep_time));
	}

out:
	cyapa_gen6_config_dev_irq(cyapa, GEN6_ENABLE_CMD_IRQ);
	return error;
}

static int cyapa_gen6_initialize(struct cyapa *cyapa)
{
	return 0;
}

static int cyapa_pip_retrieve_data_structure(struct cyapa *cyapa,
		u16 read_offset, u16 read_len, u8 data_id,
		u8 *data, int *data_buf_lens)
{
	struct retrieve_data_struct_cmd {
		struct pip_app_cmd_head head;
		__le16 read_offset;
		__le16 read_length;
		u8 data_id;
	} __packed cmd;
	u8 resp_data[GEN6_MAX_RX_NUM + 10];
	int resp_len;
	int error;

	memset(&cmd, 0, sizeof(cmd));
	put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &cmd.head.addr);
	put_unaligned_le16(sizeof(cmd) - 2, &cmd.head.length);
	cmd.head.report_id = PIP_APP_CMD_REPORT_ID;
	cmd.head.cmd_code = PIP_RETRIEVE_DATA_STRUCTURE;
	put_unaligned_le16(read_offset, &cmd.read_offset);
	put_unaligned_le16(read_len, &cmd.read_length);
	cmd.data_id = data_id;

	resp_len = sizeof(resp_data);
	error = cyapa_i2c_pip_cmd_irq_sync(cyapa,
				(u8 *)&cmd, sizeof(cmd),
				resp_data, &resp_len,
				500, cyapa_sort_tsg_pip_app_resp_data,
				true);
	if (error || !PIP_CMD_COMPLETE_SUCCESS(resp_data) ||
		resp_data[6] != data_id ||
		!VALID_CMD_RESP_HEADER(resp_data, PIP_RETRIEVE_DATA_STRUCTURE))
		return (error < 0) ? error : -EAGAIN;

	read_len = get_unaligned_le16(&resp_data[7]);
	if (*data_buf_lens < read_len) {
		*data_buf_lens = read_len;
		return -ENOBUFS;
	}

	memcpy(data, &resp_data[10], read_len);
	*data_buf_lens = read_len;
	return 0;
}

static ssize_t cyapa_gen6_show_baseline(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct cyapa *cyapa = dev_get_drvdata(dev);
	u8 data[GEN6_MAX_RX_NUM];
	int data_len;
	int size = 0;
	int i;
	int error;
	int resume_error;

	if (!cyapa_is_pip_app_mode(cyapa))
		return -EBUSY;

	/* 1. Suspend Scanning*/
	error = cyapa_pip_suspend_scanning(cyapa);
	if (error)
		return error;

	/* 2. IDAC and RX Attenuator Calibration Data (Center Frequency). */
	data_len = sizeof(data);
	error = cyapa_pip_retrieve_data_structure(cyapa, 0, data_len,
			GEN6_RETRIEVE_DATA_ID_RX_ATTENURATOR_IDAC,
			data, &data_len);
	if (error)
		goto resume_scanning;

	size = scnprintf(buf, PAGE_SIZE, "%d %d %d %d %d %d ",
			data[0],  /* RX Attenuator Mutual */
			data[1],  /* IDAC Mutual */
			data[2],  /* RX Attenuator Self RX */
			data[3],  /* IDAC Self RX */
			data[4],  /* RX Attenuator Self TX */
			data[5]	  /* IDAC Self TX */
			);

	/* 3. Read Attenuator Trim. */
	data_len = sizeof(data);
	error = cyapa_pip_retrieve_data_structure(cyapa, 0, data_len,
			GEN6_RETRIEVE_DATA_ID_ATTENURATOR_TRIM,
			data, &data_len);
	if (error)
		goto resume_scanning;

	/* set attenuator trim values. */
	for (i = 0; i < data_len; i++)
		size += scnprintf(buf + size, PAGE_SIZE - size,	"%d ", data[i]);
	size += scnprintf(buf + size, PAGE_SIZE - size, "\n");

resume_scanning:
	/* 4. Resume Scanning*/
	resume_error = cyapa_pip_resume_scanning(cyapa);
	if (resume_error || error) {
		memset(buf, 0, PAGE_SIZE);
		return resume_error ? resume_error : error;
	}

	return size;
}

static int cyapa_gen6_operational_check(struct cyapa *cyapa)
{
	struct device *dev = &cyapa->client->dev;
	int error;

	if (cyapa->gen != CYAPA_GEN6)
		return -ENODEV;

	switch (cyapa->state) {
	case CYAPA_STATE_GEN6_BL:
		error = cyapa_pip_bl_exit(cyapa);
		if (error) {
			/* Try to update trackpad product information. */
			cyapa_gen6_bl_read_app_info(cyapa);
			goto out;
		}

		cyapa->state = CYAPA_STATE_GEN6_APP;
		fallthrough;

	case CYAPA_STATE_GEN6_APP:
		/*
		 * If trackpad device in deep sleep mode,
		 * the app command will fail.
		 * So always try to reset trackpad device to full active when
		 * the device state is required.
		 */
		error = cyapa_gen6_set_power_mode(cyapa,
				PWR_MODE_FULL_ACTIVE, 0, CYAPA_PM_ACTIVE);
		if (error)
			dev_warn(dev, "%s: failed to set power active mode.\n",
				__func__);

		/* By default, the trackpad proximity function is enabled. */
		error = cyapa_pip_set_proximity(cyapa, true);
		if (error)
			dev_warn(dev, "%s: failed to enable proximity.\n",
				__func__);

		/* Get trackpad product information. */
		error = cyapa_gen6_read_sys_info(cyapa);
		if (error)
			goto out;
		/* Only support product ID starting with CYTRA */
		if (memcmp(cyapa->product_id, product_id,
				strlen(product_id)) != 0) {
			dev_err(dev, "%s: unknown product ID (%s)\n",
				__func__, cyapa->product_id);
			error = -EINVAL;
		}
		break;
	default:
		error = -EINVAL;
	}

out:
	return error;
}

const struct cyapa_dev_ops cyapa_gen6_ops = {
	.check_fw = cyapa_pip_check_fw,
	.bl_enter = cyapa_pip_bl_enter,
	.bl_initiate = cyapa_pip_bl_initiate,
	.update_fw = cyapa_pip_do_fw_update,
	.bl_activate = cyapa_pip_bl_activate,
	.bl_deactivate = cyapa_pip_bl_deactivate,

	.show_baseline = cyapa_gen6_show_baseline,
	.calibrate_store = cyapa_pip_do_calibrate,

	.initialize = cyapa_gen6_initialize,

	.state_parse = cyapa_pip_state_parse,
	.operational_check = cyapa_gen6_operational_check,

	.irq_handler = cyapa_pip_irq_handler,
	.irq_cmd_handler = cyapa_pip_irq_cmd_handler,
	.sort_empty_output_data = cyapa_empty_pip_output_data,
	.set_power_mode = cyapa_gen6_set_power_mode,

	.set_proximity = cyapa_gen6_set_proximity,
};
