/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT espressif_esp32_i2c

/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <soc/dport_reg.h>
#include <soc/i2c_reg.h>
#include <rom/gpio.h>
#include <soc/gpio_sig_map.h>

#include <soc.h>
#include <errno.h>
#include <drivers/gpio.h>
#include <drivers/gpio/gpio_esp32.h>
#include <drivers/i2c.h>
#include <sys/util.h>
#include <string.h>

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

#include "i2c-priv.h"

/* Number of entries in hardware command queue */
#define I2C_ESP32_NUM_CMDS 16
/* Number of bytes in hardware FIFO */
#define I2C_ESP32_BUFFER_SIZE 32

#define I2C_ESP32_TIMEOUT_MS 100
#define I2C_ESP32_SPIN_THRESHOLD 600
#define I2C_ESP32_YIELD_THRESHOLD (I2C_ESP32_SPIN_THRESHOLD / 2)
#define I2C_ESP32_TIMEOUT \
	((I2C_ESP32_YIELD_THRESHOLD) + (I2C_ESP32_SPIN_THRESHOLD))

enum i2c_esp32_opcodes {
	I2C_ESP32_OP_RSTART,
	I2C_ESP32_OP_WRITE,
	I2C_ESP32_OP_READ,
	I2C_ESP32_OP_STOP,
	I2C_ESP32_OP_END
};

struct i2c_esp32_cmd {
	u32_t num_bytes : 8;
	u32_t ack_en : 1;
	u32_t ack_exp : 1;
	u32_t ack_val : 1;
	u32_t opcode : 3;
	u32_t reserved : 17;
	u32_t done : 1;
};

struct i2c_esp32_data {
	u32_t dev_config;
	u16_t address;

	struct k_sem fifo_sem;
	struct k_sem transfer_sem;
};

typedef void (*irq_connect_cb)(void);

struct i2c_esp32_config {
	int index;

	irq_connect_cb connect_irq;

	const struct {
		int sda_out;
		int sda_in;
		int scl_out;
		int scl_in;
	} sig;

	const struct {
		int scl;
		int sda;
	} pins;

	const struct esp32_peripheral peripheral;

	const struct {
		bool tx_lsb_first;
		bool rx_lsb_first;
	} mode;

	const struct {
		int source;
		int line;
	} irq;

	const u32_t default_config;
	const u32_t bitrate;
};

static int i2c_esp32_configure_pins(int pin, int matrix_out, int matrix_in)
{
	const int pin_mode = GPIO_OUTPUT_HIGH |
			     GPIO_OPEN_DRAIN  |
			     GPIO_PULL_UP;
	const char *device_name = gpio_esp32_get_gpio_for_pin(pin);
	struct device *gpio;
	int ret;

	if (!device_name) {
		return -EINVAL;
	}
	gpio = device_get_binding(device_name);
	if (!gpio) {
		return -EINVAL;
	}

	ret = gpio_pin_configure(gpio, pin, pin_mode);
	if (ret < 0) {
		return ret;
	}

	esp32_rom_gpio_matrix_out(pin, matrix_out, false, false);
	esp32_rom_gpio_matrix_in(pin, matrix_in, false);

	return 0;
}

