// SPDX-License-Identifier: GPL-2.0
//
// tcan4x5x - Texas Instruments TCAN4x5x Family CAN controller driver
//
// Copyright (c) 2020 Pengutronix,
//                    Marc Kleine-Budde <kernel@pengutronix.de>
// Copyright (c) 2018-2019 Texas Instruments Incorporated
//                    http://www.ti.com/

#include "tcan4x5x.h"

#define TCAN4X5X_SPI_INSTRUCTION_WRITE (0x61 << 24)
#define TCAN4X5X_SPI_INSTRUCTION_READ (0x41 << 24)

#define TCAN4X5X_MAX_REGISTER 0x8ffc

static int tcan4x5x_regmap_gather_write(void *context,
					const void *reg, size_t reg_len,
					const void *val, size_t val_len)
{
	struct spi_device *spi = context;
	struct tcan4x5x_priv *priv = spi_get_drvdata(spi);
	struct tcan4x5x_map_buf *buf_tx = &priv->map_buf_tx;
	struct spi_transfer xfer[] = {
		{
			.tx_buf = buf_tx,
			.len = sizeof(buf_tx->cmd) + val_len,
		},
	};

	memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd.cmd) +
	       sizeof(buf_tx->cmd.addr));
	tcan4x5x_spi_cmd_set_len(&buf_tx->cmd, val_len);
	memcpy(buf_tx->data, val, val_len);

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

static int tcan4x5x_regmap_write(void *context, const void *data, size_t count)
{
	return tcan4x5x_regmap_gather_write(context, data, sizeof(__be32),
					    data + sizeof(__be32),
					    count - sizeof(__be32));
}

static int tcan4x5x_regmap_read(void *context,
				const void *reg_buf, size_t reg_len,
				void *val_buf, size_t val_len)
{
	struct spi_device *spi = context;
	struct tcan4x5x_priv *priv = spi_get_drvdata(spi);
	struct tcan4x5x_map_buf *buf_rx = &priv->map_buf_rx;
	struct tcan4x5x_map_buf *buf_tx = &priv->map_buf_tx;
	struct spi_transfer xfer[2] = {
		{
			.tx_buf = buf_tx,
		}
	};
	struct spi_message msg;
	int err;

	spi_message_init(&msg);
	spi_message_add_tail(&xfer[0], &msg);

	memcpy(&buf_tx->cmd, reg_buf, sizeof(buf_tx->cmd.cmd) +
	       sizeof(buf_tx->cmd.addr));
	tcan4x5x_spi_cmd_set_len(&buf_tx->cmd, val_len);

	if (spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX) {
		xfer[0].len = sizeof(buf_tx->cmd);

		xfer[1].rx_buf = val_buf;
		xfer[1].len = val_len;
		spi_message_add_tail(&xfer[1], &msg);
	} else {
		xfer[0].rx_buf = buf_rx;
		xfer[0].len = sizeof(buf_tx->cmd) + val_len;

		if (TCAN4X5X_SANITIZE_SPI)
			memset(buf_tx->data, 0x0, val_len);
	}

	err = spi_sync(spi, &msg);
	if (err)
		return err;

	if (!(spi->controller->flags & SPI_CONTROLLER_HALF_DUPLEX))
		memcpy(val_buf, buf_rx->data, val_len);

	return 0;
}

static const struct regmap_range tcan4x5x_reg_table_yes_range[] = {
	regmap_reg_range(0x0000, 0x002c),	/* Device ID and SPI Registers */
	regmap_reg_range(0x0800, 0x083c),	/* Device configuration registers and Interrupt Flags*/
	regmap_reg_range(0x1000, 0x10fc),	/* M_CAN */
	regmap_reg_range(0x8000, 0x87fc),	/* MRAM */
};

static const struct regmap_access_table tcan4x5x_reg_table = {
	.yes_ranges = tcan4x5x_reg_table_yes_range,
	.n_yes_ranges = ARRAY_SIZE(tcan4x5x_reg_table_yes_range),
};

static const struct regmap_config tcan4x5x_regmap = {
	.reg_bits = 24,
	.reg_stride = 4,
	.pad_bits = 8,
	.val_bits = 32,
	.wr_table = &tcan4x5x_reg_table,
	.rd_table = &tcan4x5x_reg_table,
	.max_register = TCAN4X5X_MAX_REGISTER,
	.cache_type = REGCACHE_NONE,
	.read_flag_mask = (__force unsigned long)
		cpu_to_be32(TCAN4X5X_SPI_INSTRUCTION_READ),
	.write_flag_mask = (__force unsigned long)
		cpu_to_be32(TCAN4X5X_SPI_INSTRUCTION_WRITE),
};

static const struct regmap_bus tcan4x5x_bus = {
	.write = tcan4x5x_regmap_write,
	.gather_write = tcan4x5x_regmap_gather_write,
	.read = tcan4x5x_regmap_read,
	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
	.val_format_endian_default = REGMAP_ENDIAN_BIG,
	.max_raw_read = 256,
	.max_raw_write = 256,
};

int tcan4x5x_regmap_init(struct tcan4x5x_priv *priv)
{
	priv->regmap = devm_regmap_init(&priv->spi->dev, &tcan4x5x_bus,
					priv->spi, &tcan4x5x_regmap);
	return PTR_ERR_OR_ZERO(priv->regmap);
}
