/*
 * Copyright (c) 2021 IoT.bzh
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT renesas_rcar_i2c

#include <errno.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/renesas_cpg_mssr.h>

#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(i2c_rcar);

#include "i2c-priv.h"

typedef void (*init_func_t)(const struct device *dev);

struct i2c_rcar_cfg {
	uint32_t reg_addr;
	init_func_t init_func;
	const struct device *clock_dev;
	struct rcar_cpg_clk mod_clk;
	uint32_t bitrate;
};

struct i2c_rcar_data {
	uint8_t status_mask;
	struct k_sem int_sem;
};

/* Registers */
#define RCAR_I2C_ICSCR          0x00    /* Slave Control Register */
#define RCAR_I2C_ICMCR          0x04    /* Master Control Register */
#define RCAR_I2C_ICSIER         0x10    /* Slave IRQ Enable */
#define RCAR_I2C_ICMIER         0x14    /* Master IRQ Enable */
#define RCAR_I2C_ICSSR          0x08    /* Slave Status */
#define RCAR_I2C_ICMSR          0x0c    /* Master Status */
#define RCAR_I2C_ICCCR          0x18    /* Clock Control Register */
#define RCAR_I2C_ICSAR          0x1c    /* Slave Address Register */
#define RCAR_I2C_ICMAR          0x20    /* Master Address Register */
#define RCAR_I2C_ICRXD_ICTXD    0x24    /* Receive Transmit Data Register */
#define RCAR_I2C_ICFBSCR        0x38    /* First Bit Setup Cycle (Gen3).*/
#define RCAR_I2C_ICFBSCR_TCYC17 0x0f    /* 17*Tcyc */

#define RCAR_I2C_ICMCR_MDBS     BIT(7)  /* Master Data Buffer Select */
#define RCAR_I2C_ICMCR_FSCL     BIT(6)  /* Forced SCL */
#define RCAR_I2C_ICMCR_FSDA     BIT(5)  /* Forced SDA */
#define RCAR_I2C_ICMCR_OBPC     BIT(4)  /* Override Bus Pin Control */
#define RCAR_I2C_ICMCR_MIE      BIT(3)  /* Master Interface Enable */
#define RCAR_I2C_ICMCR_TSBE     BIT(2)  /* Start Byte Transmission Enable */
#define RCAR_I2C_ICMCR_FSB      BIT(1)  /* Forced Stop onto the Bus */
#define RCAR_I2C_ICMCR_ESG      BIT(0)  /* Enable Start Generation */
#define RCAR_I2C_ICMCR_MASTER   (RCAR_I2C_ICMCR_MDBS | RCAR_I2C_ICMCR_MIE)

/* Bits to manage ICMIER and ICMSR registers */
#define RCAR_I2C_MNR            BIT(6)  /* Master Nack Received */
#define RCAR_I2C_MAL            BIT(5)  /* Master Arbitration lost */
#define RCAR_I2C_MST            BIT(4)  /* Master Stop Transmitted */
#define RCAR_I2C_MDE            BIT(3)  /* Master Data Empty */
#define RCAR_I2C_MDT            BIT(2)  /* Master Data Transmitted */
#define RCAR_I2C_MDR            BIT(1)  /* Master Data Received */
#define RCAR_I2C_MAT            BIT(0)  /* Master Address Transmitted */

/* Recommended bitrate settings from official documentation */
#define RCAR_I2C_ICCCR_CDF_100_KHZ  6
#define RCAR_I2C_ICCCR_CDF_400_KHZ  6
#define RCAR_I2C_ICCCR_SCGD_100_KHZ 21
#define RCAR_I2C_ICCCR_SCGD_400_KHZ 3

#define MAX_WAIT_US 100

static uint32_t i2c_rcar_read(const struct i2c_rcar_cfg *config,
			      uint32_t offs)
{
	return sys_read32(config->reg_addr + offs);
}

static void i2c_rcar_write(const struct i2c_rcar_cfg *config,
			   uint32_t offs, uint32_t value)
{
	sys_write32(value, config->reg_addr + offs);
}

static void i2c_rcar_isr(const struct device *dev)
{
	const struct i2c_rcar_cfg *config = dev->config;
	struct i2c_rcar_data *data = dev->data;

	if (((i2c_rcar_read(config, RCAR_I2C_ICMSR)) & data->status_mask) ==
	    data->status_mask) {
		k_sem_give(&data->int_sem);
		i2c_rcar_write(config, RCAR_I2C_ICMIER, 0);
	}
}

static int i2c_rcar_wait_for_state(const struct device *dev, uint8_t mask)
{
	const struct i2c_rcar_cfg *config = dev->config;
	struct i2c_rcar_data *data = dev->data;

	data->status_mask = mask;

	/* Reset interrupts semaphore */
	k_sem_reset(&data->int_sem);

	/* Enable interrupts */
	i2c_rcar_write(config, RCAR_I2C_ICMIER, mask);

	/* Wait for the interrupts */
	return k_sem_take(&data->int_sem, K_USEC(MAX_WAIT_US));
}

