// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Goodix GT7986U SPI Driver Code for HID.
 *
 * Copyright (C) 2024 Godix, Inc.
 */
#include <linux/unaligned.h>
#include <linux/delay.h>
#include <linux/hid.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/sizes.h>
#include <linux/spi/spi.h>

#define GOODIX_DEV_CONFIRM_ADDR		0x10000
#define GOODIX_HID_DESC_ADDR		0x1058C
#define GOODIX_HID_REPORT_DESC_ADDR	0x105AA
#define GOODIX_HID_SIGN_ADDR		0x10D32
#define GOODIX_HID_CMD_ADDR		0x10364
#define GOODIX_HID_REPORT_ADDR		0x22C8C

#define GOODIX_HID_GET_REPORT_CMD	0x02
#define GOODIX_HID_SET_REPORT_CMD	0x03

#define GOODIX_HID_MAX_INBUF_SIZE	128
#define GOODIX_HID_ACK_READY_FLAG	0x01
#define GOODIX_HID_REPORT_READY_FLAG	0x80

#define GOODIX_DEV_CONFIRM_VAL		0xAA

#define GOODIX_SPI_WRITE_FLAG		0xF0
#define GOODIX_SPI_READ_FLAG		0xF1
#define GOODIX_SPI_TRANS_PREFIX_LEN	1
#define GOODIX_REGISTER_WIDTH		4
#define GOODIX_SPI_READ_DUMMY_LEN	3
#define GOODIX_SPI_READ_PREFIX_LEN	(GOODIX_SPI_TRANS_PREFIX_LEN + \
					 GOODIX_REGISTER_WIDTH + \
					 GOODIX_SPI_READ_DUMMY_LEN)
#define GOODIX_SPI_WRITE_PREFIX_LEN	(GOODIX_SPI_TRANS_PREFIX_LEN + \
					 GOODIX_REGISTER_WIDTH)

#define GOODIX_CHECKSUM_SIZE		sizeof(u16)
#define GOODIX_NORMAL_RESET_DELAY_MS	150

struct goodix_hid_report_header {
	u8 flag;
	__le16 size;
} __packed;
#define GOODIX_HID_ACK_HEADER_SIZE	sizeof(struct goodix_hid_report_header)

struct goodix_hid_report_package {
	__le16 size;
	u8 data[];
};

#define GOODIX_HID_PKG_LEN_SIZE		sizeof(u16)
#define GOODIX_HID_COOR_DATA_LEN	82
#define GOODIX_HID_COOR_PKG_LEN		(GOODIX_HID_PKG_LEN_SIZE + \
					 GOODIX_HID_COOR_DATA_LEN)

/* power state */
#define GOODIX_SPI_POWER_ON		0x00
#define GOODIX_SPI_POWER_SLEEP		0x01

/* flags used to record the current device operating state */
#define GOODIX_HID_STARTED		0

struct goodix_hid_report_event {
	struct goodix_hid_report_header hdr;
	u8 data[GOODIX_HID_COOR_PKG_LEN];
} __packed;

struct goodix_hid_desc {
	__le16 desc_length;
	__le16 bcd_version;
	__le16 report_desc_length;
	__le16 report_desc_register;
	__le16 input_register;
	__le16 max_input_length;
	__le16 output_register;
	__le16 max_output_length;
	__le16 cmd_register;
	__le16 data_register;
	__le16 vendor_id;
	__le16 product_id;
	__le16 version_id;
	__le32 reserved;
} __packed;

struct goodix_ts_data {
	struct device *dev;
	struct spi_device *spi;
	struct hid_device *hid;
	struct goodix_hid_desc hid_desc;

	struct gpio_desc *reset_gpio;
	u32 hid_report_addr;

	unsigned long flags;
	/* lock for hid raw request operation */
	struct mutex hid_request_lock;
	/* buffer used to store hid report event */
	u8 *event_buf;
	u32 hid_max_event_sz;
	/* buffer used to do spi data transfer */
	u8 xfer_buf[SZ_2K] ____cacheline_aligned;
};

