/*
 * Copyright (c) 2016 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file I2C/TWI Controller driver for Atmel SAM3 family processor
 *
 * Notes on this driver:
 * 1. The controller does not have a documented way to
 *    issue RESTART when changing transfer direction as master.
 *
 *    Datasheet said about using the internal address register
 *    (IADR) to write 3 bytes before reading. This limits
 *    the number of bytes to write before a read. Also,
 *    this was documented under 7-bit addressing, and nothing
 *    about this with 10-bit addressing.
 *
 *    Experiments show that STOP has to be issued or the controller
 *    hangs forever. This was tested with reading and writing
 *    the Fujitsu I2C-based FRAM MB85RC256V.
 */

#include <nanokernel.h>

#include <board.h>
#include <i2c.h>

#include <misc/util.h>

#include "i2c_atmel_sam3.h"


#ifndef CONFIG_I2C_DEBUG
#define DBG(...) { ; }
#else
#if defined(CONFIG_STDOUT_CONSOLE)
#include <stdio.h>
#define DBG printf
#else
#define DBG printk
#endif /* CONFIG_STDOUT_CONSOLE */
#endif /* CONFIG_I2C_DEBUG */


/* for use with dev_data->state */
#define STATE_READY		0
#define STATE_BUSY		(1 << 0)
#define STATE_TX		(1 << 1)
#define STATE_RX		(1 << 2)
#define STATE_ERR		(1 << 3)


typedef void (*config_func_t)(struct device *port);


struct i2c_sam3_dev_config {
	volatile struct __twi	*port;

	config_func_t		config_func;
};

struct i2c_sam3_dev_data {
	device_sync_call_t	sync;
	union dev_config	dev_config;

	volatile uint32_t	state;

	uint8_t			*xfr_buf;
	uint32_t		xfr_len;
	uint32_t		xfr_flags;
};


/**
 * Calculate clock dividers for TWI controllers.
 *
 * @param dev Device struct
 * @return Value used for TWI_CWGR register.
 */
static uint32_t clk_div_calc(struct device *dev)
{
#if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 84000000)

	/* Use pre-calculated clock dividers when the SoC is running at
	 * 84 MHz. This saves execution time and ROM space.
	 */
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;

	switch ((dev_data->dev_config.bits.speed)) {
	case I2C_SPEED_STANDARD:
		/* CKDIV = 1
		 * CHDIV = CLDIV = 208 = 0xD0
		 */
		return 0x0001D0D0;
	case I2C_SPEED_FAST:
		/* CKDIV = 0
		 * CHDIV = CLDIV = 101 = 0x65
		 */
		return 0x00006565;
	default:
		/* Return 0 as error */
		return 0;
	}

#else /* !(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 84000000) */

	/* Need to calcualte the clock dividers if the SoC is running at
	 * other frequencies.
	 */

	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;
	uint32_t i2c_clk;
	uint32_t cldiv, ckdiv;

	/* The T(low) and T(high) are used to calculate CLDIV and CHDIV.
	 * Since we treat both clock low and clock high to have same period,
	 * the I2C clock frequency used for calculation has to be doubled.
	 */
	switch ((dev_data->dev_config.bits.speed)) {
	case I2C_SPEED_STANDARD:
		i2c_clk = 100000 * 2;
		break;
	case I2C_SPEED_FAST:
		i2c_clk = 400000 * 2;
		break;
	default:
		/* Return 0 as error */
		return 0;
	}

	cldiv = (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) / i2c_clk - 4;
	ckdiv = 0;
	while (cldiv > 255) {
		ckdiv++;
		cldiv /= 2;
	}

	return ((ckdiv << TWI_CWGR_CKDIV_POS) + (cldiv << TWI_CWGR_CHDIV_POS)
		+ (cldiv << TWI_CWGR_CLDIV_POS));

#endif /* CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC == 84000000 */
}

static int i2c_sam3_runtime_configure(struct device *dev, uint32_t config)
{
	struct i2c_sam3_dev_config * const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;
	uint32_t reg;
	uint32_t clk;

	dev_data->dev_config.raw = config;
	reg = 0;

	/* Currently support master mode only */
	if (dev_data->dev_config.bits.is_slave_read) {
		return DEV_INVALID_CONF;
	}

	/* Calculate clock dividers */
	clk = clk_div_calc(dev);
	if (!clk) {
		return DEV_INVALID_CONF;
	}

	/* Disable controller first before changing anything */
	cfg->port->cr = TWI_CR_MSDIS | TWI_CR_SVDIS;

	/* Setup clock wavefore generator */
	cfg->port->cwgr = clk;

	return DEV_OK;
}