static int i2c_rcar_finish(const struct device *dev)
{
	const struct i2c_rcar_cfg *config = dev->config;
	int ret;

	/* Enable STOP generation */
	i2c_rcar_write(config, RCAR_I2C_ICMCR, RCAR_I2C_ICMCR_MASTER | RCAR_I2C_ICMCR_FSB);
	i2c_rcar_write(config, RCAR_I2C_ICMSR, 0);

	/* Wait for STOP to be transmitted */
	ret = i2c_rcar_wait_for_state(dev, RCAR_I2C_MST);
	i2c_rcar_write(config, RCAR_I2C_ICMSR, 0);

	/* Disable STOP generation */
	i2c_rcar_write(config, RCAR_I2C_ICMCR, RCAR_I2C_ICMCR_MASTER);

	return ret;
}

static int i2c_rcar_set_addr(const struct device *dev,
			     uint8_t chip, uint8_t read)
{
	const struct i2c_rcar_cfg *config = dev->config;

	/* Set slave address & transfer mode */
	i2c_rcar_write(config, RCAR_I2C_ICMAR, (chip << 1) | read);
	/* Reset */
	i2c_rcar_write(config, RCAR_I2C_ICMCR, RCAR_I2C_ICMCR_MASTER | RCAR_I2C_ICMCR_ESG);
	/* Clear Status */
	i2c_rcar_write(config, RCAR_I2C_ICMSR, 0);

	/* Wait for address & transfer mode to be transmitted */
	if (read != 0) {
		return i2c_rcar_wait_for_state(dev, RCAR_I2C_MAT | RCAR_I2C_MDR);
	} else {
		return i2c_rcar_wait_for_state(dev, RCAR_I2C_MAT | RCAR_I2C_MDE);
	}
}

