/*
 * LPC32xx I2C interface driver
 *
 * (C) Copyright 2014  DENX Software Engineering GmbH
 * Written-by: Albert ARIBAUD - 3ADEV <albert.aribaud@3adev.fr>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/io.h>
#include <i2c.h>
#include <asm/errno.h>
#include <asm/arch/clk.h>

/*
 * Provide default speed and slave if target did not
 */

#if !defined(CONFIG_SYS_I2C_LPC32XX_SPEED)
#define CONFIG_SYS_I2C_LPC32XX_SPEED 350000
#endif

#if !defined(CONFIG_SYS_I2C_LPC32XX_SLAVE)
#define CONFIG_SYS_I2C_LPC32XX_SLAVE 0
#endif

/* i2c register set */
struct lpc32xx_i2c_registers {
	union {
		u32 rx;
		u32 tx;
	};
	u32 stat;
	u32 ctrl;
	u32 clk_hi;
	u32 clk_lo;
	u32 adr;
	u32 rxfl;
	u32 txfl;
	u32 rxb;
	u32 txb;
	u32 stx;
	u32 stxfl;
};

/* TX register fields */
#define LPC32XX_I2C_TX_START		0x00000100
#define LPC32XX_I2C_TX_STOP		0x00000200

/* Control register values */
#define LPC32XX_I2C_SOFT_RESET		0x00000100

/* Status register values */
#define LPC32XX_I2C_STAT_TFF		0x00000400
#define LPC32XX_I2C_STAT_RFE		0x00000200
#define LPC32XX_I2C_STAT_DRMI		0x00000008
#define LPC32XX_I2C_STAT_NAI		0x00000004
#define LPC32XX_I2C_STAT_TDI		0x00000001

static struct lpc32xx_i2c_registers *lpc32xx_i2c[] = {
	(struct lpc32xx_i2c_registers *)I2C1_BASE,
	(struct lpc32xx_i2c_registers *)I2C2_BASE
};

/* Set I2C bus speed */
static unsigned int lpc32xx_i2c_set_bus_speed(struct i2c_adapter *adap,
			unsigned int speed)
{
	int half_period;

	if (speed == 0)
		return -EINVAL;

	half_period = (105000000 / speed) / 2;

	if ((half_period > 255) || (half_period < 0))
		return -EINVAL;

	writel(half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_hi);
	writel(half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_lo);
	return 0;
}

/* I2C init called by cmd_i2c when doing 'i2c reset'. */
static void _i2c_init(struct i2c_adapter *adap,
	int requested_speed, int slaveadd)
{
	struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];

	/* soft reset (auto-clears) */
	writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl);
	/* set HI and LO periods for about 350 kHz */
	lpc32xx_i2c_set_bus_speed(adap, requested_speed);
}

/* I2C probe called by cmd_i2c when doing 'i2c probe'. */
static int lpc32xx_i2c_probe(struct i2c_adapter *adap, u8 dev)
{
	struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];
	int stat;

	/* Soft-reset the controller */
	writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl);
	while (readl(&i2c->ctrl) & LPC32XX_I2C_SOFT_RESET)
		;
	/* Addre slave for write with start before and stop after */
	writel((dev<<1) | LPC32XX_I2C_TX_START | LPC32XX_I2C_TX_STOP,
	       &i2c->tx);
	/* wait for end of transation */
	while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI))
		;
	/* was there no acknowledge? */
	return (stat & LPC32XX_I2C_STAT_NAI) ? -1 : 0;
}

/*
 * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
 * Begin write, send address byte(s), begin read, receive data bytes, end.
 */
