/*
 * TI DaVinci (TMS320DM644x) I2C driver.
 *
 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
 *
 * --------------------------------------------------------
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <i2c.h>
#include <asm/arch/hardware.h>
#include <asm/arch/i2c_defs.h>

#define CHECK_NACK() \
	do {\
		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
			REG(I2C_CON) = 0;\
			return(1);\
		}\
	} while (0)


static int wait_for_bus(void)
{
	int	stat, timeout;

	REG(I2C_STAT) = 0xffff;

	for (timeout = 0; timeout < 10; timeout++) {
		if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) {
			REG(I2C_STAT) = 0xffff;
			return(0);
		}

		REG(I2C_STAT) = stat;
		udelay(50000);
	}

	REG(I2C_STAT) = 0xffff;
	return(1);
}


static int poll_i2c_irq(int mask)
{
	int	stat, timeout;

	for (timeout = 0; timeout < 10; timeout++) {
		udelay(1000);
		stat = REG(I2C_STAT);
		if (stat & mask) {
			return(stat);
		}
	}

	REG(I2C_STAT) = 0xffff;
	return(stat | I2C_TIMEOUT);
}


void flush_rx(void)
{
	while (1) {
		if (!(REG(I2C_STAT) & I2C_STAT_RRDY))
			break;

		REG(I2C_DRR);
		REG(I2C_STAT) = I2C_STAT_RRDY;
		udelay(1000);
	}
}


void i2c_init(int speed, int slaveadd)
{
	u_int32_t	div, psc;

	if (REG(I2C_CON) & I2C_CON_EN) {
		REG(I2C_CON) = 0;
		udelay (50000);
	}

	psc = 2;
	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;	/* SCLL + SCLH */
	REG(I2C_PSC) = psc;			/* 27MHz / (2 + 1) = 9MHz */
	REG(I2C_SCLL) = (div * 50) / 100;	/* 50% Duty */
	REG(I2C_SCLH) = div - REG(I2C_SCLL);

	REG(I2C_OA) = slaveadd;
	REG(I2C_CNT) = 0;

	/* Interrupts must be enabled or I2C module won't work */
	REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;

	/* Now enable I2C controller (get it out of reset) */
	REG(I2C_CON) = I2C_CON_EN;

	udelay(1000);
}

int i2c_set_bus_speed(unsigned int speed)
{
	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
	return 0;
}

int i2c_probe(u_int8_t chip)
{
	int	rc = 1;

	if (chip == REG(I2C_OA)) {
		return(rc);
	}

	REG(I2C_CON) = 0;
	if (wait_for_bus()) {return(1);}

	/* try to read one byte from current (or only) address */
	REG(I2C_CNT) = 1;
	REG(I2C_SA) = chip;
	REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP);
	udelay (50000);

	if (!(REG(I2C_STAT) & I2C_STAT_NACK)) {
		rc = 0;
		flush_rx();
		REG(I2C_STAT) = 0xffff;
	} else {
		REG(I2C_STAT) = 0xffff;
		REG(I2C_CON) |= I2C_CON_STP;
		udelay(20000);
		if (wait_for_bus()) {return(1);}
	}

	flush_rx();
	REG(I2C_STAT) = 0xffff;
	REG(I2C_CNT) = 0;
	return(rc);
}


int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
{
	u_int32_t	tmp;
	int		i;

	if ((alen < 0) || (alen > 2)) {
		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
		return(1);
	}

	if (wait_for_bus()) {return(1);}

	if (alen != 0) {
		/* Start address phase */
		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
		REG(I2C_CNT) = alen;
		REG(I2C_SA) = chip;
		REG(I2C_CON) = tmp;

		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);

		CHECK_NACK();

		switch (alen) {
			case 2:
				/* Send address MSByte */
				if (tmp & I2C_STAT_XRDY) {
					REG(I2C_DXR) = (addr >> 8) & 0xff;
				} else {
					REG(I2C_CON) = 0;
					return(1);
				}

				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);

				CHECK_NACK();
				/* No break, fall through */
			case 1:
				/* Send address LSByte */
				if (tmp & I2C_STAT_XRDY) {
					REG(I2C_DXR) = addr & 0xff;
				} else {
					REG(I2C_CON) = 0;
					return(1);
				}

				tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY);

				CHECK_NACK();

				if (!(tmp & I2C_STAT_ARDY)) {
					REG(I2C_CON) = 0;
					return(1);
				}
		}
	}

	/* Address phase is over, now read 'len' bytes and stop */
	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
	REG(I2C_CNT) = len & 0xffff;
	REG(I2C_SA) = chip;
	REG(I2C_CON) = tmp;

	for (i = 0; i < len; i++) {
		tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR);

		CHECK_NACK();

		if (tmp & I2C_STAT_RRDY) {
			buf[i] = REG(I2C_DRR);
		} else {
			REG(I2C_CON) = 0;
			return(1);
		}
	}

	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);

	CHECK_NACK();

	if (!(tmp & I2C_STAT_SCD)) {
		REG(I2C_CON) = 0;
		return(1);
	}

	flush_rx();
	REG(I2C_STAT) = 0xffff;
	REG(I2C_CNT) = 0;
	REG(I2C_CON) = 0;

	return(0);
}


int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
{
	u_int32_t	tmp;
	int		i;

	if ((alen < 0) || (alen > 2)) {
		printf("%s(): bogus address length %x\n", __FUNCTION__, alen);
		return(1);
	}
	if (len < 0) {
		printf("%s(): bogus length %x\n", __FUNCTION__, len);
		return(1);
	}

	if (wait_for_bus()) {return(1);}

	/* Start address phase */
	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP;
	REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen;
	REG(I2C_SA) = chip;
	REG(I2C_CON) = tmp;

	switch (alen) {
		case 2:
			/* Send address MSByte */
			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);

			CHECK_NACK();

			if (tmp & I2C_STAT_XRDY) {
				REG(I2C_DXR) = (addr >> 8) & 0xff;
			} else {
				REG(I2C_CON) = 0;
				return(1);
			}
			/* No break, fall through */
		case 1:
			/* Send address LSByte */
			tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);

			CHECK_NACK();

			if (tmp & I2C_STAT_XRDY) {
				REG(I2C_DXR) = addr & 0xff;
			} else {
				REG(I2C_CON) = 0;
				return(1);
			}
	}

	for (i = 0; i < len; i++) {
		tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);

		CHECK_NACK();

		if (tmp & I2C_STAT_XRDY) {
			REG(I2C_DXR) = buf[i];
		} else {
			return(1);
		}
	}

	tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK);

	CHECK_NACK();

	if (!(tmp & I2C_STAT_SCD)) {
		REG(I2C_CON) = 0;
		return(1);
	}

	flush_rx();
	REG(I2C_STAT) = 0xffff;
	REG(I2C_CNT) = 0;
	REG(I2C_CON) = 0;

	return(0);
}
