// SPDX-License-Identifier: GPL-2.0-only
/*
 * Cypress Trackpad PS/2 mouse driver
 *
 * Copyright (c) 2012 Cypress Semiconductor Corporation.
 *
 * Author:
 *   Dudley Du <dudl@cypress.com>
 *
 * Additional contributors include:
 *   Kamal Mostafa <kamal@canonical.com>
 *   Kyle Fazzari <git@status.e4ward.com>
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/serio.h>
#include <linux/libps2.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/sched.h>
#include <linux/wait.h>

#include "cypress_ps2.h"

#undef CYTP_DEBUG_VERBOSE  /* define this and DEBUG for more verbose dump */

static void cypress_set_packet_size(struct psmouse *psmouse, unsigned int n)
{
	struct cytp_data *cytp = psmouse->private;
	cytp->pkt_size = n;
}

static const u8 cytp_rate[] = {10, 20, 40, 60, 100, 200};
static const u8 cytp_resolution[] = {0x00, 0x01, 0x02, 0x03};

static int cypress_ps2_sendbyte(struct psmouse *psmouse, u8 cmd)
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
	int error;

	error = ps2_sendbyte(ps2dev, cmd, CYTP_CMD_TIMEOUT);
	if (error) {
		psmouse_dbg(psmouse,
			    "sending command 0x%02x failed, resp 0x%02x, error %d\n",
			    cmd, ps2dev->nak, error);
		return error;
	}

#ifdef CYTP_DEBUG_VERBOSE
	psmouse_dbg(psmouse, "sending command 0x%02x succeeded\n", cmd);
#endif

	return 0;
}

static int cypress_ps2_ext_cmd(struct psmouse *psmouse, u8 prefix, u8 nibble)
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
	int tries = CYTP_PS2_CMD_TRIES;
	int rc;

	ps2_begin_command(ps2dev);

	do {
		/*
		 * Send extension command byte (0xE8 or 0xF3).
		 * If sending the command fails, send recovery command
		 * to make the device return to the ready state.
		 */
		rc = cypress_ps2_sendbyte(psmouse, prefix);
		if (rc == -EAGAIN) {
			rc = cypress_ps2_sendbyte(psmouse, 0x00);
			if (rc == -EAGAIN)
				rc = cypress_ps2_sendbyte(psmouse, 0x0a);
		}

		if (!rc) {
			rc = cypress_ps2_sendbyte(psmouse, nibble);
			if (rc == -EAGAIN)
				rc = cypress_ps2_sendbyte(psmouse, nibble);

			if (!rc)
				break;
		}
	} while (--tries > 0);

	ps2_end_command(ps2dev);

	return rc;
}

static bool cypress_verify_cmd_state(struct psmouse *psmouse, u8 cmd, u8* param)
{
	bool rate_match = false;
	bool resolution_match = false;
	int i;

	/* callers will do further checking. */
	if (cmd == CYTP_CMD_READ_CYPRESS_ID ||
	    cmd == CYTP_CMD_STANDARD_MODE ||
	    cmd == CYTP_CMD_READ_TP_METRICS)
		return true;

	if ((~param[0] & DFLT_RESP_BITS_VALID) == DFLT_RESP_BITS_VALID &&
	    (param[0] & DFLT_RESP_BIT_MODE) == DFLT_RESP_STREAM_MODE) {
		for (i = 0; i < sizeof(cytp_resolution); i++)
			if (cytp_resolution[i] == param[1])
				resolution_match = true;

		for (i = 0; i < sizeof(cytp_rate); i++)
			if (cytp_rate[i] == param[2])
				rate_match = true;

		if (resolution_match && rate_match)
			return true;
	}

	psmouse_dbg(psmouse, "verify cmd state failed.\n");
	return false;
}

