/*
 * Copyright 2019 NXP
 *
 * SPDX-License-Identifier: GPL-2.0
 */

#include <common.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <dm.h>
#include <fdtdec.h>
#include <i2c.h>
#include <asm/mach-imx/imx_vservice.h>

DECLARE_GLOBAL_DATA_PTR;

#define MAX_SRTM_I2C_BUF_SIZE 16
#define SRTM_I2C_CATEGORY 0x09
#define SRTM_VERSION 0x0001
#define SRTM_TYPE_REQ 0x0
#define SRTM_TYPE_RESP 0x1
#define SRTM_CMD_READ 0x0
#define SRTM_CMD_WRITE 0x1

#define I2C_M_SELECT_MUX_BUS	0x010000
#define I2C_M_SRTM_STOP       0x0200

struct imx_virt_i2c_bus {
	int index;
	ulong base;
	struct imx_vservice_channel *vservice;
};

struct imx_srtm_i2c_msg {
	u8 categary;
	u8 version[2];
	u8 type;
	u8 command;
	u8 priority;
	u8 reserved[4];

	u8 i2c_bus;
	u8 return_val;
	u16 slave_addr;
	u16 flag;
	u16 data_length;
	u8 data_buf[MAX_SRTM_I2C_BUF_SIZE];
};

static void imx_virt_i2c_msg_dump(struct imx_srtm_i2c_msg *msg)
{
	u32 i = 0;
	u32 size = sizeof(struct imx_srtm_i2c_msg);
	u8 *buf = (u8 *)msg;

	for (; i < size; i++) {
		debug("%02x ", buf[i]);
		if (i % 16 == 15)
			debug("\n");
	}
}

static int imx_virt_i2c_read(struct udevice *bus, u32 chip, u8 *buf, int len, uint flag)
{
	struct imx_srtm_i2c_msg *msg;
	u32 size;
	int ret = 0;
	struct imx_virt_i2c_bus *i2c_bus = dev_get_priv(bus);

	debug("imx_virt_i2c_read, bus %d\n", i2c_bus->index);

	if (len > MAX_SRTM_I2C_BUF_SIZE) {
		printf("virt_i2c_read exceed the buf length, len=%d\n", len);
		return -EINVAL;
	}

	size = sizeof(struct imx_srtm_i2c_msg);
	msg = imx_vservice_get_buffer(i2c_bus->vservice, size);
	if (msg == NULL)
		return -ENOMEM;

	/* Fill buf with SRTM i2c format */
	msg->categary = SRTM_I2C_CATEGORY;
	msg->version[0] = SRTM_VERSION & 0xff;
	msg->version[1] = (SRTM_VERSION >> 8) & 0xff;
	msg->type = SRTM_TYPE_REQ;
	msg->command = SRTM_CMD_READ;
	msg->priority = 1;

	msg->i2c_bus = i2c_bus->index;
	msg->return_val = 0;
	msg->slave_addr = (u16)chip;
	msg->flag = (u16)flag;
	msg->data_length = len;

	imx_virt_i2c_msg_dump(msg);

	/* Send request and get return data */
	ret = imx_vservice_blocking_request(i2c_bus->vservice, (u8 *)msg, &size);
	if (ret) {
		printf("Vservice request is failed, ret %d\n", ret);
		return ret;
	}

	if (msg->type != SRTM_TYPE_RESP || msg->categary != SRTM_I2C_CATEGORY
		|| msg->command !=SRTM_CMD_READ) {
		printf("Error read response message\n");
		return -EIO;
	}

	if (msg->return_val != 0)
		return msg->return_val;

	if (len != 0)
		memcpy(buf, msg->data_buf, msg->data_length);

	return ret;
}

static int imx_virt_i2c_write(struct udevice *bus, u32 chip, u8 *buf, int len, uint flag)
{
	struct imx_srtm_i2c_msg *msg;
	u32 size;
	int ret = 0;
	struct imx_virt_i2c_bus *i2c_bus = dev_get_priv(bus);

	debug("imx_virt_i2c_write, bus %d\n", i2c_bus->index);

	if (len > MAX_SRTM_I2C_BUF_SIZE) {
		printf("virt_i2c_read exceed the buf length, len=%d\n", len);
		return -EINVAL;
	}

	size = sizeof(struct imx_srtm_i2c_msg);
	msg = imx_vservice_get_buffer(i2c_bus->vservice, size);
	if (msg == NULL)
		return -ENOMEM;

	/* Fill buf with SRTM i2c format */
	msg->categary = SRTM_I2C_CATEGORY;
	msg->version[0] = SRTM_VERSION & 0xff;
	msg->version[1] = (SRTM_VERSION >> 8) & 0xff;
	msg->type = SRTM_TYPE_REQ;
	msg->command = SRTM_CMD_WRITE;
	msg->priority = 1;

	msg->i2c_bus = i2c_bus->index;
	msg->return_val = 0;
	msg->slave_addr = (u16)chip;
	msg->flag = (u16)flag;
	msg->data_length = len;

	imx_virt_i2c_msg_dump(msg);

	if (buf) /* probe chip does not have data buffer */
		memcpy(msg->data_buf, buf, msg->data_length);

	/* Send request and get return data */
	ret = imx_vservice_blocking_request(i2c_bus->vservice,  (u8 *)msg, &size);
	if (ret) {
		printf("Vservice request is failed, ret %d\n", ret);
		return ret;
	}

	if (msg->type != SRTM_TYPE_RESP || msg->categary != SRTM_I2C_CATEGORY
		|| msg->command !=SRTM_CMD_WRITE) {
		printf("Error write response message\n");
		return -EIO;
	}

	if (msg->return_val != 0) {
		debug("Peer process message, ret %d\n", msg->return_val);
		return -EACCES;
	}

	debug("imx_vservice_blocking_request get size = %d\n", size);

	return ret;

}