static int i2c_esp32_configure_speed(const struct i2c_esp32_config *config,
				     u32_t speed)
{
	static const u32_t speed_to_freq_tbl[] = {
		[I2C_SPEED_STANDARD] = KHZ(100),
		[I2C_SPEED_FAST] = KHZ(400),
		[I2C_SPEED_FAST_PLUS] = MHZ(1),
		[I2C_SPEED_HIGH] = 0,
		[I2C_SPEED_ULTRA] = 0
	};
	u32_t freq_hz = speed_to_freq_tbl[speed];
	u32_t period;

	if (!freq_hz) {
		return -ENOTSUP;
	}

	period = (APB_CLK_FREQ / freq_hz);

	period /= 2U; /* Set hold and setup times to 1/2th of period */

	esp32_set_mask32(period << I2C_SCL_LOW_PERIOD_S,
		   I2C_SCL_LOW_PERIOD_REG(config->index));
	esp32_set_mask32(period << I2C_SCL_HIGH_PERIOD_S,
		   I2C_SCL_HIGH_PERIOD_REG(config->index));

	esp32_set_mask32(period << I2C_SCL_START_HOLD_TIME_S,
		   I2C_SCL_START_HOLD_REG(config->index));
	esp32_set_mask32(period << I2C_SCL_RSTART_SETUP_TIME_S,
		   I2C_SCL_RSTART_SETUP_REG(config->index));
	esp32_set_mask32(period << I2C_SCL_STOP_HOLD_TIME_S,
		   I2C_SCL_STOP_HOLD_REG(config->index));
	esp32_set_mask32(period << I2C_SCL_STOP_SETUP_TIME_S,
		   I2C_SCL_STOP_SETUP_REG(config->index));

	period /= 2U; /* Set sample and hold times to 1/4th of period */
	esp32_set_mask32(period << I2C_SDA_HOLD_TIME_S,
		   I2C_SDA_HOLD_REG(config->index));
	esp32_set_mask32(period << I2C_SDA_SAMPLE_TIME_S,
		   I2C_SDA_SAMPLE_REG(config->index));

	return 0;
}

static int i2c_esp32_configure(struct device *dev, u32_t dev_config)
{
	const struct i2c_esp32_config *config = dev->config_info;
	struct i2c_esp32_data *data = dev->driver_data;
	unsigned int key = irq_lock();
	u32_t v = 0U;
	int ret;

	ret = i2c_esp32_configure_pins(config->pins.scl,
				       config->sig.scl_out,
				       config->sig.scl_in);
	if (ret < 0) {
		return ret;
	}

	ret = i2c_esp32_configure_pins(config->pins.sda,
				       config->sig.sda_out,
				       config->sig.sda_in);
	if (ret < 0) {
		return ret;
	}

	esp32_enable_peripheral(&config->peripheral);

	/* MSB or LSB first is configurable for both TX and RX */
	if (config->mode.tx_lsb_first) {
		v |= I2C_TX_LSB_FIRST;
	}

	if (config->mode.rx_lsb_first) {
		v |= I2C_RX_LSB_FIRST;
	}

	if (dev_config & I2C_MODE_MASTER) {
		v |= I2C_MS_MODE;
		sys_write32(0, I2C_SLAVE_ADDR_REG(config->index));
	} else {
		u32_t addr = (data->address & I2C_SLAVE_ADDR_V);

		if (dev_config & I2C_ADDR_10_BITS) {
			addr |= I2C_ADDR_10BIT_EN;
		}
		sys_write32(addr << I2C_SLAVE_ADDR_S,
			    I2C_SLAVE_ADDR_REG(config->index));

		/* Before setting up FIFO and interrupts, stop transmission */
		sys_clear_bit(I2C_CTR_REG(config->index), I2C_TRANS_START_S);

		/* Byte after address isn't the offset address in slave RAM */
		sys_clear_bit(I2C_FIFO_CONF_REG(config->index),
			      I2C_FIFO_ADDR_CFG_EN_S);
	}

	/* Use open-drain for clock and data pins */
	v |= (I2C_SCL_FORCE_OUT | I2C_SDA_FORCE_OUT);
	v |= I2C_CLK_EN;
	sys_write32(v, I2C_CTR_REG(config->index));

	ret = i2c_esp32_configure_speed(config, I2C_SPEED_GET(dev_config));
	if (ret < 0) {
		goto out;
	}

	/* Use FIFO to transmit data */
	sys_clear_bit(I2C_FIFO_CONF_REG(config->index), I2C_NONFIFO_EN_S);

	v = CONFIG_I2C_ESP32_TIMEOUT & I2C_TIME_OUT_REG;
	sys_write32(v << I2C_TIME_OUT_REG_S, I2C_TO_REG(config->index));

	/* Enable interrupt types handled by the ISR */
	sys_write32(I2C_ACK_ERR_INT_ENA_M |
		    I2C_TIME_OUT_INT_ENA_M |
		    I2C_TRANS_COMPLETE_INT_ENA_M |
		    I2C_ARBITRATION_LOST_INT_ENA_M,
		    I2C_INT_ENA_REG(config->index));

	irq_enable(config->irq.line);

out:
	irq_unlock(key);

	return ret;
}