static int cypress_send_ext_cmd(struct psmouse *psmouse, u8 cmd, u8 *param)
{
	u8 cmd_prefix = PSMOUSE_CMD_SETRES & 0xff;
	unsigned int resp_size = cmd == CYTP_CMD_READ_TP_METRICS ? 8 : 3;
	unsigned int ps2_cmd = (PSMOUSE_CMD_GETINFO & 0xff) | (resp_size << 8);
	int tries = CYTP_PS2_CMD_TRIES;
	int error;

	psmouse_dbg(psmouse, "send extension cmd 0x%02x, [%d %d %d %d]\n",
		 cmd, DECODE_CMD_AA(cmd), DECODE_CMD_BB(cmd),
		 DECODE_CMD_CC(cmd), DECODE_CMD_DD(cmd));

	do {
		cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_DD(cmd));
		cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_CC(cmd));
		cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_BB(cmd));
		cypress_ps2_ext_cmd(psmouse, cmd_prefix, DECODE_CMD_AA(cmd));

		error = ps2_command(&psmouse->ps2dev, param, ps2_cmd);
		if (error) {
			psmouse_dbg(psmouse, "Command 0x%02x failed: %d\n",
				    cmd, error);
		} else {
			psmouse_dbg(psmouse,
				    "Command 0x%02x response data (0x): %*ph\n",
				    cmd, resp_size, param);

			if (cypress_verify_cmd_state(psmouse, cmd, param))
				return 0;
		}
	} while (--tries > 0);

	return -EIO;
}

int cypress_detect(struct psmouse *psmouse, bool set_properties)
{
	u8 param[3];

	if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param))
		return -ENODEV;

	/* Check for Cypress Trackpad signature bytes: 0x33 0xCC */
	if (param[0] != 0x33 || param[1] != 0xCC)
		return -ENODEV;

	if (set_properties) {
		psmouse->vendor = "Cypress";
		psmouse->name = "Trackpad";
	}

	return 0;
}

static int cypress_read_fw_version(struct psmouse *psmouse)
{
	struct cytp_data *cytp = psmouse->private;
	u8 param[3];

	if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_CYPRESS_ID, param))
		return -ENODEV;

	/* Check for Cypress Trackpad signature bytes: 0x33 0xCC */
	if (param[0] != 0x33 || param[1] != 0xCC)
		return -ENODEV;

	cytp->fw_version = param[2] & FW_VERSION_MASX;
	cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0;

	/*
	 * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to
	 * CYTP_CMD_READ_TP_METRICS so do not try to use it. LP: #1103594.
	 */
	if (cytp->fw_version >= 11)
		cytp->tp_metrics_supported = 0;

	psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version);
	psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n",
		 cytp->tp_metrics_supported);

	return 0;
}

static int cypress_read_tp_metrics(struct psmouse *psmouse)
{
	struct cytp_data *cytp = psmouse->private;
	u8 param[8];

	/* set default values for tp metrics. */
	cytp->tp_width = CYTP_DEFAULT_WIDTH;
	cytp->tp_high = CYTP_DEFAULT_HIGH;
	cytp->tp_max_abs_x = CYTP_ABS_MAX_X;
	cytp->tp_max_abs_y = CYTP_ABS_MAX_Y;
	cytp->tp_min_pressure = CYTP_MIN_PRESSURE;
	cytp->tp_max_pressure = CYTP_MAX_PRESSURE;
	cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width;
	cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high;

	if (!cytp->tp_metrics_supported)
		return 0;

	memset(param, 0, sizeof(param));
	if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) {
		/* Update trackpad parameters. */
		cytp->tp_max_abs_x = (param[1] << 8) | param[0];
		cytp->tp_max_abs_y = (param[3] << 8) | param[2];
		cytp->tp_min_pressure = param[4];
		cytp->tp_max_pressure = param[5];
	}

	if (!cytp->tp_max_pressure ||
	    cytp->tp_max_pressure < cytp->tp_min_pressure ||
	    !cytp->tp_width || !cytp->tp_high ||
	    !cytp->tp_max_abs_x ||
	    cytp->tp_max_abs_x < cytp->tp_width ||
	    !cytp->tp_max_abs_y ||
	    cytp->tp_max_abs_y < cytp->tp_high)
		return -EINVAL;

	cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width;
	cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high;

