/*
 * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Copyright (c) 2010-2011 NVIDIA Corporation
 *  NVIDIA Corporation <www.nvidia.com>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <fdtdec.h>
#include <i2c.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/funcmux.h>
#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/clk_rst.h>
#include <asm/arch-tegra/tegra_i2c.h>

DECLARE_GLOBAL_DATA_PTR;

static unsigned int i2c_bus_num;

/* Information about i2c controller */
struct i2c_bus {
	int			id;
	enum periph_id		periph_id;
	int			speed;
	int			pinmux_config;
	struct i2c_control	*control;
	struct i2c_ctlr		*regs;
	int			is_dvc;		/* DVC type, rather than I2C */
	int			is_scs;		/* single clock src (T114+) */
	int			inited;			/* bus is inited */
	int			node;			/* fdt node */
	int			no_repeat_start;	/* no Repeat_Start */
};

static struct i2c_bus i2c_controllers[TEGRA_I2C_NUM_CONTROLLERS];

static void set_packet_mode(struct i2c_bus *i2c_bus)
{
	u32 config;

	config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK;

	if (i2c_bus->is_dvc) {
		struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;

		writel(config, &dvc->cnfg);
	} else {
		writel(config, &i2c_bus->regs->cnfg);
		/*
		 * program I2C_SL_CNFG.NEWSL to ENABLE. This fixes probe
		 * issues, i.e., some slaves may be wrongly detected.
		 */
		setbits_le32(&i2c_bus->regs->sl_cnfg, I2C_SL_CNFG_NEWSL_MASK);
	}
}

static void i2c_reset_controller(struct i2c_bus *i2c_bus)
{
	/* Reset I2C controller. */
	reset_periph(i2c_bus->periph_id, 1);

	/* re-program config register to packet mode */
	set_packet_mode(i2c_bus);
}

static void i2c_init_controller(struct i2c_bus *i2c_bus)
{
	/*
	 * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8
	 * here, in section 23.3.1, but in fact we seem to need a factor of
	 * 16 to get the right frequency.
	 */
	clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
		i2c_bus->speed * 2 * 8);

	if (i2c_bus->is_scs) {
		/*
		 * T114 I2C went to a single clock source for standard/fast and
		 * HS clock speeds. The new clock rate setting calculation is:
		 *  SCL = CLK_SOURCE.I2C /
		 *   (CLK_MULT_STD_FAST_MODE * (I2C_CLK_DIV_STD_FAST_MODE+1) *
		 *   I2C FREQUENCY DIVISOR) as per the T114 TRM (sec 30.3.1).
		 *
		 * NOTE: We do this here, after the initial clock/pll start,
		 * because if we read the clk_div reg before the controller
		 * is running, we hang, and we need it for the new calc.
		 */
		int clk_div_stdfst_mode = readl(&i2c_bus->regs->clk_div) >> 16;
		debug("%s: CLK_DIV_STD_FAST_MODE setting = %d\n", __func__,
			clk_div_stdfst_mode);

		clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
			CLK_MULT_STD_FAST_MODE * (clk_div_stdfst_mode + 1) *
			i2c_bus->speed * 2);
	}

	/* Reset I2C controller. */
	i2c_reset_controller(i2c_bus);

	/* Configure I2C controller. */
	if (i2c_bus->is_dvc) {	/* only for DVC I2C */
		struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;

		setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK);
	}

	funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config);
}

static void send_packet_headers(
	struct i2c_bus *i2c_bus,
	struct i2c_trans_info *trans,
	u32 packet_id)
{
	u32 data;

	/* prepare header1: Header size = 0 Protocol = I2C, pktType = 0 */
	data = PROTOCOL_TYPE_I2C << PKT_HDR1_PROTOCOL_SHIFT;
	data |= packet_id << PKT_HDR1_PKT_ID_SHIFT;
	data |= i2c_bus->id << PKT_HDR1_CTLR_ID_SHIFT;
	writel(data, &i2c_bus->control->tx_fifo);
	debug("pkt header 1 sent (0x%x)\n", data);

	/* prepare header2 */
	data = (trans->num_bytes - 1) << PKT_HDR2_PAYLOAD_SIZE_SHIFT;
	writel(data, &i2c_bus->control->tx_fifo);
	debug("pkt header 2 sent (0x%x)\n", data);

	/* prepare IO specific header: configure the slave address */
	data = trans->address << PKT_HDR3_SLAVE_ADDR_SHIFT;

	/* Enable Read if it is not a write transaction */
	if (!(trans->flags & I2C_IS_WRITE))
		data |= PKT_HDR3_READ_MODE_MASK;

	if (trans->flags & I2C_USE_REPEATED_START) {
		data |= PKT_HDR3_REPEAT_START_MASK;
		debug("I2C%d: Set REPEAT_START in master xmit packet header\n",
		      i2c_bus->id);
	}

	/* Write I2C specific header */
	writel(data, &i2c_bus->control->tx_fifo);
	debug("pkt header 3 sent (0x%x)\n", data);
}