static int imx_virt_i2c_probe_chip(struct udevice *bus, u32 chip,
				u32 chip_flags)
{
	debug("imx_virt_i2c_probe_chip\n");

	return imx_virt_i2c_write(bus, chip, NULL, 0, I2C_M_SRTM_STOP);
}

static int imx_virt_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
{
	int ret = 0;
	uint flag = 0;

	for (; nmsgs > 0; nmsgs--, msg++) {
		debug("virt_i2c_xfer: chip=0x%x, len=0x%x, buf=0x%08x\n", msg->addr, msg->len, *msg->buf);

		flag = msg->flags;
		if (nmsgs == 1)
			flag |= I2C_M_SRTM_STOP;

		if (flag & I2C_M_RD)
			ret = imx_virt_i2c_read(bus, msg->addr, msg->buf, msg->len, flag);
		else {
			ret = imx_virt_i2c_write(bus, msg->addr, msg->buf,
					    msg->len, flag);
			if (ret)
				break;
		}
	}

	if (ret)
		printf("i2c_xfer: error %d\n", ret);

	return ret;
}

static int imx_virt_i2c_probe(struct udevice *bus)
{
	struct imx_virt_i2c_bus *i2c_bus = dev_get_priv(bus);
	fdt_addr_t addr;

	addr = devfdt_get_addr(bus);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	i2c_bus->base = addr;
	i2c_bus->index = bus->seq;

	debug("virt_i2c : controller bus %d at 0x%lx,  bus udev 0x%lx\n",
	      bus->seq, i2c_bus->base, (ulong)bus);

	i2c_bus->vservice = imx_vservice_setup(bus);
	if (i2c_bus->vservice == NULL) {
		printf("virt_i2c: Faild to setup vservice\n");
		return -ENODEV;
	}

	return 0;
}

static int imx_virt_i2c_set_flags(struct udevice *child_dev, uint flags)
{
#ifdef CONFIG_I2C_MUX_IMX_VIRT
	if (child_dev->uclass->uc_drv->id == UCLASS_I2C_MUX) {
		struct udevice *bus = child_dev->parent;
		struct imx_virt_i2c_bus *i2c_bus = dev_get_priv(bus);

		if (flags == 0) {
			i2c_bus->index = bus->seq;
		} else if (flags & I2C_M_SELECT_MUX_BUS) {
			i2c_bus->index = (flags >> 24) & 0xff;
		}

		debug("virt_i2c_set_flags bus %d\n", i2c_bus->index);
	}
#endif
	return 0;
}

int __weak board_imx_virt_i2c_bind(struct udevice *dev)
{
	return 0;
}

static int imx_virt_i2c_bind(struct udevice *dev)
{
	debug("imx_virt_i2c_bind, %s, seq %d\n", dev->name, dev->req_seq);

	return board_imx_virt_i2c_bind(dev);
}

static int imx_virt_i2c_child_post_bind(struct udevice *child_dev)
{
#ifdef CONFIG_I2C_MUX_IMX_VIRT
	if (child_dev->uclass->uc_drv->id == UCLASS_I2C_MUX) {
		if (!strcmp(child_dev->driver->name, "imx_virt_i2c_mux"))
			return 0;
		else
			return -ENODEV;
	}
#endif

	return 0;
}

static const struct dm_i2c_ops imx_virt_i2c_ops = {
	.xfer		= imx_virt_i2c_xfer,
	.probe_chip	= imx_virt_i2c_probe_chip,
	.set_flags = imx_virt_i2c_set_flags,
};

static const struct udevice_id imx_virt_i2c_ids[] = {
	{ .compatible = "fsl,imx-virt-i2c", },
	{}
};

U_BOOT_DRIVER(imx_virt_i2c) = {
	.name = "imx_virt_i2c",
	.id = UCLASS_I2C,
	.of_match = imx_virt_i2c_ids,
	.bind = imx_virt_i2c_bind,
	.probe = imx_virt_i2c_probe,
	.child_post_bind = imx_virt_i2c_child_post_bind,
	.priv_auto_alloc_size = sizeof(struct imx_virt_i2c_bus),
	.ops = &imx_virt_i2c_ops,
	.flags	= DM_FLAG_IGNORE_POWER_ON | DM_FLAG_IGNORE_DEFAULT_CLKS,
};