#ifdef CYTP_DEBUG_VERBOSE
	psmouse_dbg(psmouse, "Dump trackpad hardware configuration as below:\n");
	psmouse_dbg(psmouse, "cytp->tp_width = %d\n", cytp->tp_width);
	psmouse_dbg(psmouse, "cytp->tp_high = %d\n", cytp->tp_high);
	psmouse_dbg(psmouse, "cytp->tp_max_abs_x = %d\n", cytp->tp_max_abs_x);
	psmouse_dbg(psmouse, "cytp->tp_max_abs_y = %d\n", cytp->tp_max_abs_y);
	psmouse_dbg(psmouse, "cytp->tp_min_pressure = %d\n", cytp->tp_min_pressure);
	psmouse_dbg(psmouse, "cytp->tp_max_pressure = %d\n", cytp->tp_max_pressure);
	psmouse_dbg(psmouse, "cytp->tp_res_x = %d\n", cytp->tp_res_x);
	psmouse_dbg(psmouse, "cytp->tp_res_y = %d\n", cytp->tp_res_y);

	psmouse_dbg(psmouse, "tp_type_APA = %d\n",
			(param[6] & TP_METRICS_BIT_APA) ? 1 : 0);
	psmouse_dbg(psmouse, "tp_type_MTG = %d\n",
			(param[6] & TP_METRICS_BIT_MTG) ? 1 : 0);
	psmouse_dbg(psmouse, "tp_palm = %d\n",
			(param[6] & TP_METRICS_BIT_PALM) ? 1 : 0);
	psmouse_dbg(psmouse, "tp_stubborn = %d\n",
			(param[6] & TP_METRICS_BIT_STUBBORN) ? 1 : 0);
	psmouse_dbg(psmouse, "tp_1f_jitter = %d\n",
			(param[6] & TP_METRICS_BIT_1F_JITTER) >> 2);
	psmouse_dbg(psmouse, "tp_2f_jitter = %d\n",
			(param[6] & TP_METRICS_BIT_2F_JITTER) >> 4);
	psmouse_dbg(psmouse, "tp_1f_spike = %d\n",
			param[7] & TP_METRICS_BIT_1F_SPIKE);
	psmouse_dbg(psmouse, "tp_2f_spike = %d\n",
			(param[7] & TP_METRICS_BIT_2F_SPIKE) >> 2);
	psmouse_dbg(psmouse, "tp_abs_packet_format_set = %d\n",
			(param[7] & TP_METRICS_BIT_ABS_PKT_FORMAT_SET) >> 4);
#endif

	return 0;
}

static int cypress_query_hardware(struct psmouse *psmouse)
{
	int error;

	error = cypress_read_fw_version(psmouse);
	if (error)
		return error;

	error = cypress_read_tp_metrics(psmouse);
	if (error)
		return error;

	return 0;
}

static int cypress_set_absolute_mode(struct psmouse *psmouse)
{
	struct cytp_data *cytp = psmouse->private;
	u8 param[3];
	int error;

	error = cypress_send_ext_cmd(psmouse, CYTP_CMD_ABS_WITH_PRESSURE_MODE,
				     param);
	if (error)
		return error;

	cytp->mode = (cytp->mode & ~CYTP_BIT_ABS_REL_MASK)
			| CYTP_BIT_ABS_PRESSURE;
	cypress_set_packet_size(psmouse, 5);

	return 0;
}

/*
 * Reset trackpad device.
 * This is also the default mode when trackpad powered on.
 */
static void cypress_reset(struct psmouse *psmouse)
{
	struct cytp_data *cytp = psmouse->private;

	cytp->mode = 0;

	psmouse_reset(psmouse);
}

