// SPDX-License-Identifier: GPL-2.0
/*
 * SPI access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
 *
 * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
 */

#include <linux/crc8.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>

#include <linux/mfd/tps6594.h>

#define TPS6594_SPI_PAGE_SHIFT	5
#define TPS6594_SPI_READ_BIT	BIT(4)

static bool enable_crc;
module_param(enable_crc, bool, 0444);
MODULE_PARM_DESC(enable_crc, "Enable CRC feature for SPI interface");

DECLARE_CRC8_TABLE(tps6594_spi_crc_table);

static int tps6594_spi_reg_read(void *context, unsigned int reg, unsigned int *val)
{
	struct spi_device *spi = context;
	struct tps6594 *tps = spi_get_drvdata(spi);
	u8 buf[4] = { 0 };
	size_t count_rx = 1;
	int ret;

	buf[0] = reg;
	buf[1] = TPS6594_REG_TO_PAGE(reg) << TPS6594_SPI_PAGE_SHIFT | TPS6594_SPI_READ_BIT;

	if (tps->use_crc)
		count_rx++;

	ret = spi_write_then_read(spi, buf, 2, buf + 2, count_rx);
	if (ret < 0)
		return ret;

	if (tps->use_crc && buf[3] != crc8(tps6594_spi_crc_table, buf, 3, CRC8_INIT_VALUE))
		return -EIO;

	*val = buf[2];

	return 0;
}

static int tps6594_spi_reg_write(void *context, unsigned int reg, unsigned int val)
{
	struct spi_device *spi = context;
	struct tps6594 *tps = spi_get_drvdata(spi);
	u8 buf[4] = { 0 };
	size_t count = 3;

	buf[0] = reg;
	buf[1] = TPS6594_REG_TO_PAGE(reg) << TPS6594_SPI_PAGE_SHIFT;
	buf[2] = val;

	if (tps->use_crc)
		buf[3] = crc8(tps6594_spi_crc_table, buf, count++, CRC8_INIT_VALUE);

	return spi_write(spi, buf, count);
}

static struct regmap_config tps6594_spi_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
	.volatile_table = &tps6594_volatile_table,
	.reg_read = tps6594_spi_reg_read,
	.reg_write = tps6594_spi_reg_write,
	.use_single_read = true,
	.use_single_write = true,
};

static const struct of_device_id tps6594_spi_of_match_table[] = {
	{ .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
	{ .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
	{ .compatible = "ti,lp8764-q1",  .data = (void *)LP8764,  },
	{ .compatible = "ti,tps65224-q1", .data = (void *)TPS65224, },
	{}
};
MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);

static int tps6594_spi_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct tps6594 *tps;
	const struct of_device_id *match;

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

	spi_set_drvdata(spi, tps);

	tps->dev = dev;
	tps->reg = spi_get_chipselect(spi, 0);
	tps->irq = spi->irq;

	match = of_match_device(tps6594_spi_of_match_table, dev);
	if (!match)
		return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
	tps->chip_id = (unsigned long)match->data;

	if (tps->chip_id == TPS65224)
		tps6594_spi_regmap_config.volatile_table = &tps65224_volatile_table;

	tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
	if (IS_ERR(tps->regmap))
		return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");

	crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL);

	return tps6594_device_init(tps, enable_crc);
}

static struct spi_driver tps6594_spi_driver = {
	.driver	= {
		.name = "tps6594",
		.of_match_table = tps6594_spi_of_match_table,
	},
	.probe = tps6594_spi_probe,
};
module_spi_driver(tps6594_spi_driver);

MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
MODULE_DESCRIPTION("SPI Interface Driver for TPS65224, TPS6594/3, and LP8764");
MODULE_LICENSE("GPL");