static int lpc32xx_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,
			 int alen, u8 *data, int length)
{
	struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];
	int stat, wlen;

	/* Soft-reset the controller */
	writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl);
	while (readl(&i2c->ctrl) & LPC32XX_I2C_SOFT_RESET)
		;
	/* do we need to write an address at all? */
	if (alen) {
		/* Address slave in write mode */
		writel((dev<<1) | LPC32XX_I2C_TX_START, &i2c->tx);
		/* write address bytes */
		while (alen--) {
			/* compute address byte + stop for the last one */
			int a = (addr >> (8 * alen)) & 0xff;
			if (!alen)
				a |= LPC32XX_I2C_TX_STOP;
			/* Send address byte */
			writel(a, &i2c->tx);
		}
		/* wait for end of transation */
		while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI))
			;
		/* clear end-of-transaction flag */
		writel(1, &i2c->stat);
	}
	/* do we have to read data at all? */
	if (length) {
		/* Address slave in read mode */
		writel(1 | (dev<<1) | LPC32XX_I2C_TX_START, &i2c->tx);
		wlen = length;
		/* get data */
		while (length | wlen) {
			/* read status for TFF and RFE */
			stat = readl(&i2c->stat);
			/* must we, can we write a trigger byte? */
			if ((wlen > 0)
			   & (!(stat & LPC32XX_I2C_STAT_TFF))) {
				wlen--;
				/* write trigger byte + stop if last */
				writel(wlen ? 0 :
				LPC32XX_I2C_TX_STOP, &i2c->tx);
			}
			/* must we, can we read a data byte? */
			if ((length > 0)
			   & (!(stat & LPC32XX_I2C_STAT_RFE))) {
				length--;
				/* read byte */
				*(data++) = readl(&i2c->rx);
			}
		}
	}
	/* wait for end of transation */
	while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI))
		;
	/* clear end-of-transaction flag */
	writel(1, &i2c->stat);
	/* success */
	return 0;
}

/*
 * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
 * Begin write, send address byte(s), send data bytes, end.
 */
static int lpc32xx_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,
			  int alen, u8 *data, int length)
{
	struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr];
	int stat;

	/* Soft-reset the controller */
	writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl);
	while (readl(&i2c->ctrl) & LPC32XX_I2C_SOFT_RESET)
		;
	/* do we need to write anything at all? */
	if (alen | length)
		/* Address slave in write mode */
		writel((dev<<1) | LPC32XX_I2C_TX_START, &i2c->tx);
	/* write address bytes */
	while (alen) {
		/* wait for transmit fifo not full */
		stat = readl(&i2c->stat);
		if (!(stat & LPC32XX_I2C_STAT_TFF)) {
			alen--;
			int a = (addr >> (8 * alen)) & 0xff;
			if (!(alen | length))
				a |= LPC32XX_I2C_TX_STOP;
			/* Send address byte */
			writel(a, &i2c->tx);
		}
	}
	while (length) {
		/* wait for transmit fifo not full */
		stat = readl(&i2c->stat);
		if (!(stat & LPC32XX_I2C_STAT_TFF)) {
			/* compute data byte, add stop if length==0 */
			length--;
			int d = *(data++);
			if (!length)
				d |= LPC32XX_I2C_TX_STOP;
			/* Send data byte */
			writel(d, &i2c->tx);
		}
	}
	/* wait for end of transation */
	while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI))
		;
	/* clear end-of-transaction flag */
	writel(1, &i2c->stat);
	return 0;
}

U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_0, _i2c_init, lpc32xx_i2c_probe,
			 lpc32xx_i2c_read, lpc32xx_i2c_write,
			 lpc32xx_i2c_set_bus_speed,
			 CONFIG_SYS_I2C_LPC32XX_SPEED,
			 CONFIG_SYS_I2C_LPC32XX_SLAVE,
			 0)

U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_1, _i2c_init, lpc32xx_i2c_probe,
			 lpc32xx_i2c_read, lpc32xx_i2c_write,
			 lpc32xx_i2c_set_bus_speed,
			 CONFIG_SYS_I2C_LPC32XX_SPEED,
			 CONFIG_SYS_I2C_LPC32XX_SLAVE,
			 1)
