/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *  * Neither the name of The Linux Foundation, Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * QUP driver for Qualcomm MSM platforms
 *
 */

#include <debug.h>
#include <arch/arm.h>
#include <reg.h>
#include <kernel/thread.h>
#include <dev/gpio.h>
#include <stdlib.h>
#include <string.h>

#include <gsbi.h>
#include <i2c_qup.h>
#include <platform/irqs.h>
#include <platform/iomap.h>
#include <platform/gpio.h>
#include <platform/clock.h>
#include <platform/timer.h>
#include <platform/interrupts.h>

static struct qup_i2c_dev *dev_addr = NULL;

/* QUP Registers */
enum {
	QUP_CONFIG = 0x0,
	QUP_STATE = 0x4,
	QUP_IO_MODE = 0x8,
	QUP_SW_RESET = 0xC,
	QUP_OPERATIONAL = 0x18,
	QUP_ERROR_FLAGS = 0x1C,
	QUP_ERROR_FLAGS_EN = 0x20,
	QUP_MX_READ_CNT = 0x208,
	QUP_MX_INPUT_CNT = 0x200,
	QUP_MX_WR_CNT = 0x100,
	QUP_OUT_DEBUG = 0x108,
	QUP_OUT_FIFO_CNT = 0x10C,
	QUP_OUT_FIFO_BASE = 0x110,
	QUP_IN_READ_CUR = 0x20C,
	QUP_IN_DEBUG = 0x210,
	QUP_IN_FIFO_CNT = 0x214,
	QUP_IN_FIFO_BASE = 0x218,
	QUP_I2C_CLK_CTL = 0x400,
	QUP_I2C_STATUS = 0x404,
};

/* QUP States and reset values */
enum {
	QUP_RESET_STATE = 0,
	QUP_RUN_STATE = 1U,
	QUP_STATE_MASK = 3U,
	QUP_PAUSE_STATE = 3U,
	QUP_STATE_VALID = 1U << 2,
	QUP_I2C_MAST_GEN = 1U << 4,
	QUP_OPERATIONAL_RESET = 0xFF0,
	QUP_I2C_STATUS_RESET = 0xFFFFFC,
};

/* QUP OPERATIONAL FLAGS */
enum {
	QUP_OUT_SVC_FLAG = 1U << 8,
	QUP_IN_SVC_FLAG = 1U << 9,
	QUP_MX_INPUT_DONE = 1U << 11,
};

/* I2C mini core related values */
enum {
	I2C_MINI_CORE = 2U << 8,
	I2C_N_VAL = 0xF,

};

/* Packing Unpacking words in FIFOs , and IO modes*/
enum {
	QUP_WR_BLK_MODE = 1U << 10,
	QUP_RD_BLK_MODE = 1U << 12,
	QUP_UNPACK_EN = 1U << 14,
	QUP_PACK_EN = 1U << 15,
};

/* QUP tags */
enum {
	QUP_OUT_NOP = 0,
	QUP_OUT_START = 1U << 8,
	QUP_OUT_DATA = 2U << 8,
	QUP_OUT_STOP = 3U << 8,
	QUP_OUT_REC = 4U << 8,
	QUP_IN_DATA = 5U << 8,
	QUP_IN_STOP = 6U << 8,
	QUP_IN_NACK = 7U << 8,
};

/* Status, Error flags */
enum {
	I2C_STATUS_WR_BUFFER_FULL = 1U << 0,
	I2C_STATUS_BUS_ACTIVE = 1U << 8,
	I2C_STATUS_ERROR_MASK = 0x38000FC,
	QUP_I2C_NACK_FLAG = 1U << 3,
	QUP_IN_NOT_EMPTY = 1U << 5,
	QUP_STATUS_ERROR_FLAGS = 0x7C,
};