static inline void i2c_esp32_reset_fifo(const struct i2c_esp32_config *config)
{
	u32_t reg = I2C_FIFO_CONF_REG(config->index);

	/* Writing 1 and then 0 to these bits will reset the I2C fifo */
	esp32_set_mask32(I2C_TX_FIFO_RST | I2C_RX_FIFO_RST, reg);
	esp32_clear_mask32(I2C_TX_FIFO_RST | I2C_RX_FIFO_RST, reg);
}

static int i2c_esp32_spin_yield(int *counter)
{
	*counter = *counter + 1;

	if (*counter > I2C_ESP32_TIMEOUT) {
		return -ETIMEDOUT;
	}

	if (*counter > I2C_ESP32_SPIN_THRESHOLD) {
		k_yield();
	}

	return 0;
}

static int i2c_esp32_transmit(struct device *dev)
{
	const struct i2c_esp32_config *config = dev->config_info;
	struct i2c_esp32_data *data = dev->driver_data;
	u32_t status;

	/* Start transmission and wait for the ISR to give the semaphore */
	sys_set_bit(I2C_CTR_REG(config->index), I2C_TRANS_START_S);
	if (k_sem_take(&data->fifo_sem, K_MSEC(I2C_ESP32_TIMEOUT_MS)) < 0) {
		return -ETIMEDOUT;
	}

	status = sys_read32(I2C_INT_RAW_REG(config->index));
	if (status & (I2C_ARBITRATION_LOST_INT_RAW | I2C_ACK_ERR_INT_RAW)) {
		return -EIO;
	}
	if (status & I2C_TIME_OUT_INT_RAW) {
		return -ETIMEDOUT;
	}

	return 0;
}