static void i2c_sam3_isr(void *arg)
{
	struct device * const dev = (struct device *)arg;
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;

	/* Disable all interrupts so they can be processed
	 * before ISR is called again.
	 */
	cfg->port->idr = TWI_IRQ_DISABLE;

	device_sync_call_complete(&dev_data->sync);
}

/* This should be used ONLY IF <bits> are the only bits of concern.
 * This is because reading from status register will clear certain
 * bits, and thus status might be ignored afterwards.
 */
static inline void sr_bits_set_wait(struct device *dev, uint32_t bits)
{
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;

	while (!(cfg->port->sr & bits)) {
		/* loop till <bits> are set */
	};
}

/* Clear the status registers from previous transfers */
static inline void status_reg_clear(struct device *dev)
{
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;
	uint32_t stat_reg;

	do {
		stat_reg = cfg->port->sr;

		/* ignore these */
		stat_reg &= ~(TWI_IRQ_PDC | TWI_IRQ_TXRDY | TWI_IRQ_TXCOMP
				| TWI_IRQ_SVREAD);

		if (stat_reg & TWI_IRQ_OVRE) {
			continue;
		}

		if (stat_reg & TWI_IRQ_NACK) {
			continue;
		}

		if (stat_reg & TWI_IRQ_RXRDY) {
			stat_reg = cfg->port->rhr;
		}
	} while (stat_reg);
}

static inline void transfer_setup(struct device *dev, uint16_t slave_address)
{
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;
	uint32_t mmr;
	uint32_t iadr;

	/* Set slave address */
	if (dev_data->dev_config.bits.use_10_bit_addr) {
		/* 10-bit slave addressing:
		 * first two bits goes to MMR/DADR, other 8 to IADR.
		 *
		 * 0x78 is the 0b11110xx bit prefix.
		 */
		mmr = 0x78 | ((slave_address >> 8) & 0x03);
		mmr <<= TWI_MMR_DADR_POS;
		mmr |= TWI_MMR_IADRSZ_1_BYTE;

		iadr = slave_address & 0xFF;
	} else {
		/* 7-bit slave addressing */
		mmr = (slave_address << TWI_MMR_DADR_POS) & TWI_MMR_DADR_MASK;

		iadr = 0;
	}

	cfg->port->mmr = mmr;
	cfg->port->iadr = iadr;
}

static inline void msg_write(struct device *dev)
{
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;

	/* To write to slave */
	cfg->port->mmr &= ~TWI_MMR_MREAD;

	/* Setup PDC to do DMA transfer */
	cfg->port->pdc.ptcr = PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS;
	cfg->port->pdc.tpr = (uint32_t)dev_data->xfr_buf;
	cfg->port->pdc.tcr = dev_data->xfr_len;

	/* Enable TX related interrupts.
	 * TXRDY is used by PDC so we don't want to interfere.
	 */
	cfg->port->ier = TWI_IRQ_ENDTX | TWI_IRQ_NACK;

	/* Start DMA transfer for TX */
	cfg->port->pdc.ptcr = PDC_PTCR_TXTEN;

	/* Wait till transfer is done or error occurs */
	device_sync_call_wait(&dev_data->sync);

	/* Check for error */
	if (cfg->port->sr & TWI_IRQ_NACK) {
		dev_data->state |= STATE_ERR;
		return;
	}

	/* STOP if needed */
	if (dev_data->xfr_flags & I2C_MSG_STOP) {
		cfg->port->cr = TWI_CR_STOP;

		/* Wait for TXCOMP if sending STOP.
		 * The transfer is done and the controller just needs to
		 * 'send' the STOP bit. So wait should be very short.
		 */
		sr_bits_set_wait(dev, TWI_IRQ_TXCOMP);
	} else {
		/* If no STOP, just wait for TX buffer to clear.
		 * At this point, this should take no time.
		 */
		sr_bits_set_wait(dev, TWI_IRQ_TXRDY);
	}

	/* Disable PDC */
	cfg->port->pdc.ptcr = PDC_PTCR_TXTDIS;
}

