// 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 <asm/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	3
#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN	(GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
						 GOODIX_BERLIN_REGISTER_WIDTH + \
						 GOODIX_BERLIN_SPI_READ_DUMMY_LEN)
#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;
	struct spi_transfer xfers;
	struct spi_message spi_msg;
	const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */
	u8 *buf;
	int error;

	if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH)
		return -EINVAL;

	buf = kzalloc(GOODIX_BERLIN_SPI_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(3bytes) + 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, GOODIX_BERLIN_SPI_READ_DUMMY_LEN);

	xfers.tx_buf = buf;
	xfers.rx_buf = buf;
	xfers.len = GOODIX_BERLIN_SPI_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);
	else
		memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size);

	kfree(buf);
	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 */
	u8 *buf;
	int error;

	buf = 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);

	kfree(buf);
	return error;
}

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)
{
	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 - GOODIX_BERLIN_SPI_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);
	if (error)
		return error;

	return 0;
}

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

static const struct of_device_id goodix_berlin_spi_of_match[] = {
	{ .compatible = "goodix,gt9916", },
	{ }
};
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),
	},
	.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>");