static int wait_for_tx_fifo_empty(struct i2c_control *control)
{
	u32 count;
	int timeout_us = I2C_TIMEOUT_USEC;

	while (timeout_us >= 0) {
		count = (readl(&control->fifo_status) & TX_FIFO_EMPTY_CNT_MASK)
				>> TX_FIFO_EMPTY_CNT_SHIFT;
		if (count == I2C_FIFO_DEPTH)
			return 1;
		udelay(10);
		timeout_us -= 10;
	}

	return 0;
}

static int wait_for_rx_fifo_notempty(struct i2c_control *control)
{
	u32 count;
	int timeout_us = I2C_TIMEOUT_USEC;

	while (timeout_us >= 0) {
		count = (readl(&control->fifo_status) & TX_FIFO_FULL_CNT_MASK)
				>> TX_FIFO_FULL_CNT_SHIFT;
		if (count)
			return 1;
		udelay(10);
		timeout_us -= 10;
	}

	return 0;
}

static int wait_for_transfer_complete(struct i2c_control *control)
{
	int int_status;
	int timeout_us = I2C_TIMEOUT_USEC;

	while (timeout_us >= 0) {
		int_status = readl(&control->int_status);
		if (int_status & I2C_INT_NO_ACK_MASK)
			return -int_status;
		if (int_status & I2C_INT_ARBITRATION_LOST_MASK)
			return -int_status;
		if (int_status & I2C_INT_XFER_COMPLETE_MASK)
			return 0;

		udelay(10);
		timeout_us -= 10;
	}

	return -1;
}

static int send_recv_packets(struct i2c_bus *i2c_bus,
			     struct i2c_trans_info *trans)
{
	struct i2c_control *control = i2c_bus->control;
	u32 int_status;
	u32 words;
	u8 *dptr;
	u32 local;
	uchar last_bytes;
	int error = 0;
	int is_write = trans->flags & I2C_IS_WRITE;

	/* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */
	int_status = readl(&control->int_status);
	writel(int_status, &control->int_status);

	send_packet_headers(i2c_bus, trans, 1);

	words = DIV_ROUND_UP(trans->num_bytes, 4);
	last_bytes = trans->num_bytes & 3;
	dptr = trans->buf;

	while (words) {
		u32 *wptr = (u32 *)dptr;

		if (is_write) {
			/* deal with word alignment */
			if ((unsigned)dptr & 3) {
				memcpy(&local, dptr, sizeof(u32));
				writel(local, &control->tx_fifo);
				debug("pkt data sent (0x%x)\n", local);
			} else {
				writel(*wptr, &control->tx_fifo);
				debug("pkt data sent (0x%x)\n", *wptr);
			}
			if (!wait_for_tx_fifo_empty(control)) {
				error = -1;
				goto exit;
			}
		} else {
			if (!wait_for_rx_fifo_notempty(control)) {
				error = -1;
				goto exit;
			}
			/*
			 * for the last word, we read into our local buffer,
			 * in case that caller did not provide enough buffer.
			 */
			local = readl(&control->rx_fifo);
			if ((words == 1) && last_bytes)
				memcpy(dptr, (char *)&local, last_bytes);
			else if ((unsigned)dptr & 3)
				memcpy(dptr, &local, sizeof(u32));
			else
				*wptr = local;
			debug("pkt data received (0x%x)\n", local);
		}
		words--;
		dptr += sizeof(u32);
	}

	if (wait_for_transfer_complete(control)) {
		error = -1;
		goto exit;
	}
	return 0;
exit:
	/* error, reset the controller. */
	i2c_reset_controller(i2c_bus);

	return error;
}

