// SPDX-License-Identifier: GPL-2.0+
/*
 * I2C driver for Renesas Synchronization Management Unit (SMU) devices.
 *
 * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company.
 */

#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/rsmu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include "rsmu.h"

/*
 * 32-bit register address: the lower 8 bits of the register address come
 * from the offset addr byte and the upper 24 bits come from the page register.
 */
#define	RSMU_CM_PAGE_ADDR		0xFC
#define RSMU_CM_PAGE_MASK		0xFFFFFF00
#define RSMU_CM_ADDRESS_MASK		0x000000FF

/*
 * 15-bit register address: the lower 7 bits of the register address come
 * from the offset addr byte and the upper 8 bits come from the page register.
 */
#define	RSMU_SABRE_PAGE_ADDR		0x7F
#define	RSMU_SABRE_PAGE_WINDOW		128

static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = {
	{
		.range_min = 0,
		.range_max = 0x400,
		.selector_reg = RSMU_SABRE_PAGE_ADDR,
		.selector_mask = 0xFF,
		.selector_shift = 0,
		.window_start = 0,
		.window_len = RSMU_SABRE_PAGE_WINDOW,
	}
};

static bool rsmu_sabre_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case RSMU_SABRE_PAGE_ADDR:
		return false;
	default:
		return true;
	}
}

static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
{
	struct i2c_client *client = to_i2c_client(rsmu->dev);
	struct i2c_msg msg[2];
	int cnt;

	msg[0].addr = client->addr;
	msg[0].flags = 0;
	msg[0].len = 1;
	msg[0].buf = &reg;

	msg[1].addr = client->addr;
	msg[1].flags = I2C_M_RD;
	msg[1].len = bytes;
	msg[1].buf = buf;

	cnt = i2c_transfer(client->adapter, msg, 2);

	if (cnt < 0) {
		dev_err(rsmu->dev, "i2c_transfer failed at addr: %04x!", reg);
		return cnt;
	} else if (cnt != 2) {
		dev_err(rsmu->dev,
			"i2c_transfer sent only %d of 2 messages", cnt);
		return -EIO;
	}

	return 0;
}

static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
{
	struct i2c_client *client = to_i2c_client(rsmu->dev);
	u8 msg[RSMU_MAX_WRITE_COUNT + 1]; /* 1 Byte added for the device register */
	int cnt;

	if (bytes > RSMU_MAX_WRITE_COUNT)
		return -EINVAL;

	msg[0] = reg;
	memcpy(&msg[1], buf, bytes);

	cnt = i2c_master_send(client, msg, bytes + 1);

	if (cnt < 0) {
		dev_err(&client->dev,
			"i2c_master_send failed at addr: %04x!", reg);
		return cnt;
	}

	return 0;
}

static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)
{
	u32 page = reg & RSMU_CM_PAGE_MASK;
	u8 buf[4];
	int err;

	/* Do not modify offset register for none-scsr registers */
	if (reg < RSMU_CM_SCSR_BASE)
		return 0;

	/* Simply return if we are on the same page */
	if (rsmu->page == page)
		return 0;

	buf[0] = 0x0;
	buf[1] = (u8)((page >> 8) & 0xFF);
	buf[2] = (u8)((page >> 16) & 0xFF);
	buf[3] = (u8)((page >> 24) & 0xFF);

	err = rsmu_write_device(rsmu, RSMU_CM_PAGE_ADDR, buf, sizeof(buf));
	if (err)
		dev_err(rsmu->dev, "Failed to set page offset 0x%x\n", page);
	else
		/* Remember the last page */
		rsmu->page = page;

	return err;
}

static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
{
	struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
	u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
	int err;

	err = rsmu_write_page_register(rsmu, reg);
	if (err)
		return err;

	err = rsmu_read_device(rsmu, addr, (u8 *)val, 1);
	if (err)
		dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr);

	return err;
}

static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
{
	struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
	u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
	u8 data = (u8)val;
	int err;

	err = rsmu_write_page_register(rsmu, reg);
	if (err)
		return err;

	err = rsmu_write_device(rsmu, addr, &data, 1);
	if (err)
		dev_err(rsmu->dev,
			"Failed to write offset address 0x%x\n", addr);

	return err;
}