static inline void msg_read(struct device *dev)
{
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;
	uint32_t stat_reg;
	uint32_t ctrl_reg;
	uint32_t last_len;

	/* To read from slave */
	cfg->port->mmr |= TWI_MMR_MREAD;

	/* START bit in control register needs to be set to start
	 * reading from slave. If the previous message is also read,
	 * there is no need to set the START bit again.
	 */
	ctrl_reg = 0;
	if (dev_data->xfr_flags & I2C_MSG_RESTART) {
		ctrl_reg = TWI_CR_START;
	}
	/* If there is only one byte to read, need to send STOP also. */
	if ((dev_data->xfr_len == 1)
	    && (dev_data->xfr_flags & I2C_MSG_STOP)) {
		ctrl_reg |= TWI_CR_STOP;
	}
	cfg->port->cr = ctrl_reg;

	/* Note that this is entirely possible to do the last byte without
	 * going through DMA. But that requires another block of code to
	 * setup the transfer and test for RXRDY bit (and other). So do it
	 * this way to save a few bytes of code space.
	 */
	while (dev_data->xfr_len > 0) {
		/* Setup PDC to do DMA transfer. */
		cfg->port->pdc.ptcr = PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS;
		cfg->port->pdc.rpr = (uint32_t)dev_data->xfr_buf;

		/* Note that we need to set the STOP bit before reading
		 * last byte from RHR. So we need to process the last byte
		 * differently.
		 */
		if (dev_data->xfr_len > 1) {
			last_len = dev_data->xfr_len - 1;
		} else {
			last_len = 1;

			/* Set STOP bit for last byte */
			cfg->port->cr = TWI_CR_STOP;
		}
		cfg->port->pdc.rcr = last_len;

		/* Start DMA transfer for RX */
		cfg->port->pdc.ptcr = PDC_PTCR_RXTEN;

		/* Enable RX related interrupts
		 * RXRDY is used by PDC so we don't want to interfere.
		 */
		cfg->port->ier = TWI_IRQ_ENDRX | TWI_IRQ_NACK | TWI_IRQ_OVRE;

		/* Wait till transfer is done or error occurs */
		device_sync_call_wait(&dev_data->sync);

		/* Check for errors */
		stat_reg = cfg->port->sr;
		if ((stat_reg & TWI_IRQ_NACK) || (stat_reg & TWI_IRQ_OVRE)) {
			dev_data->state |= STATE_ERR;
			return;
		}

		/* no more bytes to send */
		if (dev_data->xfr_len == 0) {
			break;
		}

		dev_data->xfr_buf += last_len;
		dev_data->xfr_len -= last_len;
	}

	/* Disable PDC */
	cfg->port->pdc.ptcr = PDC_PTCR_RXTDIS;

	/* TXCOMP is kind of misleading here. This bit is set when THR/RHR
	 * and all shift registers are empty, and STOP (or NACK) is detected.
	 * So we wait here.
	 */
	sr_bits_set_wait(dev, TWI_IRQ_TXCOMP);
}

