/*
 * 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 = (get_hclk_clk_rate() / 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);
	else
		return 0;
	/* 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)