static int tegra_i2c_write_data(u32 addr, u8 *data, u32 len, u32 flags)
{
	int error;
	struct i2c_trans_info trans_info;

	trans_info.address = addr;
	trans_info.buf = data;
	trans_info.flags = I2C_IS_WRITE | flags;
	trans_info.num_bytes = len;
	trans_info.is_10bit_address = 0;

	error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info);
	if (error)
		debug("tegra_i2c_write_data: Error (%d) !!!\n", error);

	return error;
}

static int tegra_i2c_read_data(u32 addr, u8 *data, u32 len, u32 flags)
{
	int error;
	struct i2c_trans_info trans_info;

	trans_info.address = addr | 1;
	trans_info.buf = data;
	trans_info.flags = flags;
	trans_info.num_bytes = len;
	trans_info.is_10bit_address = 0;

	error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info);
	if (error)
		debug("tegra_i2c_read_data: Error (%d) !!!\n", error);

	return error;
}

#ifndef CONFIG_OF_CONTROL
#error "Please enable device tree support to use this driver"
#endif

unsigned int i2c_get_bus_speed(void)
{
	return i2c_controllers[i2c_bus_num].speed;
}

int i2c_set_bus_speed(unsigned int speed)
{
	struct i2c_bus *i2c_bus;

	i2c_bus = &i2c_controllers[i2c_bus_num];
	i2c_bus->speed = speed;
	i2c_init_controller(i2c_bus);

	return 0;
}

static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
{
	i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");

	/*
	 * We don't have a binding for pinmux yet. Leave it out for now. So
	 * far no one needs anything other than the default.
	 */
	i2c_bus->pinmux_config = FUNCMUX_DEFAULT;
	i2c_bus->speed = fdtdec_get_int(blob, node, "clock-frequency", 0);
	i2c_bus->periph_id = clock_decode_periph_id(blob, node);
	i2c_bus->no_repeat_start = fdtdec_get_bool(blob, node,
						   "nvidia,no-repeat-start");

	/*
	 * We can't specify the pinmux config in the fdt, so I2C2 will not
	 * work on Seaboard. It normally has no devices on it anyway.
	 * You could add in this little hack if you need to use it.
	 * The correct solution is a pinmux binding in the fdt.
	 *
	 *	if (i2c_bus->periph_id == PERIPH_ID_I2C2)
	 *		i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA;
	 */
	if (i2c_bus->periph_id == -1)
		return -FDT_ERR_NOTFOUND;

	return 0;
}

/*
 * Process a list of nodes, adding them to our list of I2C ports.
 *
 * @param blob		fdt blob
 * @param node_list	list of nodes to process (any <=0 are ignored)
 * @param count		number of nodes to process
 * @param is_dvc	1 if these are DVC ports, 0 if standard I2C
 * @param is_scs	1 if this HW uses a single clock source (T114+)
 * @return 0 if ok, -1 on error
 */
static int process_nodes(const void *blob, int node_list[], int count,
			 int is_dvc, int is_scs)
{
	struct i2c_bus *i2c_bus;
	int i;

	/* build the i2c_controllers[] for each controller */
	for (i = 0; i < count; i++) {
		int node = node_list[i];

		if (node <= 0)
			continue;

		i2c_bus = &i2c_controllers[i];
		i2c_bus->id = i;
		i2c_bus->node = node;

		if (i2c_get_config(blob, node, i2c_bus)) {
			printf("i2c_init_board: failed to decode bus %d\n", i);
			return -1;
		}

		i2c_bus->is_scs = is_scs;

		i2c_bus->is_dvc = is_dvc;
		if (is_dvc) {
			i2c_bus->control =
				&((struct dvc_ctlr *)i2c_bus->regs)->control;
		} else {
			i2c_bus->control = &i2c_bus->regs->control;
		}
		debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
		      is_dvc ? "dvc" : "i2c", i, i2c_bus->regs,
		      i2c_bus->periph_id, i2c_bus->speed);
		i2c_init_controller(i2c_bus);
		debug("ok\n");
		i2c_bus->inited = 1;

		/* Mark position as used */
		node_list[i] = -1;
	}

	return 0;
}