static int cypress_set_input_params(struct input_dev *input,
				    struct cytp_data *cytp)
{
	int error;

	if (!cytp->tp_res_x || !cytp->tp_res_y)
		return -EINVAL;

	__set_bit(EV_ABS, input->evbit);
	input_set_abs_params(input, ABS_X, 0, cytp->tp_max_abs_x, 0, 0);
	input_set_abs_params(input, ABS_Y, 0, cytp->tp_max_abs_y, 0, 0);
	input_set_abs_params(input, ABS_PRESSURE,
			     cytp->tp_min_pressure, cytp->tp_max_pressure, 0, 0);
	input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 255, 0, 0);

	/* finger position */
	input_set_abs_params(input, ABS_MT_POSITION_X, 0, cytp->tp_max_abs_x, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cytp->tp_max_abs_y, 0, 0);
	input_set_abs_params(input, ABS_MT_PRESSURE, 0, 255, 0, 0);

	error = input_mt_init_slots(input, CYTP_MAX_MT_SLOTS,
				    INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);
	if (error)
		return error;

	__set_bit(INPUT_PROP_SEMI_MT, input->propbit);

	input_abs_set_res(input, ABS_X, cytp->tp_res_x);
	input_abs_set_res(input, ABS_Y, cytp->tp_res_y);

	input_abs_set_res(input, ABS_MT_POSITION_X, cytp->tp_res_x);
	input_abs_set_res(input, ABS_MT_POSITION_Y, cytp->tp_res_y);

	__set_bit(BTN_TOUCH, input->keybit);
	__set_bit(BTN_TOOL_FINGER, input->keybit);
	__set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
	__set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
	__set_bit(BTN_TOOL_QUADTAP, input->keybit);
	__set_bit(BTN_TOOL_QUINTTAP, input->keybit);

	__clear_bit(EV_REL, input->evbit);
	__clear_bit(REL_X, input->relbit);
	__clear_bit(REL_Y, input->relbit);

	__set_bit(EV_KEY, input->evbit);
	__set_bit(BTN_LEFT, input->keybit);
	__set_bit(BTN_RIGHT, input->keybit);
	__set_bit(BTN_MIDDLE, input->keybit);

	return 0;
}

static int cypress_get_finger_count(u8 header_byte)
{
	u8 bits6_7;
	int finger_count;

	bits6_7 = header_byte >> 6;
	finger_count = bits6_7 & 0x03;

	if (finger_count == 1)
		return 1;

	if (header_byte & ABS_HSCROLL_BIT) {
		/* HSCROLL gets added on to 0 finger count. */
		switch (finger_count) {
			case 0:	return 4;
			case 2: return 5;
			default:
				/* Invalid contact (e.g. palm). Ignore it. */
				return 0;
		}
	}

	return finger_count;
}


static int cypress_parse_packet(struct psmouse *psmouse,
				struct cytp_data *cytp,
				struct cytp_report_data *report_data)
{
	u8 *packet = psmouse->packet;
	u8 header_byte = packet[0];

	memset(report_data, 0, sizeof(struct cytp_report_data));

	report_data->contact_cnt = cypress_get_finger_count(header_byte);
	report_data->tap = (header_byte & ABS_MULTIFINGER_TAP) ? 1 : 0;

	if (report_data->contact_cnt == 1) {
		report_data->contacts[0].x =
			((packet[1] & 0x70) << 4) | packet[2];
		report_data->contacts[0].y =
			((packet[1] & 0x07) << 8) | packet[3];
		if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
			report_data->contacts[0].z = packet[4];

	} else if (report_data->contact_cnt >= 2) {
		report_data->contacts[0].x =
			((packet[1] & 0x70) << 4) | packet[2];
		report_data->contacts[0].y =
			((packet[1] & 0x07) << 8) | packet[3];
		if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
			report_data->contacts[0].z = packet[4];

		report_data->contacts[1].x =
			((packet[5] & 0xf0) << 4) | packet[6];
		report_data->contacts[1].y =
			((packet[5] & 0x0f) << 8) | packet[7];
		if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
			report_data->contacts[1].z = report_data->contacts[0].z;
	}