static void *goodix_get_event_report(struct goodix_ts_data *ts, u32 addr,
				     u8 *data, size_t len)
{
	struct spi_device *spi = to_spi_device(&ts->spi->dev);
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	int error;

	/* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
	data[0] = GOODIX_SPI_READ_FLAG;
	put_unaligned_be32(addr, data + GOODIX_SPI_TRANS_PREFIX_LEN);

	spi_message_init(&spi_msg);
	memset(&xfers, 0, sizeof(xfers));
	xfers.tx_buf = data;
	xfers.rx_buf = data;
	xfers.len = GOODIX_SPI_READ_PREFIX_LEN + len;
	spi_message_add_tail(&xfers, &spi_msg);

	error = spi_sync(spi, &spi_msg);
	if (error) {
		dev_err(ts->dev, "spi transfer error: %d", error);
		return NULL;
	}

	return data + GOODIX_SPI_READ_PREFIX_LEN;
}

static int goodix_spi_read(struct goodix_ts_data *ts, u32 addr,
			   void *data, size_t len)
{
	struct spi_device *spi = to_spi_device(&ts->spi->dev);
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	int error;

	if (GOODIX_SPI_READ_PREFIX_LEN + len > sizeof(ts->xfer_buf)) {
		dev_err(ts->dev, "read data len exceed limit %zu",
			sizeof(ts->xfer_buf) - GOODIX_SPI_READ_PREFIX_LEN);
		return -EINVAL;
	}

	/* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
	ts->xfer_buf[0] = GOODIX_SPI_READ_FLAG;
	put_unaligned_be32(addr, ts->xfer_buf + GOODIX_SPI_TRANS_PREFIX_LEN);

	spi_message_init(&spi_msg);
	memset(&xfers, 0, sizeof(xfers));
	xfers.tx_buf = ts->xfer_buf;
	xfers.rx_buf = ts->xfer_buf;
	xfers.len = GOODIX_SPI_READ_PREFIX_LEN + len;
	spi_message_add_tail(&xfers, &spi_msg);

	error = spi_sync(spi, &spi_msg);
	if (error)
		dev_err(ts->dev, "spi transfer error: %d", error);
	else
		memcpy(data, ts->xfer_buf + GOODIX_SPI_READ_PREFIX_LEN, len);

	return error;
}

static int goodix_spi_write(struct goodix_ts_data *ts, u32 addr,
			    const void *data, size_t len)
{
	struct spi_device *spi = to_spi_device(&ts->spi->dev);
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	int error;

	if (GOODIX_SPI_WRITE_PREFIX_LEN + len > sizeof(ts->xfer_buf)) {
		dev_err(ts->dev, "write data len exceed limit %zu",
			sizeof(ts->xfer_buf) - GOODIX_SPI_WRITE_PREFIX_LEN);
		return -EINVAL;
	}

	/* buffer format: 0xF0 + addr(4bytes) + data */
	ts->xfer_buf[0] = GOODIX_SPI_WRITE_FLAG;
	put_unaligned_be32(addr, ts->xfer_buf + GOODIX_SPI_TRANS_PREFIX_LEN);
	memcpy(ts->xfer_buf + GOODIX_SPI_WRITE_PREFIX_LEN, data, len);

	spi_message_init(&spi_msg);
	memset(&xfers, 0, sizeof(xfers));
	xfers.tx_buf = ts->xfer_buf;
	xfers.len = GOODIX_SPI_WRITE_PREFIX_LEN + len;
	spi_message_add_tail(&xfers, &spi_msg);

	error = spi_sync(spi, &spi_msg);
	if (error)
		dev_err(ts->dev, "spi transfer error: %d", error);

	return error;
}

