/*
 * i2c driver for Freescale mx31
 *
 * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
 *
 * 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>

#if defined(CONFIG_HARD_I2C)

#include <asm/arch/mx31.h>
#include <asm/arch/mx31-regs.h>

#define IADR	0x00
#define IFDR	0x04
#define I2CR	0x08
#define I2SR	0x0c
#define I2DR	0x10

#define I2CR_IEN	(1 << 7)
#define I2CR_IIEN	(1 << 6)
#define I2CR_MSTA	(1 << 5)
#define I2CR_MTX	(1 << 4)
#define I2CR_TX_NO_AK	(1 << 3)
#define I2CR_RSTA	(1 << 2)

#define I2SR_ICF	(1 << 7)
#define I2SR_IBB	(1 << 5)
#define I2SR_IIF	(1 << 1)
#define I2SR_RX_NO_AK	(1 << 0)

#ifdef CONFIG_SYS_I2C_MX31_PORT1
#define I2C_BASE	0x43f80000
#elif defined (CONFIG_SYS_I2C_MX31_PORT2)
#define I2C_BASE	0x43f98000
#elif defined (CONFIG_SYS_I2C_MX31_PORT3)
#define I2C_BASE	0x43f84000
#else
#error "define CONFIG_SYS_I2C_MX31_PORTx to use the mx31 I2C driver"
#endif

#ifdef DEBUG
#define DPRINTF(args...)  printf(args)
#else
#define DPRINTF(args...)
#endif

static u16 div[] = { 30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144,
	             160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960,
	             1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840};

void i2c_init(int speed, int unused)
{
	int freq = mx31_get_ipg_clk();
	int i;

	for (i = 0; i < 0x1f; i++)
		if (freq / div[i] <= speed)
			break;

	DPRINTF("%s: speed: %d\n",__FUNCTION__, speed);

	__REG16(I2C_BASE + I2CR) = 0; /* Reset module */
	__REG16(I2C_BASE + IFDR) = i;
	__REG16(I2C_BASE + I2CR) = I2CR_IEN;
	__REG16(I2C_BASE + I2SR) = 0;
}

static int wait_busy(void)
{
	int timeout = 10000;

	while (!(__REG16(I2C_BASE + I2SR) & I2SR_IIF) && --timeout)
		udelay(1);
	__REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */

	return timeout;
}

static int tx_byte(u8 byte)
{
	__REG16(I2C_BASE + I2DR) = byte;

	if (!wait_busy() || __REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK)
		return -1;
	return 0;
}

static int rx_byte(void)
{
	if (!wait_busy())
		return -1;

	return __REG16(I2C_BASE + I2DR);
}

int i2c_probe(uchar chip)
{
	int ret;

	__REG16(I2C_BASE + I2CR) = 0; /* Reset module */
	__REG16(I2C_BASE + I2CR) = I2CR_IEN;

	__REG16(I2C_BASE + I2CR) = I2CR_IEN |  I2CR_MSTA | I2CR_MTX;
	ret = tx_byte(chip << 1);
	__REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MTX;

	return ret;
}

static int i2c_addr(uchar chip, uint addr, int alen)
{
	__REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */
	__REG16(I2C_BASE + I2CR) = I2CR_IEN |  I2CR_MSTA | I2CR_MTX;

	if (tx_byte(chip << 1))
		return -1;

	while (alen--)
		if (tx_byte((addr >> (alen * 8)) & 0xff))
			return -1;
	return 0;
}

int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
{
	int timeout = 10000;
	int ret;

	DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",__FUNCTION__, chip, addr, alen, len);

	if (i2c_addr(chip, addr, alen)) {
		printf("i2c_addr failed\n");
		return -1;
	}

	__REG16(I2C_BASE + I2CR) = I2CR_IEN |  I2CR_MSTA | I2CR_MTX | I2CR_RSTA;

	if (tx_byte(chip << 1 | 1))
		return -1;

	__REG16(I2C_BASE + I2CR) = I2CR_IEN |  I2CR_MSTA | ((len == 1) ? I2CR_TX_NO_AK : 0);

	ret = __REG16(I2C_BASE + I2DR);

	while (len--) {
		if ((ret = rx_byte()) < 0)
			return -1;
		*buf++ = ret;
		if (len <= 1)
			__REG16(I2C_BASE + I2CR) = I2CR_IEN |  I2CR_MSTA | I2CR_TX_NO_AK;
	}

	wait_busy();

	__REG16(I2C_BASE + I2CR) = I2CR_IEN;

	while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout)
		udelay(1);

	return 0;
}

int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
{
	int timeout = 10000;
	DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",__FUNCTION__, chip, addr, alen, len);

	if (i2c_addr(chip, addr, alen))
		return -1;

	while (len--)
		if (tx_byte(*buf++))
			return -1;

	__REG16(I2C_BASE + I2CR) = I2CR_IEN;

	while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout)
		udelay(1);

	return 0;
}

#endif /* CONFIG_HARD_I2C */