	report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0;
	report_data->right = (header_byte & BTN_RIGHT_BIT) ? 1 : 0;

	/*
	 * This is only true if one of the mouse buttons were tapped.  Make
	 * sure it doesn't turn into a click. The regular tap-to-click
	 * functionality will handle that on its own. If we don't do this,
	 * disabling tap-to-click won't affect the mouse button zones.
	 */
	if (report_data->tap)
		report_data->left = 0;

#ifdef CYTP_DEBUG_VERBOSE
	{
		int i;
		int n = report_data->contact_cnt;
		psmouse_dbg(psmouse, "Dump parsed report data as below:\n");
		psmouse_dbg(psmouse, "contact_cnt = %d\n",
			report_data->contact_cnt);
		if (n > CYTP_MAX_MT_SLOTS)
		    n = CYTP_MAX_MT_SLOTS;
		for (i = 0; i < n; i++)
			psmouse_dbg(psmouse, "contacts[%d] = {%d, %d, %d}\n", i,
					report_data->contacts[i].x,
					report_data->contacts[i].y,
					report_data->contacts[i].z);
		psmouse_dbg(psmouse, "left = %d\n", report_data->left);
		psmouse_dbg(psmouse, "right = %d\n", report_data->right);
		psmouse_dbg(psmouse, "middle = %d\n", report_data->middle);
	}
#endif

	return 0;
}

static void cypress_process_packet(struct psmouse *psmouse, bool zero_pkt)
{
	int i;
	struct input_dev *input = psmouse->dev;
	struct cytp_data *cytp = psmouse->private;
	struct cytp_report_data report_data;
	struct cytp_contact *contact;
	struct input_mt_pos pos[CYTP_MAX_MT_SLOTS];
	int slots[CYTP_MAX_MT_SLOTS];
	int n;

	cypress_parse_packet(psmouse, cytp, &report_data);

	n = report_data.contact_cnt;
	if (n > CYTP_MAX_MT_SLOTS)
		n = CYTP_MAX_MT_SLOTS;

	for (i = 0; i < n; i++) {
		contact = &report_data.contacts[i];
		pos[i].x = contact->x;
		pos[i].y = contact->y;
	}

	input_mt_assign_slots(input, slots, pos, n, 0);

	for (i = 0; i < n; i++) {
		contact = &report_data.contacts[i];
		input_mt_slot(input, slots[i]);
		input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
		input_report_abs(input, ABS_MT_POSITION_X, contact->x);
		input_report_abs(input, ABS_MT_POSITION_Y, contact->y);
		input_report_abs(input, ABS_MT_PRESSURE, contact->z);
	}

	input_mt_sync_frame(input);

	input_mt_report_finger_count(input, report_data.contact_cnt);

	input_report_key(input, BTN_LEFT, report_data.left);
	input_report_key(input, BTN_RIGHT, report_data.right);
	input_report_key(input, BTN_MIDDLE, report_data.middle);

	input_sync(input);
}