static int goodix_dev_confirm(struct goodix_ts_data *ts)
{
	u8 tx_buf[8], rx_buf[8];
	int retry = 3;
	int error;

	gpiod_set_value_cansleep(ts->reset_gpio, 0);
	usleep_range(4000, 4100);

	memset(tx_buf, GOODIX_DEV_CONFIRM_VAL, sizeof(tx_buf));
	while (retry--) {
		error = goodix_spi_write(ts, GOODIX_DEV_CONFIRM_ADDR,
					 tx_buf, sizeof(tx_buf));
		if (error)
			return error;

		error = goodix_spi_read(ts, GOODIX_DEV_CONFIRM_ADDR,
					rx_buf, sizeof(rx_buf));
		if (error)
			return error;

		if (!memcmp(tx_buf, rx_buf, sizeof(tx_buf)))
			return 0;

		usleep_range(5000, 5100);
	}

	dev_err(ts->dev, "device confirm failed, rx_buf: %*ph", 8, rx_buf);
	return -EINVAL;
}

/**
 * goodix_hid_parse() - hid-core .parse() callback
 * @hid: hid device instance
 *
 * This function gets called during call to hid_add_device
 *
 * Return: 0 on success and non zero on error
 */
static int goodix_hid_parse(struct hid_device *hid)
{
	struct goodix_ts_data *ts = hid->driver_data;
	u16 rsize;
	int error;

	rsize = le16_to_cpu(ts->hid_desc.report_desc_length);
	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
		dev_err(ts->dev, "invalid report desc size, %d", rsize);
		return -EINVAL;
	}

	u8 *rdesc __free(kfree) = kzalloc(rsize, GFP_KERNEL);
	if (!rdesc)
		return -ENOMEM;

	error = goodix_spi_read(ts, GOODIX_HID_REPORT_DESC_ADDR, rdesc, rsize);
	if (error) {
		dev_err(ts->dev, "failed get report desc, %d", error);
		return error;
	}

	error = hid_parse_report(hid, rdesc, rsize);
	if (error) {
		dev_err(ts->dev, "failed parse report, %d", error);
		return error;
	}

	return 0;
}

static int goodix_hid_get_report_length(struct hid_report *report)
{
	return ((report->size - 1) >> 3) + 1 +
		report->device->report_enum[report->type].numbered + 2;
}

static void goodix_hid_find_max_report(struct hid_device *hid, unsigned int type,
				       unsigned int *max)
{
	struct hid_report *report;
	unsigned int size;

	list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
		size = goodix_hid_get_report_length(report);
		if (*max < size)
			*max = size;
	}
}

static int goodix_hid_start(struct hid_device *hid)
{
	struct goodix_ts_data *ts = hid->driver_data;
	unsigned int bufsize = GOODIX_HID_COOR_PKG_LEN;
	u32 report_size;

	goodix_hid_find_max_report(hid, HID_INPUT_REPORT, &bufsize);
	goodix_hid_find_max_report(hid, HID_OUTPUT_REPORT, &bufsize);
	goodix_hid_find_max_report(hid, HID_FEATURE_REPORT, &bufsize);

	report_size = GOODIX_SPI_READ_PREFIX_LEN +
			GOODIX_HID_ACK_HEADER_SIZE + bufsize;
	if (report_size <= ts->hid_max_event_sz)
		return 0;

	ts->event_buf = devm_krealloc(ts->dev, ts->event_buf,
				      report_size, GFP_KERNEL);
	if (!ts->event_buf)
		return -ENOMEM;

	ts->hid_max_event_sz = report_size;
	return 0;
}

static void goodix_hid_stop(struct hid_device *hid)
{
	hid->claimed = 0;
}

static int goodix_hid_open(struct hid_device *hid)
{
	struct goodix_ts_data *ts = hid->driver_data;

	set_bit(GOODIX_HID_STARTED, &ts->flags);
	return 0;
}

static void goodix_hid_close(struct hid_device *hid)
{
	struct goodix_ts_data *ts = hid->driver_data;

	clear_bit(GOODIX_HID_STARTED, &ts->flags);
}