static int i2c_sam3_transfer(struct device *dev,
			     struct i2c_msg *msgs, uint8_t num_msgs,
			     uint16_t slave_address)
{
	struct i2c_sam3_dev_config *const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;
	struct i2c_msg *cur_msg = msgs;
	uint8_t msg_left = num_msgs;
	uint32_t pflags = 0;
	int ret = DEV_OK;

	/* Why bother processing no messages */
	if (!msgs || !num_msgs) {
		return DEV_INVALID_OP;
	}

	/* Device is busy servicing another transfer */
	if (dev_data->state & STATE_BUSY) {
		return DEV_FAIL;
	}

	dev_data->state = STATE_BUSY;

	/* Need to clear status from previous transfers */
	status_reg_clear(dev);

	/* Enable master */
	cfg->port->cr = TWI_CR_MSEN | TWI_CR_SVDIS;

	transfer_setup(dev, slave_address);

	/* Process all messages one-by-one */
	while (msg_left > 0) {
		dev_data->xfr_buf = cur_msg->buf;
		dev_data->xfr_len = cur_msg->len;
		dev_data->xfr_flags = cur_msg->flags;

		/* Send STOP if this is the last message */
		if (msg_left == 1) {
			dev_data->xfr_flags |= I2C_MSG_STOP;
		}

		/* The controller does not have a documented way to
		 * issue RESTART when changing transfer direction as master.
		 *
		 * Datasheet said about using the internal address register
		 * (IADR) to write 3 bytes before reading. This limits
		 * the number of bytes to write before a read. Also,
		 * this was documented under 7-bit addressing, and nothing
		 * about this with 10-bit addressing.
		 *
		 * Experiments show that STOP has to be issued or
		 * the controller hangs forever.
		 */
		if (msg_left > 1) {
			if ((dev_data->xfr_flags & I2C_MSG_RW_MASK) !=
			    (cur_msg[1].flags & I2C_MSG_RW_MASK)) {
				dev_data->xfr_flags |= I2C_MSG_STOP;
			}
		}

		/* The RESTART flag is used to indicate whether to set
		 * the START bit in control register. This is used only
		 * when changing from write to read, as the START needs
		 * to be set to start receiving. This is also to avoid
		 * setting the START bit multiple time if we are doing
		 * multiple read messages in a roll.
		 */
		if ((dev_data->xfr_flags & I2C_MSG_RW_MASK) !=
		    (pflags & I2C_MSG_RW_MASK)) {
			dev_data->xfr_flags |= I2C_MSG_RESTART;
		}

		dev_data->state &= ~(STATE_TX | STATE_RX);

		if ((dev_data->xfr_flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			dev_data->state |= STATE_TX;
			msg_write(dev);
		} else {
			dev_data->state |= STATE_RX;
			msg_read(dev);
		}

		if (dev_data->state & STATE_ERR) {
			/* Error encountered:
			 * Reset the controller and configure it again.
			 */
			cfg->port->pdc.ptcr = PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS;
			cfg->port->cr = TWI_CR_SWRST;

			i2c_sam3_runtime_configure(dev,
						   dev_data->dev_config.raw);

			ret = DEV_FAIL;
			goto done;
		}

		cur_msg++;
		msg_left--;
		pflags = cur_msg->flags;
	}

done:
	dev_data->state = STATE_READY;

	/* Disable master and slave after transfer is done */
	cfg->port->cr = TWI_CR_MSDIS | TWI_CR_SVDIS;

	return ret;
}

static int i2c_sam3_suspend(struct device *dev)
{
	/* TODO - add this code */
	return DEV_OK;
}

static int i2c_sam3_resume(struct device *dev)
{
	/* TODO - add this code */
	return DEV_OK;
}

static struct i2c_driver_api api_funcs = {
	.configure = i2c_sam3_runtime_configure,
	.transfer = i2c_sam3_transfer,
	.suspend = i2c_sam3_suspend,
	.resume = i2c_sam3_resume,
};

static int i2c_sam3_init(struct device *dev)
{
	struct i2c_sam3_dev_config * const cfg = dev->config->config_info;
	struct i2c_sam3_dev_data * const dev_data = dev->driver_data;

	dev->driver_api = &api_funcs;

	device_sync_call_init(&dev_data->sync);

	/* Disable all interrupts */
	cfg->port->idr = TWI_IRQ_DISABLE;

	cfg->config_func(dev);

	if (i2c_sam3_runtime_configure(dev, dev_data->dev_config.raw)
	    != DEV_OK) {
		DBG("I2C: Cannot set default configuration 0x%x\n",
		    dev_data->dev_config.raw);
		return DEV_INVALID_CONF;
	}

	return DEV_OK;
}

#ifdef CONFIG_I2C_ATMEL_SAM3_0

static void config_func_0(struct device *port);

static struct i2c_sam3_dev_config dev_config_0 = {
	.port = __TWI0,
	.config_func = config_func_0,
};

static struct i2c_sam3_dev_data dev_data_0 = {
	.dev_config.raw = CONFIG_I2C_ATMEL_SAM3_0_DEFAULT_CFG,
};

DEVICE_INIT(i2c_sam3_0, CONFIG_I2C_ATMEL_SAM3_0_NAME, &i2c_sam3_init,
	    &dev_data_0, &dev_config_0,
	    SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

static void config_func_0(struct device *dev)
{
	/* Enable clock for TWI0 controller */
	__PMC->pcer0 = (1 << PID_TWI0);

	IRQ_CONNECT(IRQ_TWI0, CONFIG_I2C_ATMEL_SAM3_0_INT_PRIORITY,
		    i2c_sam3_isr, DEVICE_GET(i2c_sam3_0), 0);
	irq_enable(IRQ_TWI0);
}

#endif /* CONFIG_I2C_ATMEL_SAM3_0 */

#ifdef CONFIG_I2C_ATMEL_SAM3_1

static void config_func_1(struct device *port);

static struct i2c_sam3_dev_config dev_config_1 = {
	.port = __TWI1,
	.config_func = config_func_1,
};

static struct i2c_sam3_dev_data dev_data_1 = {
	.dev_config.raw = CONFIG_I2C_ATMEL_SAM3_1_DEFAULT_CFG,
};

DEVICE_INIT(i2c_sam3_1, CONFIG_I2C_ATMEL_SAM3_1_NAME, &i2c_sam3_init,
	    &dev_data_1, &dev_config_1,
	    SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);

static void config_func_1(struct device *dev)
{
	/* Enable clock for TWI0 controller */
	__PMC->pcer0 = (1 << PID_TWI1);

	IRQ_CONNECT(IRQ_TWI1, CONFIG_I2C_ATMEL_SAM3_1_INT_PRIORITY,
		    i2c_sam3_isr, DEVICE_GET(i2c_sam3_1), 0);
	irq_enable(IRQ_TWI1);
}

#endif /* CONFIG_I2C_ATMEL_SAM3_1 */