#ifdef DEBUG_QUP
static void qup_print_status(struct qup_i2c_dev *dev)
{
	unsigned val;
	val = readl(dev->qup_base + QUP_CONFIG);
	dprintf(INFO, "Qup config is :0x%x\n", val);
	val = readl(dev->qup_base + QUP_STATE);
	dprintf(INFO, "Qup state is :0x%x\n", val);
	val = readl(dev->qup_base + QUP_IO_MODE);
	dprintf(INFO, "Qup mode is :0x%x\n", val);
}
#else
static inline void qup_print_status(struct qup_i2c_dev *dev)
{
}
#endif

static irqreturn_t qup_i2c_interrupt(void)
{
	struct qup_i2c_dev *dev = dev_addr;
	if (!dev) {
		dprintf(CRITICAL,
			"dev_addr is NULL, that means i2c_qup_init failed...\n");
		return IRQ_FAIL;
	}
	unsigned status = readl(dev->qup_base + QUP_I2C_STATUS);
	unsigned status1 = readl(dev->qup_base + QUP_ERROR_FLAGS);
	unsigned op_flgs = readl(dev->qup_base + QUP_OPERATIONAL);
	int err = 0;

	if (!dev->msg)
		return IRQ_HANDLED;

	if (status & I2C_STATUS_ERROR_MASK) {
		dprintf(CRITICAL, "QUP: I2C status flags :0x%x \n", status);
		err = -status;
		/* Clear Error interrupt if it's a level triggered interrupt */
		if (dev->num_irqs == 1) {
			writel(QUP_RESET_STATE, dev->qup_base + QUP_STATE);
		}
		goto intr_done;
	}

	if (status1 & 0x7F) {
		dprintf(CRITICAL, "QUP: QUP status flags :0x%x\n", status1);
		err = -status1;
		/* Clear Error interrupt if it's a level triggered interrupt */
		if (dev->num_irqs == 1)
			writel((status1 & QUP_STATUS_ERROR_FLAGS),
			       dev->qup_base + QUP_ERROR_FLAGS);
		goto intr_done;
	}

	if (op_flgs & QUP_OUT_SVC_FLAG)
		writel(QUP_OUT_SVC_FLAG, dev->qup_base + QUP_OPERATIONAL);
	if (dev->msg->flags == I2C_M_RD) {
		if ((op_flgs & QUP_MX_INPUT_DONE)
		    || (op_flgs & QUP_IN_SVC_FLAG))
			writel(QUP_IN_SVC_FLAG,
			       dev->qup_base + QUP_OPERATIONAL);
		else
			return IRQ_HANDLED;
	}

 intr_done:
	dev->err = err;
	return IRQ_HANDLED;
}

static int qup_i2c_poll_writeready(struct qup_i2c_dev *dev)
{
	unsigned retries = 0;

	while (retries != 2000) {
		unsigned status = readl(dev->qup_base + QUP_I2C_STATUS);

		if (!(status & I2C_STATUS_WR_BUFFER_FULL)) {
			if (!(status & I2C_STATUS_BUS_ACTIVE))
				return 0;
			else	/* 1-bit delay before we check for bus busy */
				udelay(dev->one_bit_t);
		}
		if (retries++ == 1000)
			udelay(100);
	}
	qup_print_status(dev);
	return -ETIMEDOUT;
}

static int qup_i2c_poll_state(struct qup_i2c_dev *dev, unsigned state)
{
	unsigned retries = 0;

	dprintf(INFO, "Polling Status for state:0x%x\n", state);

	while (retries != 2000) {
		unsigned status = readl(dev->qup_base + QUP_STATE);

		if ((status & (QUP_STATE_VALID | state)) ==
		    (QUP_STATE_VALID | state))
			return 0;
		else if (retries++ == 1000)
			udelay(100);
	}
	return -ETIMEDOUT;
}

