// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Goodix Berlin Touchscreen Driver
 *
 * Copyright (C) 2020 - 2021 Goodix, Inc.
 * Copyright (C) 2023 Linaro Ltd.
 *
 * Based on goodix_ts_berlin driver.
 */
#include <linux/unaligned.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/input.h>

#include "goodix_berlin.h"

#define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN	1
#define GOODIX_BERLIN_REGISTER_WIDTH		4
#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A	4
#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D	3
#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN_A	(GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
						 GOODIX_BERLIN_REGISTER_WIDTH + \
						 GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A)
#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN_D	(GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
						 GOODIX_BERLIN_REGISTER_WIDTH + \
						 GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D)
#define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN	(GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
						 GOODIX_BERLIN_REGISTER_WIDTH)

#define GOODIX_BERLIN_SPI_WRITE_FLAG		0xF0
#define GOODIX_BERLIN_SPI_READ_FLAG		0xF1

static int goodix_berlin_spi_read(void *context, const void *reg_buf,
				  size_t reg_size, void *val_buf,
				  size_t val_size)
{
	struct spi_device *spi = context;
	const struct goodix_berlin_ic_data *ic_data = spi_get_device_match_data(spi);
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */
	int error;

	if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH)
		return -EINVAL;

	u8 *buf __free(kfree) =
		kzalloc(ic_data->read_prefix_len + val_size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	spi_message_init(&spi_msg);
	memset(&xfers, 0, sizeof(xfers));

	/* buffer format: 0xF1 + addr(4bytes) + dummy(3/4bytes) + data */
	buf[0] = GOODIX_BERLIN_SPI_READ_FLAG;
	put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN);
	memset(buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + GOODIX_BERLIN_REGISTER_WIDTH,
	       0xff, ic_data->read_dummy_len);

	xfers.tx_buf = buf;
	xfers.rx_buf = buf;
	xfers.len = ic_data->read_prefix_len + val_size;
	xfers.cs_change = 0;
	spi_message_add_tail(&xfers, &spi_msg);

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

	memcpy(val_buf, buf + ic_data->read_prefix_len, val_size);
	return error;
}

static int goodix_berlin_spi_write(void *context, const void *data,
				   size_t count)
{
	unsigned int len = count - GOODIX_BERLIN_REGISTER_WIDTH;
	struct spi_device *spi = context;
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	const u32 *reg = data; /* reg is stored as native u32 at start of buffer */
	int error;

	u8 *buf __free(kfree) =
		kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	spi_message_init(&spi_msg);
	memset(&xfers, 0, sizeof(xfers));

	buf[0] = GOODIX_BERLIN_SPI_WRITE_FLAG;
	put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN);
	memcpy(buf + GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN,
	       data + GOODIX_BERLIN_REGISTER_WIDTH, len);

	xfers.tx_buf = buf;
	xfers.len = GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len;
	xfers.cs_change = 0;
	spi_message_add_tail(&xfers, &spi_msg);

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

	return 0;
}

static const struct regmap_config goodix_berlin_spi_regmap_conf = {
	.reg_bits = 32,
	.val_bits = 8,
	.read = goodix_berlin_spi_read,
	.write = goodix_berlin_spi_write,
};

/* vendor & product left unassigned here, should probably be updated from fw info */
static const struct input_id goodix_berlin_spi_input_id = {
	.bustype = BUS_SPI,
};

static int goodix_berlin_spi_probe(struct spi_device *spi)
{
	const struct goodix_berlin_ic_data *ic_data = spi_get_device_match_data(spi);
	struct regmap_config regmap_config;
	struct regmap *regmap;
	size_t max_size;
	int error = 0;

	spi->mode = SPI_MODE_0;
	spi->bits_per_word = 8;
	error = spi_setup(spi);
	if (error)
		return error;

	max_size = spi_max_transfer_size(spi);

	regmap_config = goodix_berlin_spi_regmap_conf;
	regmap_config.max_raw_read = max_size - ic_data->read_prefix_len;
	regmap_config.max_raw_write = max_size - GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN;

	regmap = devm_regmap_init(&spi->dev, NULL, spi, &regmap_config);
	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	error = goodix_berlin_probe(&spi->dev, spi->irq,
				    &goodix_berlin_spi_input_id, regmap,
				    ic_data);
	if (error)
		return error;

	return 0;
}

static const struct goodix_berlin_ic_data gt9897_data = {
	.fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_A,
	.ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_A,
	.read_dummy_len = GOODIX_BERLIN_SPI_READ_DUMMY_LEN_A,
	.read_prefix_len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN_A,
};

static const struct goodix_berlin_ic_data gt9916_data = {
	.fw_version_info_addr = GOODIX_BERLIN_FW_VERSION_INFO_ADDR_D,
	.ic_info_addr = GOODIX_BERLIN_IC_INFO_ADDR_D,
	.read_dummy_len = GOODIX_BERLIN_SPI_READ_DUMMY_LEN_D,
	.read_prefix_len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN_D,
};

static const struct spi_device_id goodix_berlin_spi_ids[] = {
	{ .name = "gt9897", .driver_data = (long)&gt9897_data },
	{ .name = "gt9916", .driver_data = (long)&gt9916_data },
	{ },
};
MODULE_DEVICE_TABLE(spi, goodix_berlin_spi_ids);

static const struct of_device_id goodix_berlin_spi_of_match[] = {
	{ .compatible = "goodix,gt9897", .data = &gt9897_data },
	{ .compatible = "goodix,gt9916", .data = &gt9916_data },
	{ }
};
MODULE_DEVICE_TABLE(of, goodix_berlin_spi_of_match);

static struct spi_driver goodix_berlin_spi_driver = {
	.driver = {
		.name = "goodix-berlin-spi",
		.of_match_table = goodix_berlin_spi_of_match,
		.pm = pm_sleep_ptr(&goodix_berlin_pm_ops),
		.dev_groups = goodix_berlin_groups,
	},
	.probe = goodix_berlin_spi_probe,
	.id_table = goodix_berlin_spi_ids,
};
module_spi_driver(goodix_berlin_spi_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Goodix Berlin SPI Touchscreen driver");
MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