static int i2c_esp32_wait(struct device *dev,
			  volatile struct i2c_esp32_cmd *wait_cmd)
{
	const struct i2c_esp32_config *config = dev->config_info;
	int counter = 0;
	int ret;

	if (wait_cmd) {
		while (!wait_cmd->done) {
			ret = i2c_esp32_spin_yield(&counter);
			if (ret < 0) {
				return ret;
			}
		}
	}

	/* Wait for I2C bus to finish its business */
	while (sys_read32(I2C_SR_REG(config->index)) & I2C_BUS_BUSY) {
		ret = i2c_esp32_spin_yield(&counter);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}

static int i2c_esp32_transmit_wait(struct device *dev,
				   volatile struct i2c_esp32_cmd *wait_cmd)
{
	int ret;

	ret = i2c_esp32_transmit(dev);
	if (!ret) {
		return i2c_esp32_wait(dev, wait_cmd);
	}

	return ret;
}

static volatile struct i2c_esp32_cmd *
i2c_esp32_write_addr(struct device *dev,
		     volatile struct i2c_esp32_cmd *cmd,
		     struct i2c_msg *msg,
		     u16_t addr)
{
	const struct i2c_esp32_config *config = dev->config_info;
	struct i2c_esp32_data *data = dev->driver_data;
	u32_t addr_len = 1U;

	i2c_esp32_reset_fifo(config);

	sys_write32(addr & I2C_FIFO_RDATA, I2C_DATA_APB_REG(config->index));
	if (data->dev_config & I2C_ADDR_10_BITS) {
		sys_write32(I2C_DATA_APB_REG(config->index),
			    (addr >> 8) & I2C_FIFO_RDATA);
		addr_len++;
	}

	if ((msg->flags & I2C_MSG_RW_MASK) != I2C_MSG_WRITE) {
		*cmd++ = (struct i2c_esp32_cmd) {
			.opcode = I2C_ESP32_OP_WRITE,
			.ack_en = true,
			.num_bytes = addr_len,
		};
	} else {
		msg->len += addr_len;
	}

	return cmd;
}

static int i2c_esp32_read_msg(struct device *dev, u16_t addr,
			      struct i2c_msg msg)
{
	const struct i2c_esp32_config *config = dev->config_info;
	volatile struct i2c_esp32_cmd *cmd =
		(void *)I2C_COMD0_REG(config->index);
	u32_t i;
	int ret;

	/* Set the R/W bit to R */
	addr |= BIT(0);

	*cmd++ = (struct i2c_esp32_cmd) {
		.opcode = I2C_ESP32_OP_RSTART
	};

	cmd = i2c_esp32_write_addr(dev, cmd, &msg, addr);

	for (; msg.len; cmd = (void *)I2C_COMD0_REG(config->index)) {
		volatile struct i2c_esp32_cmd *wait_cmd = NULL;
		u32_t to_read = MIN(I2C_ESP32_BUFFER_SIZE, msg.len - 1);

		/* Might be the last byte, in which case, `to_read` will
		 * be 0 here.  See comment below.
		 */
		if (to_read) {
			*cmd++ = (struct i2c_esp32_cmd) {
				.opcode = I2C_ESP32_OP_READ,
				.num_bytes = to_read,
			};
		}

		/* I2C master won't acknowledge the last byte read from the
		 * slave device.  Divide the read command in two segments as
		 * recommended by the ESP32 Technical Reference Manual.
		 */
		if (msg.len - to_read <= 1U) {
			/* Read the last byte and explicitly ask for an
			 * acknowledgment.
			 */
			*cmd++ = (struct i2c_esp32_cmd) {
				.opcode = I2C_ESP32_OP_READ,
				.num_bytes = 1,
				.ack_val = true,
			};

			/* Account for the `msg.len - 1` when clamping
			 * transmission length to FIFO buffer size.
			 */
			to_read++;

			if (msg.flags & I2C_MSG_STOP) {
				wait_cmd = cmd;
				*cmd++ = (struct i2c_esp32_cmd) {
					.opcode = I2C_ESP32_OP_STOP
				};
			}
		}
		if (!wait_cmd) {
			*cmd++ = (struct i2c_esp32_cmd) {
				.opcode = I2C_ESP32_OP_END
			};
		}

		ret = i2c_esp32_transmit_wait(dev, wait_cmd);
		if (ret < 0) {
			return ret;
		}

		for (i = 0U; i < to_read; i++) {
			u32_t v = sys_read32(I2C_DATA_APB_REG(config->index));

			*msg.buf++ = v & I2C_FIFO_RDATA;
		}
		msg.len -= to_read;

		i2c_esp32_reset_fifo(config);
	}

	return 0;
}

static int i2c_esp32_write_msg(struct device *dev, u16_t addr,
			       struct i2c_msg msg)
{
	const struct i2c_esp32_config *config = dev->config_info;
	volatile struct i2c_esp32_cmd *cmd =
		(void *)I2C_COMD0_REG(config->index);

	*cmd++ = (struct i2c_esp32_cmd) {
		.opcode = I2C_ESP32_OP_RSTART
	};

	cmd = i2c_esp32_write_addr(dev, cmd, &msg, addr);

	for (; msg.len; cmd = (void *)I2C_COMD0_REG(config->index)) {
		u32_t to_send = MIN(I2C_ESP32_BUFFER_SIZE, msg.len);
		u32_t i;
		int ret;

		/* Copy data to TX fifo */
		for (i = 0U; i < to_send; i++) {
			sys_write32(*msg.buf++,
				    I2C_DATA_APB_REG(config->index));
		}
		*cmd++ = (struct i2c_esp32_cmd) {
			.opcode = I2C_ESP32_OP_WRITE,
			.num_bytes = to_send,
			.ack_en = true,
		};
		msg.len -= to_send;

		if (!msg.len && (msg.flags & I2C_MSG_STOP)) {
			*cmd = (struct i2c_esp32_cmd) {
				.opcode = I2C_ESP32_OP_STOP
			};
		} else {
			*cmd = (struct i2c_esp32_cmd) {
				.opcode = I2C_ESP32_OP_END
			};
		}

		ret = i2c_esp32_transmit_wait(dev, cmd);
		if (ret < 0) {
			return ret;
		}

		i2c_esp32_reset_fifo(config);
	}

	return 0;
}

static int i2c_esp32_transfer(struct device *dev, struct i2c_msg *msgs,
			      u8_t num_msgs, u16_t addr)
{
	struct i2c_esp32_data *data = dev->driver_data;
	int ret = 0;
	u8_t i;

	k_sem_take(&data->transfer_sem, K_FOREVER);

	/* Mask out unused address bits, and make room for R/W bit */
	addr &= BIT_MASK(data->dev_config & I2C_ADDR_10_BITS ? 10 : 7);
	addr <<= 1;

	for (i = 0U; i < num_msgs; i++) {
		if ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			ret = i2c_esp32_write_msg(dev, addr, msgs[i]);
		} else {
			ret = i2c_esp32_read_msg(dev, addr, msgs[i]);
		}

		if (ret < 0) {
			break;
		}
	}

	k_sem_give(&data->transfer_sem);

	return ret;
}