/* Sadly there is no error return from this function */
void i2c_init_board(void)
{
	int node_list[TEGRA_I2C_NUM_CONTROLLERS];
	const void *blob = gd->fdt_blob;
	int count;

	/* First check for newer (T114+) I2C ports */
	count = fdtdec_find_aliases_for_id(blob, "i2c",
			COMPAT_NVIDIA_TEGRA114_I2C, node_list,
			TEGRA_I2C_NUM_CONTROLLERS);
	if (process_nodes(blob, node_list, count, 0, 1))
		return;

	/* Now get the older (T20/T30) normal I2C ports */
	count = fdtdec_find_aliases_for_id(blob, "i2c",
			COMPAT_NVIDIA_TEGRA20_I2C, node_list,
			TEGRA_I2C_NUM_CONTROLLERS);
	if (process_nodes(blob, node_list, count, 0, 0))
		return;

	/* Now look for dvc ports */
	count = fdtdec_add_aliases_for_id(blob, "i2c",
			COMPAT_NVIDIA_TEGRA20_DVC, node_list,
			TEGRA_I2C_NUM_CONTROLLERS);
	if (process_nodes(blob, node_list, count, 1, 0))
		return;
}

void i2c_init(int speed, int slaveaddr)
{
	/* This will override the speed selected in the fdt for that port */
	debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
	i2c_set_bus_speed(speed);
}

/* i2c write version without the register address */
int i2c_write_data(uchar chip, uchar *buffer, int len, u32 flags)
{
	int rc;

	debug("i2c_write_data: chip=0x%x, len=0x%x\n", chip, len);
	debug("write_data: ");
	/* use rc for counter */
	for (rc = 0; rc < len; ++rc)
		debug(" 0x%02x", buffer[rc]);
	debug("\n");

	/* Shift 7-bit address over for lower-level i2c functions */
	rc = tegra_i2c_write_data(chip << 1, buffer, len, flags);
	if (rc)
		debug("i2c_write_data(): rc=%d\n", rc);

	return rc;
}

/* i2c read version without the register address */
int i2c_read_data(uchar chip, uchar *buffer, int len, u32 flags)
{
	int rc;

	debug("inside i2c_read_data():\n");
	/* Shift 7-bit address over for lower-level i2c functions */
	rc = tegra_i2c_read_data(chip << 1, buffer, len, flags);
	if (rc) {
		debug("i2c_read_data(): rc=%d\n", rc);
		return rc;
	}

	debug("i2c_read_data: ");
	/* reuse rc for counter*/
	for (rc = 0; rc < len; ++rc)
		debug(" 0x%02x", buffer[rc]);
	debug("\n");

	return 0;
}

/* Probe to see if a chip is present. */
int i2c_probe(uchar chip)
{
	int rc;
	uchar reg;

	debug("i2c_probe: addr=0x%x\n", chip);
	reg = 0;
	rc = i2c_write_data(chip, &reg, 1, 0);
	if (rc) {
		debug("Error probing 0x%x.\n", chip);
		return 1;
	}
	return 0;
}

static int i2c_addr_ok(const uint addr, const int alen)
{
	/* We support 7 or 10 bit addresses, so one or two bytes each */
	return alen == 1 || alen == 2;
}

/**
 * i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
 *
 * Read "len" number of bytes from register "addr" of i2c device whose address
 * is "chip".
 *
 * This routine reads multiple bytes from the same register "addr". It can be
 * used to read data from i2c devices that have multi-bytes wide register (e.g.,
 * ALC5640 codec has 16-bit data per register address). Or, it can be used to
 * read from a FIFO register.
 *
 * Some i2c devices will auto-increment the register "addr" internally for each
 * byte read. Some i2c devices do not auto-increment the "addr" internally for
 * multi-bytes read. For these kind of i2c devices, the caller has to call this
 * routine one byte a time.
 *
 * @param chip		address of i2c device to read data from
 * @param addr		address of register inside the i2c device
 * @param alen		# of bytes of "addr" field, must be <= 2
 *			if alen == 0, no "addr" is output to the I2C bus
 * @param buffer	data pointer to store the read data in
 * @param len		# of bytes to read from the i2c device
 */
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
	int i;
	uchar data[alen];
	u32 flags;

	debug("%s: chip=0x%x, addr=0x%x, alen=%d, len=0x%x\n", __func__, chip,
	      addr, alen, len);

	if (alen != 0) {
		if (!i2c_addr_ok(addr, alen)) {
			debug("%s: Bad addr %x.%d.\n", __func__, addr, alen);
			return 1;
		}

		for (i = 0; i < alen; i++)
			data[alen - i - 1] = addr >> (8 * i);

		if (i2c_controllers[i2c_bus_num].no_repeat_start)
			flags = 0;
		else
			flags = I2C_USE_REPEATED_START;

		/*
		 * Write the 'addr' to I2C bus.
		 *
		 * Depending on the flags, after the  writing 'addr' phase, the
		 * I2C bus will either be put in REPEATED_START state or STOP
		 * state.
		 *
		 * Normally the I2C bus should be in REPEATED_START state after
		 * 'addr' phase. But some devices requires the I2C bus be in
		 * STOP state after the 'addr' phase. For those devices, the
		 * 'no_repeat_start' flag has to be set. Since 'no_repeat_start'
		 * flag affects the whole I2C bus, all devices on that I2C bus
		 * should behave the same way.
		 */
		if (i2c_write_data(chip, data, alen, flags)) {
			debug("%s: error sending (%#x)\n", __func__, addr);
			return 1;
		}
	}

	/* note: alen==0 case comes here directly */
	if (i2c_read_data(chip, buffer, len, 0)) {
		debug("%s: error reading (0x%x.%d)\n", __func__, addr, alen);
		return 1;
	}

	return 0;
}