static const struct regmap_config rsmu_cm_regmap_config = {
	.reg_bits = 32,
	.val_bits = 8,
	.max_register = 0x20120000,
	.reg_read = rsmu_reg_read,
	.reg_write = rsmu_reg_write,
	.cache_type = REGCACHE_NONE,
};

static const struct regmap_config rsmu_sabre_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = 0x400,
	.ranges = rsmu_sabre_range_cfg,
	.num_ranges = ARRAY_SIZE(rsmu_sabre_range_cfg),
	.volatile_reg = rsmu_sabre_volatile_reg,
	.cache_type = REGCACHE_MAPLE,
	.can_multi_write = true,
};

static const struct regmap_config rsmu_sl_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.reg_format_endian = REGMAP_ENDIAN_BIG,
	.max_register = 0x340,
	.cache_type = REGCACHE_NONE,
	.can_multi_write = true,
};

static int rsmu_i2c_probe(struct i2c_client *client)
{
	const struct i2c_device_id *id = i2c_client_get_device_id(client);
	const struct regmap_config *cfg;
	struct rsmu_ddata *rsmu;
	int ret;

	rsmu = devm_kzalloc(&client->dev, sizeof(*rsmu), GFP_KERNEL);
	if (!rsmu)
		return -ENOMEM;

	i2c_set_clientdata(client, rsmu);

	rsmu->dev = &client->dev;
	rsmu->type = (enum rsmu_type)id->driver_data;

	switch (rsmu->type) {
	case RSMU_CM:
		cfg = &rsmu_cm_regmap_config;
		break;
	case RSMU_SABRE:
		cfg = &rsmu_sabre_regmap_config;
		break;
	case RSMU_SL:
		cfg = &rsmu_sl_regmap_config;
		break;
	default:
		dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
		return -ENODEV;
	}

	if (rsmu->type == RSMU_CM)
		rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg);
	else
		rsmu->regmap = devm_regmap_init_i2c(client, cfg);
	if (IS_ERR(rsmu->regmap)) {
		ret = PTR_ERR(rsmu->regmap);
		dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret);
		return ret;
	}

	return rsmu_core_init(rsmu);
}

static void rsmu_i2c_remove(struct i2c_client *client)
{
	struct rsmu_ddata *rsmu = i2c_get_clientdata(client);

	rsmu_core_exit(rsmu);
}

static const struct i2c_device_id rsmu_i2c_id[] = {
	{ "8a34000",  RSMU_CM },
	{ "8a34001",  RSMU_CM },
	{ "82p33810", RSMU_SABRE },
	{ "82p33811", RSMU_SABRE },
	{ "8v19n850", RSMU_SL },
	{ "8v19n851", RSMU_SL },
	{}
};
MODULE_DEVICE_TABLE(i2c, rsmu_i2c_id);

static const struct of_device_id rsmu_i2c_of_match[] = {
	{ .compatible = "idt,8a34000",  .data = (void *)RSMU_CM },
	{ .compatible = "idt,8a34001",  .data = (void *)RSMU_CM },
	{ .compatible = "idt,82p33810", .data = (void *)RSMU_SABRE },
	{ .compatible = "idt,82p33811", .data = (void *)RSMU_SABRE },
	{ .compatible = "idt,8v19n850", .data = (void *)RSMU_SL },
	{ .compatible = "idt,8v19n851", .data = (void *)RSMU_SL },
	{}
};
MODULE_DEVICE_TABLE(of, rsmu_i2c_of_match);

static struct i2c_driver rsmu_i2c_driver = {
	.driver = {
		.name = "rsmu-i2c",
		.of_match_table = rsmu_i2c_of_match,
	},
	.probe = rsmu_i2c_probe,
	.remove	= rsmu_i2c_remove,
	.id_table = rsmu_i2c_id,
};

static int __init rsmu_i2c_init(void)
{
	return i2c_add_driver(&rsmu_i2c_driver);
}
subsys_initcall(rsmu_i2c_init);

static void __exit rsmu_i2c_exit(void)
{
	i2c_del_driver(&rsmu_i2c_driver);
}
module_exit(rsmu_i2c_exit);

MODULE_DESCRIPTION("Renesas SMU I2C driver");
MODULE_LICENSE("GPL");
