/*
 * Copyright (c) 2018 SiFive Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT sifive_i2c0

#define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(i2c_sifive);

#include <device.h>
#include <drivers/i2c.h>
#include <sys/sys_io.h>

#include "i2c-priv.h"

/* Macros */

#define I2C_REG(config, reg)	((mem_addr_t) ((config)->base + reg))
#define IS_SET(config, reg, value) (sys_read8(I2C_REG(config, reg)) & (value))

/* Register Offsets */

#define REG_PRESCALE_LOW	0x00
#define REG_PRESCALE_HIGH	0x04

#define REG_CONTROL		0x08

/* Transmit on write, receive on read */
#define REG_TRANSMIT		0x0c
#define REG_RECEIVE		0x0c

/* Command on write, status on read */
#define REG_COMMAND		0x10
#define REG_STATUS		0x10

/* Values */

#define SF_CONTROL_EN	(1 << 7)
#define SF_CONTROL_IE	(1 << 6)

#define SF_TX_WRITE	(0 << 0)
#define SF_TX_READ	(1 << 0)

#define SF_CMD_START	(1 << 7)
#define SF_CMD_STOP	(1 << 6)
#define SF_CMD_READ	(1 << 5)
#define SF_CMD_WRITE	(1 << 4)
#define SF_CMD_ACK	(1 << 3)
#define SF_CMD_IACK	(1 << 0)

#define SF_STATUS_RXACK	(1 << 7)
#define SF_STATUS_BUSY	(1 << 6)
#define SF_STATUS_AL	(1 << 5)
#define SF_STATUS_TIP	(1 << 1)
#define SF_STATUS_IP	(1 << 0)

/* Structure declarations */

struct i2c_sifive_cfg {
	u32_t base;
	u32_t f_sys;
	u32_t f_bus;
};

/* Helper functions */

static inline bool i2c_sifive_busy(struct device *dev)
{
	const struct i2c_sifive_cfg *config = dev->config_info;

	return IS_SET(config, REG_STATUS, SF_STATUS_TIP);
}

static int i2c_sifive_send_addr(struct device *dev,
				u16_t addr,
				u16_t rw_flag)
{
	const struct i2c_sifive_cfg *config = dev->config_info;
	u8_t command = 0U;

	/* Wait for a previous transfer to complete */
	while (i2c_sifive_busy(dev)) {
	}

	/* Set transmit register to address with read/write flag */
	sys_write8((addr | rw_flag), I2C_REG(config, REG_TRANSMIT));

	/* Addresses are always written */
	command = SF_CMD_WRITE | SF_CMD_START;

	/* Write the command register to start the transfer */
	sys_write8(command, I2C_REG(config, REG_COMMAND));

	while (i2c_sifive_busy(dev)) {
	}

	if (IS_SET(config, REG_STATUS, SF_STATUS_RXACK)) {
		LOG_ERR("I2C Rx failed to acknowledge\n");
		return -EIO;
	}

	return 0;
}

static int i2c_sifive_write_msg(struct device *dev,
				struct i2c_msg *msg,
				u16_t addr)
{
	const struct i2c_sifive_cfg *config = dev->config_info;
	int rc = 0;
	u8_t command = 0U;

	rc = i2c_sifive_send_addr(dev, addr, SF_TX_WRITE);
	if (rc != 0) {
		LOG_ERR("I2C failed to write message\n");
		return rc;
	}

	for (u32_t i = 0; i < msg->len; i++) {
		/* Wait for a previous transfer */
		while (i2c_sifive_busy(dev)) {
		}

		/* Put data in transmit reg */
		sys_write8((msg->buf)[i], I2C_REG(config, REG_TRANSMIT));

		/* Generate command byte */
		command = SF_CMD_WRITE;

		/* On the last byte of the message */
		if (i == (msg->len - 1)) {
			/* If the stop bit is requested, set it */
			if (msg->flags & I2C_MSG_STOP) {
				command |= SF_CMD_STOP;
			}
		}

		/* Write command reg */
		sys_write8(command, I2C_REG(config, REG_COMMAND));

		/* Wait for a previous transfer */
		while (i2c_sifive_busy(dev)) {
		}

		if (IS_SET(config, REG_STATUS, SF_STATUS_RXACK)) {
			LOG_ERR("I2C Rx failed to acknowledge\n");
			return -EIO;
		}
	}

	return 0;
}

static int i2c_sifive_read_msg(struct device *dev,
			       struct i2c_msg *msg,
			       u16_t addr)
{
	const struct i2c_sifive_cfg *config = dev->config_info;
	u8_t command = 0U;

	i2c_sifive_send_addr(dev, addr, SF_TX_READ);

	while (i2c_sifive_busy(dev)) {
	}

	for (int i = 0; i < msg->len; i++) {
		/* Generate command byte */
		command = SF_CMD_READ;

		/* On the last byte of the message */
		if (i == (msg->len - 1)) {
			/* Set NACK to end read */
			command |= SF_CMD_ACK;

			/* If the stop bit is requested, set it */
			if (msg->flags & I2C_MSG_STOP) {
				command |= SF_CMD_STOP;
			}
		}

		/* Write command reg */
		sys_write8(command, I2C_REG(config, REG_COMMAND));

		/* Wait for the read to complete */
		while (i2c_sifive_busy(dev)) {
		}

		/* Store the received byte */
		(msg->buf)[i] = sys_read8(I2C_REG(config, REG_RECEIVE));
	}

	return 0;
}