static void i2c_esp32_isr(void *arg)
{
	const int fifo_give_mask = I2C_ACK_ERR_INT_ST |
				   I2C_TIME_OUT_INT_ST |
				   I2C_TRANS_COMPLETE_INT_ST |
				   I2C_ARBITRATION_LOST_INT_ST;
	struct device *device = arg;
	const struct i2c_esp32_config *config = device->config_info;

	if (sys_read32(I2C_INT_STATUS_REG(config->index)) & fifo_give_mask) {
		struct i2c_esp32_data *data = device->driver_data;

		/* Only give the semaphore if a watched interrupt happens.
		 * Error checking is performed at the other side of the
		 * semaphore, by reading the status register.
		 */
		k_sem_give(&data->fifo_sem);
	}

	/* Acknowledge all I2C interrupts */
	sys_write32(~0, I2C_INT_CLR_REG(config->index));
}

static int i2c_esp32_init(struct device *dev);

static const struct i2c_driver_api i2c_esp32_driver_api = {
	.configure = i2c_esp32_configure,
	.transfer = i2c_esp32_transfer,
};

#if DT_HAS_NODE_STATUS_OKAY(DT_DRV_INST(0))
DEVICE_DECLARE(i2c_esp32_0);

static void i2c_esp32_connect_irq_0(void)
{
	IRQ_CONNECT(CONFIG_I2C_ESP32_0_IRQ, 1, i2c_esp32_isr,
		    DEVICE_GET(i2c_esp32_0), 0);
}

static const struct i2c_esp32_config i2c_esp32_config_0 = {
	.index = 0,
	.connect_irq = i2c_esp32_connect_irq_0,
	.sig = {
		.sda_out = I2CEXT0_SDA_OUT_IDX,
		.sda_in = I2CEXT0_SDA_IN_IDX,
		.scl_out = I2CEXT0_SCL_OUT_IDX,
		.scl_in = I2CEXT0_SCL_IN_IDX,
	},
	.pins = {
		.scl = DT_INST_PROP(0, scl_pin),
		.sda = DT_INST_PROP(0, sda_pin),
	},
	.peripheral = {
		.clk = DPORT_I2C_EXT0_CLK_EN,
		.rst = DPORT_I2C_EXT0_RST,
	},
	.mode = {
		.tx_lsb_first =
			IS_ENABLED(CONFIG_I2C_ESP32_0_TX_LSB_FIRST),
		.rx_lsb_first =
			IS_ENABLED(CONFIG_I2C_ESP32_0_RX_LSB_FIRST),
	},
	.irq = {
		.source = ETS_I2C_EXT0_INTR_SOURCE,
		.line = CONFIG_I2C_ESP32_0_IRQ,
	},
	.default_config = I2C_MODE_MASTER, /* FIXME: Zephyr don't support I2C_SLAVE_MODE */
	.bitrate = DT_INST_PROP(0, clock_frequency),
};