/* Return date length of response data */
static int goodix_hid_check_ack_status(struct goodix_ts_data *ts, u32 *resp_len)
{
	struct goodix_hid_report_header hdr;
	int retry = 20;
	int error;
	int len;

	while (retry--) {
		/*
		 * 3 bytes of hid request response data
		 * - byte 0:    Ack flag, value of 1 for data ready
		 * - bytes 1-2: Response data length
		 */
		error = goodix_spi_read(ts, GOODIX_HID_CMD_ADDR,
					&hdr, sizeof(hdr));
		if (!error && (hdr.flag & GOODIX_HID_ACK_READY_FLAG)) {
			len = le16_to_cpu(hdr.size);
			if (len < GOODIX_HID_PKG_LEN_SIZE) {
				dev_err(ts->dev, "hrd.size too short: %d", len);
				return -EINVAL;
			}
			*resp_len = len - GOODIX_HID_PKG_LEN_SIZE;
			return 0;
		}

		/* Wait 10ms for another try */
		usleep_range(10000, 11000);
	}

	return -EINVAL;
}

/**
 * goodix_hid_get_raw_report() - Process hidraw GET REPORT operation
 * @hid: hid device instance
 * @reportnum: Report ID
 * @buf: Buffer for store the report date
 * @len: Length fo report data
 * @report_type: Report type
 *
 * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl
 * get report request. The transmitted data follows the standard i2c-hid
 * protocol with a specified header.
 *
 * Return: The length of the data in the buf on success, negative error code
 */
static int goodix_hid_get_raw_report(struct hid_device *hid,
				     unsigned char reportnum,
				     u8 *buf, size_t len,
				     unsigned char report_type)
{
	struct goodix_ts_data *ts = hid->driver_data;
	u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
	u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
	u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
	int tx_len = 0, args_len = 0;
	u32 response_data_len;
	u8 args[3];
	int error;

	if (report_type == HID_OUTPUT_REPORT)
		return -EINVAL;

	if (reportnum == 3) {
		/* Get win8 signature data */
		error = goodix_spi_read(ts, GOODIX_HID_SIGN_ADDR, buf, len);
		if (error) {
			dev_err(ts->dev, "failed get win8 sign: %d", error);
			return -EINVAL;
		}
		return len;
	}

	if (reportnum >= 0x0F)
		args[args_len++] = reportnum;

	put_unaligned_le16(data_register, args + args_len);
	args_len += sizeof(data_register);

	/* Clean 3 bytes of hid ack header data */
	memset(tmp_buf, 0, GOODIX_HID_ACK_HEADER_SIZE);
	tx_len += GOODIX_HID_ACK_HEADER_SIZE;

	put_unaligned_le16(cmd_register, tmp_buf + tx_len);
	tx_len += sizeof(cmd_register);

	tmp_buf[tx_len] = (report_type == HID_FEATURE_REPORT ? 0x03 : 0x01) << 4;
	tmp_buf[tx_len] |=  reportnum >= 0x0F ? 0x0F : reportnum;
	tx_len++;

	tmp_buf[tx_len++] = GOODIX_HID_GET_REPORT_CMD;

	memcpy(tmp_buf + tx_len, args, args_len);
	tx_len += args_len;

	/* Step1: write report request info */
	error = goodix_spi_write(ts, GOODIX_HID_CMD_ADDR, tmp_buf, tx_len);
	if (error) {
		dev_err(ts->dev, "failed send read feature cmd, %d", error);
		return error;
	}

	/* No need read response data */
	if (!len)
		return 0;

	/* Step2: check response data status */
	error = goodix_hid_check_ack_status(ts, &response_data_len);
	if (error)
		return error;

	/* Empty reprot response */
	if (!response_data_len)
		return 0;
	len = min(len, response_data_len);
	/* Step3: read response data(skip 2bytes of hid pkg length) */
	error = goodix_spi_read(ts, GOODIX_HID_CMD_ADDR +
				GOODIX_HID_ACK_HEADER_SIZE +
				GOODIX_HID_PKG_LEN_SIZE, buf, len);
	if (error) {
		dev_err(ts->dev, "failed read hid response data, %d", error);
		return error;
	}

	if (buf[0] != reportnum) {
		dev_err(ts->dev, "incorrect report (%d vs %d expected)",
			buf[0], reportnum);
		return -EINVAL;
	}
	return len;
}