#ifdef DEBUG
static void
qup_verify_fifo(struct qup_i2c_dev *dev, unsigned val, unsigned addr, int rdwr)
{
	if (rdwr)
		dprintf(INFO, "RD:Wrote 0x%x to out_ff:0x%x\n", val, addr);
	else
		dprintf(INFO, "WR:Wrote 0x%x to out_ff:0x%x\n", val, addr);
}
#else
static inline void
qup_verify_fifo(struct qup_i2c_dev *dev, unsigned val, unsigned addr, int rdwr)
{
}
#endif

static void
qup_issue_read(struct qup_i2c_dev *dev, struct i2c_msg *msg, int *idx,
	       unsigned carry_over)
{
	uint16_t addr = (msg->addr << 1) | 1;
	/* QUP limit 256 bytes per read. By HW design, 0 in the 8-bit field is
	   treated as 256 byte read. */
	uint16_t rd_len = ((dev->cnt == 256) ? 0 : dev->cnt);

	if (*idx % 4) {
		writel(carry_over | ((QUP_OUT_START | addr) << 16),
		       dev->qup_base + QUP_OUT_FIFO_BASE);

		qup_verify_fifo(dev, carry_over |
				((QUP_OUT_START | addr) << 16),
				(unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
				(*idx - 2), 1);
		writel((QUP_OUT_REC | rd_len),
		       dev->qup_base + QUP_OUT_FIFO_BASE);

		qup_verify_fifo(dev, (QUP_OUT_REC | rd_len),
				(unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
				(*idx + 2), 1);
	} else {
		writel(((QUP_OUT_REC | rd_len) << 16) |
		       QUP_OUT_START | addr, dev->qup_base + QUP_OUT_FIFO_BASE);

		qup_verify_fifo(dev, QUP_OUT_REC << 16 | rd_len << 16 |
				QUP_OUT_START | addr,
				(unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
				(*idx), 1);
	}
	*idx += 4;
}

static void
qup_issue_write(struct qup_i2c_dev *dev, struct i2c_msg *msg, int rem,
		int *idx, unsigned *carry_over)
{
	int entries = dev->cnt;
	int empty_sl = dev->wr_sz - ((*idx) >> 1);
	int i = 0;
	unsigned val = 0;
	unsigned last_entry = 0;
	uint16_t addr = msg->addr << 1;

	if (dev->pos == 0) {
		if (*idx % 4) {
			writel(*carry_over | ((QUP_OUT_START | addr) << 16),
			       dev->qup_base + QUP_OUT_FIFO_BASE);

			qup_verify_fifo(dev, *carry_over | QUP_OUT_DATA << 16 |
					addr << 16, (unsigned)dev->qup_base +
					QUP_OUT_FIFO_BASE + (*idx) - 2, 0);
		} else
			val = QUP_OUT_START | addr;
		*idx += 2;
		i++;
		entries++;
	} else {
		/* Avoid setp time issue by adding 1 NOP when number of bytes are more
		   than FIFO/BLOCK size. setup time issue can't appear otherwise since
		   next byte to be written will always be ready */
		val = (QUP_OUT_NOP | 1);
		*idx += 2;
		i++;
		entries++;
	}
	if (entries > empty_sl)
		entries = empty_sl;

	for (; i < (entries - 1); i++) {
		if (*idx % 4) {
			writel(val | ((QUP_OUT_DATA |
				       msg->buf[dev->pos]) << 16),
			       dev->qup_base + QUP_OUT_FIFO_BASE);

			qup_verify_fifo(dev, val | QUP_OUT_DATA << 16 |
					msg->buf[dev->pos] << 16,
					(unsigned)dev->qup_base +
					QUP_OUT_FIFO_BASE + (*idx) - 2, 0);
		} else
			val = QUP_OUT_DATA | msg->buf[dev->pos];
		(*idx) += 2;
		dev->pos++;
	}
	if (dev->pos < (msg->len - 1))
		last_entry = QUP_OUT_DATA;
	else if (rem > 1)	/* not last array entry */
		last_entry = QUP_OUT_DATA;
	else
		last_entry = QUP_OUT_STOP;
	if ((*idx % 4) == 0) {
		/*
		 * If read-start and read-command end up in different fifos, it
		 * may result in extra-byte being read due to extra-read cycle.
		 * Avoid that by inserting NOP as the last entry of fifo only
		 * if write command(s) leave 1 space in fifo.
		 */
		if (rem > 1) {
			struct i2c_msg *next = msg + 1;
			if (next->addr == msg->addr && (next->flags & I2C_M_RD)
			    && *idx == ((dev->wr_sz * 2) - 4)) {
				writel(((last_entry | msg->buf[dev->pos]) |
					((1 | QUP_OUT_NOP) << 16)),
				       dev->qup_base + QUP_OUT_FIFO_BASE);
				*idx += 2;
			} else
				*carry_over = (last_entry | msg->buf[dev->pos]);
		} else {
			writel((last_entry | msg->buf[dev->pos]),
			       dev->qup_base + QUP_OUT_FIFO_BASE);

			qup_verify_fifo(dev, last_entry | msg->buf[dev->pos],
					(unsigned)dev->qup_base +
					QUP_OUT_FIFO_BASE + (*idx), 0);
		}
	} else {
		writel(val | ((last_entry | msg->buf[dev->pos]) << 16),
		       dev->qup_base + QUP_OUT_FIFO_BASE);

		qup_verify_fifo(dev, val | (last_entry << 16) |
				(msg->buf[dev->pos] << 16),
				(unsigned)dev->qup_base + QUP_OUT_FIFO_BASE +
				(*idx) - 2, 0);
	}

	*idx += 2;
	dev->pos++;
	dev->cnt = msg->len - dev->pos;
}

static int qup_update_state(struct qup_i2c_dev *dev, unsigned state)
{
	if (qup_i2c_poll_state(dev, 0) != 0)
		return -EIO;
	writel(state, dev->qup_base + QUP_STATE);
	if (qup_i2c_poll_state(dev, state) != 0)
		return -EIO;
	return 0;
}

static int qup_set_read_mode(struct qup_i2c_dev *dev, int rd_len)
{
	unsigned wr_mode =
	    (dev->wr_sz < dev->out_fifo_sz) ? QUP_WR_BLK_MODE : 0;
	if (rd_len > 256) {
		dprintf(INFO, "HW doesn't support READs > 256 bytes\n");
		return -EPROTONOSUPPORT;
	}
	if (rd_len <= dev->in_fifo_sz) {
		writel(wr_mode | QUP_PACK_EN | QUP_UNPACK_EN,
		       dev->qup_base + QUP_IO_MODE);
		writel(rd_len, dev->qup_base + QUP_MX_READ_CNT);
	} else {
		writel(wr_mode | QUP_RD_BLK_MODE |
		       QUP_PACK_EN | QUP_UNPACK_EN,
		       dev->qup_base + QUP_IO_MODE);
		writel(rd_len, dev->qup_base + QUP_MX_INPUT_CNT);
	}
	return 0;
}

static int qup_set_wr_mode(struct qup_i2c_dev *dev, int rem)
{
	int total_len = 0;
	int ret = 0;
	if (dev->msg->len >= (dev->out_fifo_sz - 1)) {
		total_len =
		    dev->msg->len + 1 + (dev->msg->len / (dev->out_blk_sz - 1));
		writel(QUP_WR_BLK_MODE | QUP_PACK_EN | QUP_UNPACK_EN,
		       dev->qup_base + QUP_IO_MODE);
		dev->wr_sz = dev->out_blk_sz;
	} else
		writel(QUP_PACK_EN | QUP_UNPACK_EN,
		       dev->qup_base + QUP_IO_MODE);

	if (rem > 1) {
		struct i2c_msg *next = dev->msg + 1;
		if (next->addr == dev->msg->addr && next->flags == I2C_M_RD) {
			ret = qup_set_read_mode(dev, next->len);
			/* make sure read start & read command are in 1 blk */
			if ((total_len % dev->out_blk_sz) ==
			    (dev->out_blk_sz - 1))
				total_len += 3;
			else
				total_len += 2;
		}
	}
	/* WRITE COUNT register valid/used only in block mode */
	if (dev->wr_sz == dev->out_blk_sz)
		writel(total_len, dev->qup_base + QUP_MX_WR_CNT);
	return ret;
}

int qup_i2c_xfer(struct qup_i2c_dev *dev, struct i2c_msg msgs[], int num)
{
	int ret;
	int rem = num;
	int err;

	if (dev->suspended) {
		return -EIO;
	}

	/* Set the GSBIn_QUP_APPS_CLK to 24MHz, then below figure out what speed to
	   run I2C_MASTER_CORE at. */
#if !PERIPH_BLK_BLSP
	if (dev->clk_state == 0) {
		if (dev->clk_ctl == 0) {
			clock_config_i2c(dev->gsbi_number, dev->src_clk_freq);
		}
	}
#endif

	/* Initialize QUP registers during first transfer */
	if (dev->clk_ctl == 0) {
		int fs_div;
		int hs_div;
		unsigned fifo_reg;
#if !PERIPH_BLK_BLSP
		/* Configure the GSBI Protocol Code for i2c */
		writel((GSBI_PROTOCOL_CODE_I2C <<
			GSBI_CTRL_REG_PROTOCOL_CODE_S),
		       GSBI_CTRL_REG(dev->gsbi_base));
#endif

		fs_div = ((dev->src_clk_freq / dev->clk_freq) / 2) - 3;
		hs_div = 3;
		dev->clk_ctl = ((hs_div & 0x7) << 8) | (fs_div & 0xff);
		fifo_reg = readl(dev->qup_base + QUP_IO_MODE);
		if (fifo_reg & 0x3)
			dev->out_blk_sz = (fifo_reg & 0x3) * 16;
		else
			dev->out_blk_sz = 16;
		if (fifo_reg & 0x60)
			dev->in_blk_sz = ((fifo_reg & 0x60) >> 5) * 16;
		else
			dev->in_blk_sz = 16;
		/*
		 * The block/fifo size w.r.t. 'actual data' is 1/2 due to 'tag'
		 * associated with each byte written/received
		 */
		dev->out_blk_sz /= 2;
		dev->in_blk_sz /= 2;
		dev->out_fifo_sz =
		    dev->out_blk_sz * (2 << ((fifo_reg & 0x1C) >> 2));
		dev->in_fifo_sz =
		    dev->in_blk_sz * (2 << ((fifo_reg & 0x380) >> 7));
		dprintf(INFO, "QUP IN:bl:%d, ff:%d, OUT:bl:%d, ff:%d\n",
			dev->in_blk_sz, dev->in_fifo_sz, dev->out_blk_sz,
			dev->out_fifo_sz);
	}

	unmask_interrupt(dev->qup_irq);
	writel(1, dev->qup_base + QUP_SW_RESET);
	ret = qup_i2c_poll_state(dev, QUP_RESET_STATE);
	if (ret) {
		dprintf(INFO, "QUP Busy:Trying to recover\n");
		goto out_err;
	}

	/* Initialize QUP registers */
	writel(0, dev->qup_base + QUP_CONFIG);
	writel(QUP_OPERATIONAL_RESET, dev->qup_base + QUP_OPERATIONAL);
	writel(QUP_STATUS_ERROR_FLAGS, dev->qup_base + QUP_ERROR_FLAGS_EN);

	writel(I2C_MINI_CORE | I2C_N_VAL, dev->qup_base + QUP_CONFIG);

	/* Initialize I2C mini core registers */
	writel(0, dev->qup_base + QUP_I2C_CLK_CTL);
	writel(QUP_I2C_STATUS_RESET, dev->qup_base + QUP_I2C_STATUS);

	dev->cnt = msgs->len;
	dev->pos = 0;
	dev->msg = msgs;
	while (rem) {
		int filled = FALSE;

		dev->wr_sz = dev->out_fifo_sz;
		dev->err = 0;

		if (qup_i2c_poll_state(dev, QUP_I2C_MAST_GEN) != 0) {
			ret = -EIO;
			goto out_err;
		}

		qup_print_status(dev);
		/* HW limits Read upto 256 bytes in 1 read without stop */
		if (dev->msg->flags & I2C_M_RD) {
			ret = qup_set_read_mode(dev, dev->cnt);
			if (ret != 0)
				goto out_err;
		} else {
			ret = qup_set_wr_mode(dev, rem);
			if (ret != 0)
				goto out_err;
			/* Don't fill block till we get interrupt */
			if (dev->wr_sz == dev->out_blk_sz)
				filled = TRUE;
		}

		err = qup_update_state(dev, QUP_RUN_STATE);
		if (err < 0) {
			ret = err;
			goto out_err;
		}

		qup_print_status(dev);
		writel(dev->clk_ctl, dev->qup_base + QUP_I2C_CLK_CTL);

		do {
			int idx = 0;
			unsigned carry_over = 0;

			/* Transition to PAUSE state only possible from RUN */
			err = qup_update_state(dev, QUP_PAUSE_STATE);
			if (err < 0) {
				ret = err;
				goto out_err;
			}

			qup_print_status(dev);
			/* This operation is Write, check the next operation and decide
			   mode */
			while (filled == FALSE) {
				if ((msgs->flags & I2C_M_RD)
				    && (dev->cnt == msgs->len))
					qup_issue_read(dev, msgs, &idx,
						       carry_over);
				else if (!(msgs->flags & I2C_M_RD))
					qup_issue_write(dev, msgs, rem, &idx,
							&carry_over);
				if (idx >= (dev->wr_sz << 1))
					filled = TRUE;
				/* Start new message */
				if (filled == FALSE) {
					if (msgs->flags & I2C_M_RD)
						filled = TRUE;
					else if (rem > 1) {
						/* Only combine operations with same address */
						struct i2c_msg *next = msgs + 1;
						if (next->addr != msgs->addr
						    || next->flags == 0)
							filled = TRUE;
						else {
							rem--;
							msgs++;
							dev->msg = msgs;
							dev->pos = 0;
							dev->cnt = msgs->len;
						}
					} else
						filled = TRUE;
				}
			}
			err = qup_update_state(dev, QUP_RUN_STATE);
			if (err < 0) {
				ret = err;
				goto out_err;
			}
			dprintf(INFO, "idx:%d, rem:%d, num:%d, mode:%d\n",
				idx, rem, num, dev->mode);

			qup_print_status(dev);
			if (dev->err) {
				if (dev->err & QUP_I2C_NACK_FLAG) {
					dprintf(CRITICAL,
						"I2C slave addr:0x%x not connected\n",
						dev->msg->addr);
				} else {
					dprintf(INFO,
						"QUP data xfer error %d\n",
						dev->err);
				}
				ret = dev->err;
				goto out_err;
			}
			if (dev->msg->flags & I2C_M_RD) {
				int i;
				unsigned dval = 0;
				for (i = 0; dev->pos < dev->msg->len;
				     i++, dev->pos++) {
					unsigned rd_status =
					    readl(dev->qup_base +
						  QUP_OPERATIONAL);
					if (i % 2 == 0) {
						if ((rd_status &
						     QUP_IN_NOT_EMPTY) == 0)
							break;
						dval =
						    readl(dev->qup_base +
							  QUP_IN_FIFO_BASE);
						dev->msg->buf[dev->pos] =
						    dval & 0xFF;
					} else
						dev->msg->buf[dev->pos] =
						    ((dval & 0xFF0000) >> 16);
				}
				dev->cnt -= i;
			} else
				filled = FALSE;	/* refill output FIFO */
		}
		while (dev->cnt > 0);
		if (dev->cnt == 0) {
			rem--;
			msgs++;
			if (rem) {
				dev->pos = 0;
				dev->cnt = msgs->len;
				dev->msg = msgs;
			}
		}
		/* Wait for I2C bus to be idle */
		ret = qup_i2c_poll_writeready(dev);
		if (ret) {
			dprintf(INFO, "Error waiting for write ready\n");
			goto out_err;
		}
	}

	ret = num;
 out_err:
	dev->msg = NULL;
	dev->pos = 0;
	dev->err = 0;
	dev->cnt = 0;
	mask_interrupt(dev->qup_irq);
	return ret;
}

void qup_i2c_sec_init(struct qup_i2c_dev *dev, uint32_t clk_freq,
					  uint32_t src_clk_freq)
{
	/* Set clk_freq and src_clk_freq for i2c. */
	dev->clk_freq = clk_freq;
	dev->src_clk_freq = src_clk_freq;

	dev->num_irqs = 1;

	dev->one_bit_t = USEC_PER_SEC / dev->clk_freq;
	dev->clk_ctl = 0;

	/* Register the GSBIn QUP IRQ */
	register_int_handler(dev->qup_irq, (int_handler) qup_i2c_interrupt, 0);

	/* Then disable it */
	mask_interrupt(dev->qup_irq);
}

struct qup_i2c_dev *qup_i2c_init(uint8_t gsbi_id, unsigned clk_freq,
				 unsigned src_clk_freq)
{
	struct qup_i2c_dev *dev;
	if (dev_addr != NULL) {
		return dev_addr;
	}

	dev = malloc(sizeof(struct qup_i2c_dev));
	if (!dev) {
		return NULL;
	}
	dev = memset(dev, 0, sizeof(struct qup_i2c_dev));

	/*
	 * Platform uses gsbi, setup base addresses and
	 * irq based on gsbi_id
	 */
	dev->qup_irq = GSBI_QUP_IRQ(gsbi_id);
	dev->qup_base = QUP_BASE(gsbi_id);
	dev->gsbi_base = GSBI_BASE(gsbi_id);
	dev->gsbi_number = gsbi_id;

	/* This must be done for qup_i2c_interrupt to work. */
	dev_addr = dev;

	/* Initialize the GPIO for GSBIn as i2c */
	gpio_config_i2c(dev->gsbi_number);

	/* Configure the GSBI Protocol Code for i2c */
	writel((GSBI_PROTOCOL_CODE_I2C <<
		GSBI_CTRL_REG_PROTOCOL_CODE_S), GSBI_CTRL_REG(dev->gsbi_base));

	qup_i2c_sec_init(dev, clk_freq, src_clk_freq);

	return dev;
}

struct qup_i2c_dev *qup_blsp_i2c_init(uint8_t blsp_id, uint8_t qup_id,
									  uint32_t clk_freq, uint32_t src_clk_freq)
{
	struct qup_i2c_dev *dev;

	if (dev_addr != NULL) {
		return dev_addr;
	}

	dev = malloc(sizeof(struct qup_i2c_dev));
	if (!dev) {
		return NULL;
	}
	dev = memset(dev, 0, sizeof(struct qup_i2c_dev));

	/* Platform uses BLSP */
	dev->qup_irq = BLSP_QUP_IRQ(blsp_id, qup_id);
	dev->qup_base = BLSP_QUP_BASE(blsp_id, qup_id);

	/* This must be done for qup_i2c_interrupt to work. */
	dev_addr = dev;

	/* Initialize the GPIO for BLSP i2c */
	gpio_config_blsp_i2c(blsp_id, qup_id);

	clock_config_blsp_i2c(blsp_id, qup_id);

	qup_i2c_sec_init(dev, clk_freq, src_clk_freq);

	return dev;
}

int qup_i2c_deinit(struct qup_i2c_dev *dev)
{
	/* Disable the qup_irq */
	mask_interrupt(dev->qup_irq);
	/* Free the memory used for dev */
	free(dev);
	return 0;
}
