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

/* 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 <gpio/gpio_esp32.h>
#include <drivers/i2c.h>
#include <sys/util.h>
#include <string.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;
};

static int i2c_esp32_configure_pins(int pin, int matrix_out, int matrix_in)
{
	const int pin_mode = GPIO_DIR_OUT |
			     GPIO_DS_DISCONNECT_LOW |
			     GPIO_PUD_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;
	}

	ret = gpio_pin_write(gpio, pin, 1);
	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->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->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, 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->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->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->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->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->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,
};

#ifdef CONFIG_I2C_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 = CONFIG_I2C_ESP32_0_SCL_PIN,
		.sda = CONFIG_I2C_ESP32_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 = CONFIG_I2C_0_DEFAULT_CFG,
};

static struct i2c_esp32_data i2c_esp32_data_0;

DEVICE_AND_API_INIT(i2c_esp32_0, CONFIG_I2C_0_NAME, &i2c_esp32_init,
		    &i2c_esp32_data_0, &i2c_esp32_config_0,
		    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,
		    &i2c_esp32_driver_api);
#endif /* CONFIG_I2C_0 */

#ifdef CONFIG_I2C_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 = CONFIG_I2C_ESP32_1_SCL_PIN,
		.sda = CONFIG_I2C_ESP32_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 = CONFIG_I2C_1_DEFAULT_CFG,
};

static struct i2c_esp32_data i2c_esp32_data_1;

DEVICE_AND_API_INIT(i2c_esp32_1, CONFIG_I2C_1_NAME, &i2c_esp32_init,
		    &i2c_esp32_data_1, &i2c_esp32_config_1,
		    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,
		    &i2c_esp32_driver_api);
#endif /* CONFIG_I2C_1 */

static int i2c_esp32_init(struct device *dev)
{
	const struct i2c_esp32_config *config = dev->config->config_info;
	struct i2c_esp32_data *data = dev->driver_data;
	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);
}