/**
 * goodix_hid_set_raw_report() - process hidraw SET REPORT operation
 * @hid: HID device
 * @reportnum: Report ID
 * @buf: Buffer for communication
 * @len: Length of data in the buffer
 * @report_type: Report type
 *
 * The function for hid_ll_driver.get_raw_report to handle the HIDRAW ioctl
 * set report request. The transmitted data follows the standard i2c-hid
 * protocol with a specified header.
 *
 * Return: The length of the data sent, negative error code on failure
 */
static int goodix_hid_set_raw_report(struct hid_device *hid,
				     unsigned char reportnum,
				     __u8 *buf, size_t len,
				     unsigned char report_type)
{
	struct goodix_ts_data *ts = hid->driver_data;
	u16 data_register = le16_to_cpu(ts->hid_desc.data_register);
	u16 cmd_register = le16_to_cpu(ts->hid_desc.cmd_register);
	int tx_len = 0, args_len = 0;
	u8 tmp_buf[GOODIX_HID_MAX_INBUF_SIZE];
	u8 args[5];
	int error;

	if (reportnum >= 0x0F) {
		args[args_len++] = reportnum;
		reportnum = 0x0F;
	}

	put_unaligned_le16(data_register, args + args_len);
	args_len += sizeof(data_register);

	put_unaligned_le16(GOODIX_HID_PKG_LEN_SIZE + len, args + args_len);
	args_len += GOODIX_HID_PKG_LEN_SIZE;

	/* Clean 3 bytes of hid ack header data */
	memset(tmp_buf, 0, GOODIX_HID_ACK_HEADER_SIZE);
	tx_len += GOODIX_HID_ACK_HEADER_SIZE;

	put_unaligned_le16(cmd_register, tmp_buf + tx_len);
	tx_len += sizeof(cmd_register);

	tmp_buf[tx_len++] = ((report_type == HID_FEATURE_REPORT ? 0x03 : 0x02) << 4) | reportnum;
	tmp_buf[tx_len++] = GOODIX_HID_SET_REPORT_CMD;

	memcpy(tmp_buf + tx_len, args, args_len);
	tx_len += args_len;

	memcpy(tmp_buf + tx_len, buf, len);
	tx_len += len;

	error = goodix_spi_write(ts, GOODIX_HID_CMD_ADDR, tmp_buf, tx_len);
	if (error) {
		dev_err(ts->dev, "failed send report: %*ph", tx_len, tmp_buf);
		return error;
	}
	return len;
}

static int goodix_hid_raw_request(struct hid_device *hid,
				  unsigned char reportnum,
				  __u8 *buf, size_t len,
				  unsigned char rtype, int reqtype)
{
	struct goodix_ts_data *ts = hid->driver_data;
	int error = -EINVAL;

	guard(mutex)(&ts->hid_request_lock);
	switch (reqtype) {
	case HID_REQ_GET_REPORT:
		error = goodix_hid_get_raw_report(hid, reportnum, buf,
						  len, rtype);
		break;
	case HID_REQ_SET_REPORT:
		if (buf[0] == reportnum)
			error = goodix_hid_set_raw_report(hid, reportnum,
							  buf, len, rtype);
		break;
	default:
		break;
	}

	return error;
}

static struct hid_ll_driver goodix_hid_ll_driver = {
	.parse = goodix_hid_parse,
	.start = goodix_hid_start,
	.stop = goodix_hid_stop,
	.open = goodix_hid_open,
	.close = goodix_hid_close,
	.raw_request = goodix_hid_raw_request
};