/* Write bytes to a single register at 'addr' */
/**
 * i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
 *
 * Write "len" number of bytes to register "addr" of i2c device whose address
 * is "chip".
 *
 * This routine writes multiple bytes to the same register "addr". It can be
 * used to write data to i2c devices that have multi-bytes wide register (e.g.,
 * ALC5640 codec has 16-bit data per register address). Or, it can be used to
 * write to a FIFO register.
 *
 * Some i2c devices will auto-increment the register "addr" internally for each
 * byte written. Some i2c devices do not auto-increment the "addr" internally
 * for multi-bytes write. For these kind of i2c devices, the caller has to call
 * this routine one byte a time.
 *
 * @param chip		address of i2c device to write data to
 * @param addr		address of register inside the i2c device
 * @param alen		# of bytes of "addr" field, must be <= 2
 *			if alen == 0, no "addr" is output to the I2C bus
 * @param buffer	data pointer to write the data from
 * @param len		# of bytes to write to the i2c device
 */
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
	int i;
	uchar data[alen + len];

	debug("%s: chip=0x%x, addr=0x%x, alen=%d, len=0x%x\n", __func__, chip,
	      addr, alen, len);

	if (alen != 0) {
		if (!i2c_addr_ok(addr, alen)) {
			debug("%s: Bad addr %x.%d.\n", __func__, addr, alen);
			return 1;
		}

		for (i = 0; i < alen; i++)
			data[alen - i - 1] = addr >> (8 * i);
	}

	/* note: alen==0 case comes here directly */
	memcpy(&data[alen], buffer, len);
	if (i2c_write_data(chip, data, alen + len, 0)) {
		debug("%s: error sending (0x%x.%d)\n", __func__, addr, alen);
		return 1;
	}

	return 0;
}

#if defined(CONFIG_I2C_MULTI_BUS)
/*
 * Functions for multiple I2C bus handling
 */
unsigned int i2c_get_bus_num(void)
{
	return i2c_bus_num;
}

int i2c_set_bus_num(unsigned int bus)
{
	if (bus >= TEGRA_I2C_NUM_CONTROLLERS || !i2c_controllers[bus].inited)
		return -1;
	i2c_bus_num = bus;

	return 0;
}
#endif

int tegra_i2c_get_dvc_bus_num(void)
{
	int i;

	for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; i++) {
		struct i2c_bus *bus = &i2c_controllers[i];

		if (bus->inited && bus->is_dvc)
			return i;
	}

	return -1;
}

#ifdef CONFIG_OF_CONTROL
int i2c_get_bus_num_fdt(int node)
{
	int i;

	debug("%s: node = %d\n", __func__, node);
	for (i = 0; i < TEGRA_I2C_NUM_CONTROLLERS; i++) {
		struct i2c_bus *bus = &i2c_controllers[i];
		debug("%s: i = %d, bus->node = %d\n", __func__, i, bus->node);
		if (bus->node == node)
			return i;
	}

	debug("%s: Can't find any matched I2C bus\n", __func__);
	return -1;
}
#endif
