// SPDX-License-Identifier: GPL-2.0
/*
 * Rockchip RK806 Core (SPI) driver
 *
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
 * Copyright (c) 2023 Collabora Ltd.
 *
 * Author: Xu Shengfei <xsf@rock-chips.com>
 * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
 */

#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rk808.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>

#define RK806_ADDR_SIZE 2
#define RK806_CMD_WITH_SIZE(CMD, VALUE_BYTES) \
	(RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (VALUE_BYTES - 1))

static const struct regmap_range rk806_volatile_ranges[] = {
	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
};

static const struct regmap_access_table rk806_volatile_table = {
	.yes_ranges = rk806_volatile_ranges,
	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
};

static const struct regmap_config rk806_regmap_config_spi = {
	.reg_bits = 16,
	.val_bits = 8,
	.max_register = RK806_BUCK_RSERVE_REG5,
	.cache_type = REGCACHE_RBTREE,
	.volatile_table = &rk806_volatile_table,
};

static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
{
	struct device *dev = context;
	struct spi_device *spi = to_spi_device(dev);
	struct spi_transfer xfer[2] = { 0 };
	/* data and thus count includes the register address */
	size_t val_size = count - RK806_ADDR_SIZE;
	char cmd;

	if (val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
		return -EINVAL;

	cmd = RK806_CMD_WITH_SIZE(WRITE, val_size);

	xfer[0].tx_buf = &cmd;
	xfer[0].len = sizeof(cmd);
	xfer[1].tx_buf = vdata;
	xfer[1].len = count;

	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
}

static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
			      void *val, size_t val_size)
{
	struct device *dev = context;
	struct spi_device *spi = to_spi_device(dev);
	char txbuf[3] = { 0 };

	if (reg_size != RK806_ADDR_SIZE ||
	    val_size < 1 || val_size > (RK806_CMD_LEN_MSK + 1))
		return -EINVAL;

	/* TX buffer contains command byte followed by two address bytes */
	txbuf[0] = RK806_CMD_WITH_SIZE(READ, val_size);
	memcpy(txbuf+1, vreg, reg_size);

	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
}

static const struct regmap_bus rk806_regmap_bus_spi = {
	.write = rk806_spi_bus_write,
	.read = rk806_spi_bus_read,
	.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
};

static int rk8xx_spi_probe(struct spi_device *spi)
{
	struct regmap *regmap;

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

	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
}

static const struct of_device_id rk8xx_spi_of_match[] = {
	{ .compatible = "rockchip,rk806", },
	{ }
};
MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);

static const struct spi_device_id rk8xx_spi_id_table[] = {
	{ "rk806", 0 },
	{ }
};
MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);

static struct spi_driver rk8xx_spi_driver = {
	.driver		= {
		.name	= "rk8xx-spi",
		.of_match_table = rk8xx_spi_of_match,
	},
	.probe		= rk8xx_spi_probe,
	.id_table	= rk8xx_spi_id_table,
};
module_spi_driver(rk8xx_spi_driver);

MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
MODULE_LICENSE("GPL");