static int i2c_rcar_transfer_msg(const struct device *dev, struct i2c_msg *msg)
{
	const struct i2c_rcar_cfg *config = dev->config;
	uint32_t i, reg;
	int ret = 0;

	if ((msg->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
		/* Reading as master */
		i2c_rcar_write(config, RCAR_I2C_ICMCR, RCAR_I2C_ICMCR_MASTER);

		for (i = 0; i < msg->len; i++) {
			if (msg->len - 1 == i) {
				i2c_rcar_write(config, RCAR_I2C_ICMCR, RCAR_I2C_ICMCR_MASTER |
					       RCAR_I2C_ICMCR_FSB);
			}

			/* Start data reception */
			reg = i2c_rcar_read(config, RCAR_I2C_ICMSR);
			reg &= ~RCAR_I2C_MDR;
			i2c_rcar_write(config, RCAR_I2C_ICMSR, reg);

			/* Wait for data to be received */
			ret = i2c_rcar_wait_for_state(dev, RCAR_I2C_MDR);
			if (ret != 0) {
				return ret;
			}

			msg->buf[i] = i2c_rcar_read(config, RCAR_I2C_ICRXD_ICTXD) & 0xff;
		}
	} else {
		/* Writing as master */
		for (i = 0; i < msg->len; i++) {
			i2c_rcar_write(config, RCAR_I2C_ICRXD_ICTXD, msg->buf[i]);

			i2c_rcar_write(config, RCAR_I2C_ICMCR, RCAR_I2C_ICMCR_MASTER);

			/* Start data transmission */
			reg = i2c_rcar_read(config, RCAR_I2C_ICMSR);
			reg &= ~RCAR_I2C_MDE;
			i2c_rcar_write(config, RCAR_I2C_ICMSR, reg);

			/* Wait for all data to be transmitted */
			ret = i2c_rcar_wait_for_state(dev, RCAR_I2C_MDE);
			if (ret != 0) {
				return ret;
			}
		}
	}

	return ret;
}

static int i2c_rcar_transfer(const struct device *dev,
			     struct i2c_msg *msgs, uint8_t num_msgs,
			     uint16_t addr)
{
	const struct i2c_rcar_cfg *config = dev->config;
	uint16_t timeout = 0;
	int ret;

	if (!num_msgs) {
		return 0;
	}

	/* Wait for the bus to be available */
	while ((i2c_rcar_read(config, RCAR_I2C_ICMCR) & RCAR_I2C_ICMCR_FSDA) && (timeout < 10)) {
		k_busy_wait(USEC_PER_MSEC);
		timeout++;
	}
	if (timeout == 10) {
		return -EIO;
	}

	do {
		/* We are not supporting 10-bit addressing */
		if ((msgs->flags & I2C_MSG_ADDR_10_BITS) == I2C_MSG_ADDR_10_BITS) {
			return -ENOTSUP;
		}

		/* Send slave address */
		if (i2c_rcar_set_addr(dev, addr, !!(msgs->flags & I2C_MSG_READ))) {
			return -EIO; /* No ACK received */
		}

		/* Transfer data */
		if (msgs->len) {
			ret = i2c_rcar_transfer_msg(dev, msgs);
			if (ret != 0) {
				return ret;
			}
		}

		/* Finish the transfer */
		if ((msgs->flags & I2C_MSG_STOP) == I2C_MSG_STOP) {
			ret = i2c_rcar_finish(dev);
			if (ret != 0) {
				return ret;
			}
		}

		/* Next message */
		msgs++;
		num_msgs--;
	} while (num_msgs);

	/* Complete without error */
	return 0;
}

static int i2c_rcar_configure(const struct device *dev, uint32_t dev_config)
{
	const struct i2c_rcar_cfg *config = dev->config;
	uint8_t cdf, scgd;

	/* We only support Master mode */
	if ((dev_config & I2C_MODE_CONTROLLER) != I2C_MODE_CONTROLLER) {
		return -ENOTSUP;
	}

	/* We are not supporting 10-bit addressing */
	if ((dev_config & I2C_ADDR_10_BITS) == I2C_ADDR_10_BITS) {
		return -ENOTSUP;
	}

	switch (I2C_SPEED_GET(dev_config)) {
	case I2C_SPEED_STANDARD:
		/* Use recommended value for 100 kHz bus */
		cdf = RCAR_I2C_ICCCR_CDF_100_KHZ;
		scgd = RCAR_I2C_ICCCR_SCGD_100_KHZ;
		break;
	case I2C_SPEED_FAST:
		/* Use recommended value for 400 kHz bus */
		cdf = RCAR_I2C_ICCCR_CDF_400_KHZ;
		scgd = RCAR_I2C_ICCCR_SCGD_400_KHZ;
		break;
	default:
		return -ENOTSUP;
	}

	/* Setting ICCCR to recommended value */
	i2c_rcar_write(config, RCAR_I2C_ICCCR, (scgd << 3) | cdf);

	/* Reset slave mode */
	i2c_rcar_write(config, RCAR_I2C_ICSIER, 0);
	i2c_rcar_write(config, RCAR_I2C_ICSAR, 0);
	i2c_rcar_write(config, RCAR_I2C_ICSCR, 0);
	i2c_rcar_write(config, RCAR_I2C_ICSSR, 0);

	/* Reset master mode */
	i2c_rcar_write(config, RCAR_I2C_ICMIER, 0);
	i2c_rcar_write(config, RCAR_I2C_ICMCR, 0);
	i2c_rcar_write(config, RCAR_I2C_ICMSR, 0);
	i2c_rcar_write(config, RCAR_I2C_ICMAR, 0);

	return 0;
}

static int i2c_rcar_init(const struct device *dev)
{
	const struct i2c_rcar_cfg *config = dev->config;
	struct i2c_rcar_data *data = dev->data;
	uint32_t bitrate_cfg;
	int ret;

	k_sem_init(&data->int_sem, 0, 1);

	if (!device_is_ready(config->clock_dev)) {
		return -ENODEV;
	}

	ret = clock_control_on(config->clock_dev,
			       (clock_control_subsys_t)&config->mod_clk);

	if (ret != 0) {
		return ret;
	}

	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);

	ret = i2c_rcar_configure(dev, I2C_MODE_CONTROLLER | bitrate_cfg);
	if (ret != 0) {
		return ret;
	}

	config->init_func(dev);

	return 0;
}

static const struct i2c_driver_api i2c_rcar_driver_api = {
	.configure = i2c_rcar_configure,
	.transfer = i2c_rcar_transfer,
};

/* Device Instantiation */
#define I2C_RCAR_INIT(n)						       \
	static void i2c_rcar_##n##_init(const struct device *dev);	       \
	static const struct i2c_rcar_cfg i2c_rcar_cfg_##n = {		       \
		.reg_addr = DT_INST_REG_ADDR(n),			       \
		.init_func = i2c_rcar_##n##_init,			       \
		.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)),	       \
		.bitrate = DT_INST_PROP(n, clock_frequency),		       \
		.mod_clk.module =					       \
			DT_INST_CLOCKS_CELL_BY_IDX(n, 0, module),	       \
		.mod_clk.domain =					       \
			DT_INST_CLOCKS_CELL_BY_IDX(n, 0, domain),	       \
	};								       \
									       \
	static struct i2c_rcar_data i2c_rcar_data_##n;			       \
									       \
	I2C_DEVICE_DT_INST_DEFINE(n,					       \
			      i2c_rcar_init,				       \
			      NULL,					       \
			      &i2c_rcar_data_##n,			       \
			      &i2c_rcar_cfg_##n,			       \
			      POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,	       \
			      &i2c_rcar_driver_api			       \
			      );					       \
	static void i2c_rcar_##n##_init(const struct device *dev)	       \
	{								       \
		IRQ_CONNECT(DT_INST_IRQN(n),				       \
			    0,						       \
			    i2c_rcar_isr,				       \
			    DEVICE_DT_INST_GET(n), 0);			       \
									       \
		irq_enable(DT_INST_IRQN(n));				       \
	}

DT_INST_FOREACH_STATUS_OKAY(I2C_RCAR_INIT)