static irqreturn_t goodix_hid_irq(int irq, void *data)
{
	struct goodix_ts_data *ts = data;
	struct goodix_hid_report_event *event;
	struct goodix_hid_report_package *pkg;
	u16 report_size;

	if (!test_bit(GOODIX_HID_STARTED, &ts->flags))
		return IRQ_HANDLED;
	/*
	 * First, read buffer with space for header and coordinate package:
	 * - event header = 3 bytes
	 * - coordinate event = GOODIX_HID_COOR_PKG_LEN bytes
	 *
	 * If the data size info in the event header exceeds
	 * GOODIX_HID_COOR_PKG_LEN, it means that there are other packages
	 * besides the coordinate package.
	 */
	event = goodix_get_event_report(ts, ts->hid_report_addr, ts->event_buf,
					GOODIX_HID_ACK_HEADER_SIZE +
					GOODIX_HID_COOR_PKG_LEN);
	if (!event) {
		dev_err(ts->dev, "failed get coordinate data");
		return IRQ_HANDLED;
	}

	/* Check coordinate data valid falg */
	if (event->hdr.flag != GOODIX_HID_REPORT_READY_FLAG)
		return IRQ_HANDLED;

	pkg = (struct goodix_hid_report_package *)event->data;
	if (le16_to_cpu(pkg->size) < GOODIX_HID_PKG_LEN_SIZE) {
		dev_err(ts->dev, "invalid coordinate event package size, %d",
			le16_to_cpu(pkg->size));
		return IRQ_HANDLED;
	}
	hid_input_report(ts->hid, HID_INPUT_REPORT, pkg->data,
			 le16_to_cpu(pkg->size) - GOODIX_HID_PKG_LEN_SIZE, 1);

	report_size = le16_to_cpu(event->hdr.size);
	/* Check if there are other packages */
	if (report_size <= GOODIX_HID_COOR_PKG_LEN)
		return IRQ_HANDLED;

	if (report_size >= ts->hid_max_event_sz) {
		dev_err(ts->dev, "package size exceed limit %d vs %d",
			report_size, ts->hid_max_event_sz);
		return IRQ_HANDLED;
	}

	/* Read the package behind the coordinate data */
	pkg = goodix_get_event_report(ts, ts->hid_report_addr + sizeof(*event),
				      ts->event_buf,
				      report_size - GOODIX_HID_COOR_PKG_LEN);
	if (!pkg) {
		dev_err(ts->dev, "failed read attachment data content");
		return IRQ_HANDLED;
	}

	hid_input_report(ts->hid, HID_INPUT_REPORT, pkg->data,
			 le16_to_cpu(pkg->size) - GOODIX_HID_PKG_LEN_SIZE, 1);

	return IRQ_HANDLED;
}

static int goodix_hid_init(struct goodix_ts_data *ts)
{
	struct hid_device *hid;
	int error;

	/* Get hid descriptor */
	error = goodix_spi_read(ts, GOODIX_HID_DESC_ADDR, &ts->hid_desc,
				sizeof(ts->hid_desc));
	if (error) {
		dev_err(ts->dev, "failed get hid desc, %d", error);
		return error;
	}

	hid = hid_allocate_device();
	if (IS_ERR(hid))
		return PTR_ERR(hid);

	hid->driver_data = ts;
	hid->ll_driver = &goodix_hid_ll_driver;
	hid->bus = BUS_SPI;
	hid->dev.parent = &ts->spi->dev;

	hid->version = le16_to_cpu(ts->hid_desc.bcd_version);
	hid->vendor = le16_to_cpu(ts->hid_desc.vendor_id);
	hid->product = le16_to_cpu(ts->hid_desc.product_id);
	snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-gdix",
		 hid->vendor, hid->product);

	error = hid_add_device(hid);
	if (error) {
		dev_err(ts->dev, "failed add hid device, %d", error);
		hid_destroy_device(hid);
		return error;
	}

	ts->hid = hid;
	return 0;
}