static psmouse_ret_t cypress_validate_byte(struct psmouse *psmouse)
{
	int contact_cnt;
	int index = psmouse->pktcnt - 1;
	u8 *packet = psmouse->packet;
	struct cytp_data *cytp = psmouse->private;

	if (index < 0 || index > cytp->pkt_size)
		return PSMOUSE_BAD_DATA;

	if (index == 0 && (packet[0] & 0xfc) == 0) {
		/* call packet process for reporting finger leave. */
		cypress_process_packet(psmouse, 1);
		return PSMOUSE_FULL_PACKET;
	}

	/*
	 * Perform validation (and adjust packet size) based only on the
	 * first byte; allow all further bytes through.
	 */
	if (index != 0)
		return PSMOUSE_GOOD_DATA;

	/*
	 * If absolute/relative mode bit has not been set yet, just pass
	 * the byte through.
	 */
	if ((cytp->mode & CYTP_BIT_ABS_REL_MASK) == 0)
		return PSMOUSE_GOOD_DATA;

	if ((packet[0] & 0x08) == 0x08)
		return PSMOUSE_BAD_DATA;

	contact_cnt = cypress_get_finger_count(packet[0]);
	if (cytp->mode & CYTP_BIT_ABS_NO_PRESSURE)
		cypress_set_packet_size(psmouse, contact_cnt == 2 ? 7 : 4);
	else
		cypress_set_packet_size(psmouse, contact_cnt == 2 ? 8 : 5);

	return PSMOUSE_GOOD_DATA;
}

static psmouse_ret_t cypress_protocol_handler(struct psmouse *psmouse)
{
	struct cytp_data *cytp = psmouse->private;

	if (psmouse->pktcnt >= cytp->pkt_size) {
		cypress_process_packet(psmouse, 0);
		return PSMOUSE_FULL_PACKET;
	}

	return cypress_validate_byte(psmouse);
}

static void cypress_set_rate(struct psmouse *psmouse, unsigned int rate)
{
	struct cytp_data *cytp = psmouse->private;
	u8 rate_param;

	if (rate >= 80) {
		psmouse->rate = 80;
		cytp->mode |= CYTP_BIT_HIGH_RATE;
	} else {
		psmouse->rate = 40;
		cytp->mode &= ~CYTP_BIT_HIGH_RATE;
	}

	rate_param = (u8)rate;
	ps2_command(&psmouse->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE);
}

static void cypress_disconnect(struct psmouse *psmouse)
{
	cypress_reset(psmouse);
	kfree(psmouse->private);
	psmouse->private = NULL;
}

static int cypress_reconnect(struct psmouse *psmouse)
{
	int tries = CYTP_PS2_CMD_TRIES;
	int error;

	do {
		cypress_reset(psmouse);
		error = cypress_detect(psmouse, false);
	} while (error && (--tries > 0));

	if (error) {
		psmouse_err(psmouse, "Reconnect: unable to detect trackpad.\n");
		return error;
	}

	error = cypress_set_absolute_mode(psmouse);
	if (error) {
		psmouse_err(psmouse, "Reconnect: Unable to initialize Cypress absolute mode.\n");
		return error;
	}

	return 0;
}

int cypress_init(struct psmouse *psmouse)
{
	struct cytp_data *cytp;
	int error;

	cytp = kzalloc_obj(*cytp);
	if (!cytp)
		return -ENOMEM;

	psmouse->private = cytp;
	psmouse->pktsize = 8;

	cypress_reset(psmouse);

	error = cypress_query_hardware(psmouse);
	if (error) {
		psmouse_err(psmouse, "Unable to query Trackpad hardware.\n");
		goto err_exit;
	}

	error = cypress_set_absolute_mode(psmouse);
	if (error) {
		psmouse_err(psmouse, "init: Unable to initialize Cypress absolute mode.\n");
		goto err_exit;
	}

	error = cypress_set_input_params(psmouse->dev, cytp);
	if (error) {
		psmouse_err(psmouse, "init: Unable to set input params.\n");
		goto err_exit;
	}

	psmouse->model = 1;
	psmouse->protocol_handler = cypress_protocol_handler;
	psmouse->set_rate = cypress_set_rate;
	psmouse->disconnect = cypress_disconnect;
	psmouse->reconnect = cypress_reconnect;
	psmouse->cleanup = cypress_reset;
	psmouse->resync_time = 0;

	return 0;

err_exit:
	/*
	 * Reset Cypress Trackpad as a standard mouse. Then
	 * let psmouse driver communicating with it as default PS2 mouse.
	 */
	cypress_reset(psmouse);

	psmouse->private = NULL;
	kfree(cytp);

	return error;
}