/* API Functions */

static int i2c_sifive_configure(struct device *dev, u32_t dev_config)
{
	const struct i2c_sifive_cfg *config = NULL;
	u32_t i2c_speed = 0U;
	u16_t prescale = 0U;

	/* Check for NULL pointers */
	if (dev == NULL) {
		LOG_ERR("Device handle is NULL");
		return -EINVAL;
	}
	config = dev->config_info;
	if (config == NULL) {
		LOG_ERR("Device config is NULL");
		return -EINVAL;
	}

	/* Disable the I2C peripheral */
	sys_write8(0, I2C_REG(config, REG_CONTROL));

	/* Configure bus frequency */
	switch (I2C_SPEED_GET(dev_config)) {
	case I2C_SPEED_STANDARD:
		i2c_speed = 100000U; /* 100 KHz */
		break;
	case I2C_SPEED_FAST:
		i2c_speed = 400000U; /* 400 KHz */
		break;
	case I2C_SPEED_FAST_PLUS:
	case I2C_SPEED_HIGH:
	case I2C_SPEED_ULTRA:
	default:
		LOG_ERR("Unsupported I2C speed requested");
		return -ENOTSUP;
	}

	/* Calculate prescale value */
	prescale = (config->f_sys / (i2c_speed * 5U)) - 1;

	/* Configure peripheral with calculated prescale */
	sys_write8((u8_t) (0xFF & prescale), I2C_REG(config, REG_PRESCALE_LOW));
	sys_write8((u8_t) (0xFF & (prescale >> 8)),
		   I2C_REG(config, REG_PRESCALE_HIGH));

	/* Support I2C Master mode only */
	if (!(dev_config & I2C_MODE_MASTER)) {
		LOG_ERR("I2C only supports operation as master");
		return -ENOTSUP;
	}

	/*
	 * Driver does not support 10-bit addressing. This can be added
	 * in the future when needed.
	 */
	if (dev_config & I2C_ADDR_10_BITS) {
		LOG_ERR("I2C driver does not support 10-bit addresses");
		return -ENOTSUP;
	}

	/* Enable the I2C peripheral */
	sys_write8(SF_CONTROL_EN, I2C_REG(config, REG_CONTROL));

	return 0;
}

static int i2c_sifive_transfer(struct device *dev,
			       struct i2c_msg *msgs,
			       u8_t num_msgs,
			       u16_t addr)
{
	int rc = 0;

	/* Check for NULL pointers */
	if (dev == NULL) {
		LOG_ERR("Device handle is NULL");
		return -EINVAL;
	}
	if (dev->config_info == NULL) {
		LOG_ERR("Device config is NULL");
		return -EINVAL;
	}
	if (msgs == NULL) {
		return -EINVAL;
	}

	for (int i = 0; i < num_msgs; i++) {
		if (msgs[i].flags & I2C_MSG_READ) {
			rc = i2c_sifive_read_msg(dev, &(msgs[i]), addr);
		} else {
			rc = i2c_sifive_write_msg(dev, &(msgs[i]), addr);
		}

		if (rc != 0) {
			LOG_ERR("I2C failed to transfer messages\n");
			return rc;
		}
	}

	return 0;
};

static int i2c_sifive_init(struct device *dev)
{
	const struct i2c_sifive_cfg *config = dev->config_info;
	u32_t dev_config = 0U;
	int rc = 0;

	dev_config = (I2C_MODE_MASTER | i2c_map_dt_bitrate(config->f_bus));

	rc = i2c_sifive_configure(dev, dev_config);
	if (rc != 0) {
		LOG_ERR("Failed to configure I2C on init");
		return rc;
	}

	return 0;
}


static struct i2c_driver_api i2c_sifive_api = {
	.configure = i2c_sifive_configure,
	.transfer = i2c_sifive_transfer,
};

/* Device instantiation */

#define I2C_SIFIVE_INIT(n) \
	static struct i2c_sifive_cfg i2c_sifive_cfg_##n = { \
		.base = DT_INST_REG_ADDR(n), \
		.f_sys = DT_INST_PROP(n, input_frequency), \
		.f_bus = DT_INST_PROP(n, clock_frequency), \
	}; \
	DEVICE_AND_API_INIT(i2c_##n, \
			    DT_INST_LABEL(n), \
			    i2c_sifive_init, \
			    NULL, \
			    &i2c_sifive_cfg_##n, \
			    POST_KERNEL, \
			    CONFIG_I2C_INIT_PRIORITY, \
			    &i2c_sifive_api);

DT_INST_FOREACH_STATUS_OKAY(I2C_SIFIVE_INIT)