static struct i2c_esp32_data i2c_esp32_data_0;

DEVICE_AND_API_INIT(i2c_esp32_0, DT_INST_LABEL(0), &i2c_esp32_init,
		    &i2c_esp32_data_0, &i2c_esp32_config_0,
		    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,
		    &i2c_esp32_driver_api);
#endif /* DT_HAS_NODE_STATUS_OKAY(DT_DRV_INST(0)) */

#if DT_HAS_NODE_STATUS_OKAY(DT_DRV_INST(1))
DEVICE_DECLARE(i2c_esp32_1);

static void i2c_esp32_connect_irq_1(void)
{
	IRQ_CONNECT(CONFIG_I2C_ESP32_1_IRQ, 1, i2c_esp32_isr,
		    DEVICE_GET(i2c_esp32_1), 0);
}

static const struct i2c_esp32_config i2c_esp32_config_1 = {
	.index = 1,
	.connect_irq = i2c_esp32_connect_irq_1,
	.sig = {
		.sda_out = I2CEXT1_SDA_OUT_IDX,
		.sda_in = I2CEXT1_SDA_IN_IDX,
		.scl_out = I2CEXT1_SCL_OUT_IDX,
		.scl_in = I2CEXT1_SCL_IN_IDX,
	},
	.pins = {
		.scl = DT_INST_PROP(1, scl_pin),
		.sda = DT_INST_PROP(1, sda_pin),
	},
	.peripheral = {
		.clk = DPORT_I2C_EXT1_CLK_EN,
		.rst = DPORT_I2C_EXT1_RST,
	},
	.mode = {
		.tx_lsb_first =
			IS_ENABLED(CONFIG_I2C_ESP32_1_TX_LSB_FIRST),
		.rx_lsb_first =
			IS_ENABLED(CONFIG_I2C_ESP32_1_RX_LSB_FIRST),
	},
	.irq = {
		.source = ETS_I2C_EXT1_INTR_SOURCE,
		.line = CONFIG_I2C_ESP32_1_IRQ,
	},
	.default_config = I2C_MODE_MASTER, /* FIXME: Zephyr don't support I2C_SLAVE_MODE */
	.bitrate = DT_INST_PROP(1, clock_frequency),
};

static struct i2c_esp32_data i2c_esp32_data_1;

DEVICE_AND_API_INIT(i2c_esp32_1, DT_INST_LABEL(1), &i2c_esp32_init,
		    &i2c_esp32_data_1, &i2c_esp32_config_1,
		    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,
		    &i2c_esp32_driver_api);
#endif /* DT_HAS_NODE_STATUS_OKAY(DT_DRV_INST(1)) */

static int i2c_esp32_init(struct device *dev)
{
	const struct i2c_esp32_config *config = dev->config_info;
	struct i2c_esp32_data *data = dev->driver_data;
	u32_t bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
	unsigned int key = irq_lock();

	k_sem_init(&data->fifo_sem, 1, 1);
	k_sem_init(&data->transfer_sem, 1, 1);

	irq_disable(config->irq.line);

	/* Even if irq_enable() is called on config->irq.line, disable
	 * interrupt sources in the I2C controller.
	 */
	sys_write32(0, I2C_INT_ENA_REG(config->index));
	esp32_rom_intr_matrix_set(0, config->irq.source, config->irq.line);

	config->connect_irq();
	irq_unlock(key);

	return i2c_esp32_configure(dev, config->default_config | bitrate_cfg);
}