static int goodix_spi_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct goodix_ts_data *ts;
	int error;

	/* init spi_device */
	spi->mode            = SPI_MODE_0;
	spi->bits_per_word   = 8;
	error = spi_setup(spi);
	if (error)
		return error;

	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	mutex_init(&ts->hid_request_lock);
	spi_set_drvdata(spi, ts);
	ts->spi = spi;
	ts->dev = dev;
	ts->hid_max_event_sz = GOODIX_SPI_READ_PREFIX_LEN +
			       GOODIX_HID_ACK_HEADER_SIZE + GOODIX_HID_COOR_PKG_LEN;
	ts->event_buf = devm_kmalloc(dev, ts->hid_max_event_sz, GFP_KERNEL);
	if (!ts->event_buf)
		return -ENOMEM;

	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(ts->reset_gpio))
		return dev_err_probe(dev, PTR_ERR(ts->reset_gpio),
				     "failed to request reset gpio\n");

	ts->hid_report_addr = GOODIX_HID_REPORT_ADDR;
	error = goodix_dev_confirm(ts);
	if (error)
		return error;

	/* Waits 150ms for firmware to fully boot */
	msleep(GOODIX_NORMAL_RESET_DELAY_MS);

	error = goodix_hid_init(ts);
	if (error) {
		dev_err(dev, "failed init hid device");
		return error;
	}

	error = devm_request_threaded_irq(&ts->spi->dev, ts->spi->irq,
					  NULL, goodix_hid_irq, IRQF_ONESHOT,
					  "goodix_spi_hid", ts);
	if (error) {
		dev_err(ts->dev, "could not register interrupt, irq = %d, %d",
			ts->spi->irq, error);
		goto err_destroy_hid;
	}

	return 0;

err_destroy_hid:
	hid_destroy_device(ts->hid);
	return error;
}

static void goodix_spi_remove(struct spi_device *spi)
{
	struct goodix_ts_data *ts = spi_get_drvdata(spi);

	disable_irq(spi->irq);
	hid_destroy_device(ts->hid);
}

static int goodix_spi_set_power(struct goodix_ts_data *ts, int power_state)
{
	u8 power_control_cmd[] = {0x00, 0x00, 0x00, 0x87, 0x02, 0x00, 0x08};
	int error;

	/* value 0 for power on, 1 for power sleep */
	power_control_cmd[5] = power_state;

	guard(mutex)(&ts->hid_request_lock);
	error = goodix_spi_write(ts, GOODIX_HID_CMD_ADDR, power_control_cmd,
				 sizeof(power_control_cmd));
	if (error) {
		dev_err(ts->dev, "failed set power mode: %s",
			power_state == GOODIX_SPI_POWER_ON ? "on" : "sleep");
		return error;
	}
	return 0;
}

static int goodix_spi_suspend(struct device *dev)
{
	struct goodix_ts_data *ts = dev_get_drvdata(dev);

	disable_irq(ts->spi->irq);
	return goodix_spi_set_power(ts, GOODIX_SPI_POWER_SLEEP);
}

static int goodix_spi_resume(struct device *dev)
{
	struct goodix_ts_data *ts = dev_get_drvdata(dev);

	enable_irq(ts->spi->irq);
	return goodix_spi_set_power(ts, GOODIX_SPI_POWER_ON);
}

static DEFINE_SIMPLE_DEV_PM_OPS(goodix_spi_pm_ops,
				goodix_spi_suspend, goodix_spi_resume);

#ifdef CONFIG_ACPI
static const struct acpi_device_id goodix_spi_acpi_match[] = {
	{ "GXTS7986" },
	{ },
};
MODULE_DEVICE_TABLE(acpi, goodix_spi_acpi_match);
#endif

#ifdef CONFIG_OF
static const struct of_device_id goodix_spi_of_match[] = {
	{ .compatible = "goodix,gt7986u-spifw", },
	{ }
};
MODULE_DEVICE_TABLE(of, goodix_spi_of_match);
#endif

static const struct spi_device_id goodix_spi_ids[] = {
	{ "gt7986u" },
	{ },
};
MODULE_DEVICE_TABLE(spi, goodix_spi_ids);

static struct spi_driver goodix_spi_driver = {
	.driver = {
		.name = "goodix-spi-hid",
		.acpi_match_table = ACPI_PTR(goodix_spi_acpi_match),
		.of_match_table = of_match_ptr(goodix_spi_of_match),
		.pm = pm_sleep_ptr(&goodix_spi_pm_ops),
	},
	.probe =	goodix_spi_probe,
	.remove =	goodix_spi_remove,
	.id_table =	goodix_spi_ids,
};
module_spi_driver(goodix_spi_driver);

MODULE_DESCRIPTION("Goodix SPI driver for HID touchscreen");
MODULE_AUTHOR("Goodix, Inc.");
MODULE_LICENSE("GPL");
