diff options
| author | Tom Rini <trini@ti.com> | 2013-12-10 09:29:45 -0500 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-12-10 09:29:45 -0500 | 
| commit | 76a8265b4f54d1b9cd2b70efb46dcdeaa5d20bfb (patch) | |
| tree | 47ede3d54193de3883adc8ae6bdbf16c1fcab271 /drivers/i2c | |
| parent | 3f56795635ab419d3378451a9291490cfa47f472 (diff) | |
| parent | e717fc6d1a2b459ae8352f7af5945cc0c216ab1e (diff) | |
| download | olio-uboot-2014.01-76a8265b4f54d1b9cd2b70efb46dcdeaa5d20bfb.tar.xz olio-uboot-2014.01-76a8265b4f54d1b9cd2b70efb46dcdeaa5d20bfb.zip | |
Merge branch 'master' of git://git.denx.de/u-boot-i2c
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/Makefile | 2 | ||||
| -rw-r--r-- | drivers/i2c/fti2c010.c | 352 | ||||
| -rw-r--r-- | drivers/i2c/omap24xx_i2c.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/s3c24x0_i2c.c | 284 | 
4 files changed, 393 insertions, 251 deletions
| diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 553b519cc..fa3a87570 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_I2C_MVTWSI) += mvtwsi.o  obj-$(CONFIG_I2C_MV) += mv_i2c.o  obj-$(CONFIG_I2C_MXS) += mxs_i2c.o  obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o -obj-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o  obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o  obj-$(CONFIG_U8500_I2C) += u8500_i2c.o  obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o @@ -24,6 +23,7 @@ obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o  obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o  obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o  obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o +obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o  obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o  obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o  obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o diff --git a/drivers/i2c/fti2c010.c b/drivers/i2c/fti2c010.c index ddeb941fa..fb9fa353d 100644 --- a/drivers/i2c/fti2c010.c +++ b/drivers/i2c/fti2c010.c @@ -13,67 +13,78 @@  #include "fti2c010.h" -#ifndef CONFIG_HARD_I2C -#error "fti2c010: CONFIG_HARD_I2C is not defined" +#ifndef CONFIG_SYS_I2C_SPEED +#define CONFIG_SYS_I2C_SPEED    5000  #endif -#ifndef CONFIG_SYS_I2C_SPEED -#define CONFIG_SYS_I2C_SPEED    50000 +#ifndef CONFIG_SYS_I2C_SLAVE +#define CONFIG_SYS_I2C_SLAVE    0  #endif -#ifndef CONFIG_FTI2C010_FREQ -#define CONFIG_FTI2C010_FREQ    clk_get_rate("I2C") +#ifndef CONFIG_FTI2C010_CLOCK +#define CONFIG_FTI2C010_CLOCK   clk_get_rate("I2C")  #endif -/* command timeout */ -#define CFG_CMD_TIMEOUT         10 /* ms */ +#ifndef CONFIG_FTI2C010_TIMEOUT +#define CONFIG_FTI2C010_TIMEOUT 10 /* ms */ +#endif -/* 7-bit chip address + 1-bit read/write */ -#define I2C_RD(chip)            ((((chip) << 1) & 0xff) | 1) -#define I2C_WR(chip)            (((chip) << 1) & 0xff) +/* 7-bit dev address + 1-bit read/write */ +#define I2C_RD(dev)             ((((dev) << 1) & 0xfe) | 1) +#define I2C_WR(dev)             (((dev) << 1) & 0xfe)  struct fti2c010_chip { -	void __iomem *regs; -	uint bus; -	uint speed; +	struct fti2c010_regs *regs;  };  static struct fti2c010_chip chip_list[] = {  	{ -		.bus  = 0, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE,  	}, -#ifdef CONFIG_I2C_MULTI_BUS -# ifdef CONFIG_FTI2C010_BASE1 +#ifdef CONFIG_FTI2C010_BASE1  	{ -		.bus  = 1, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE1, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE1,  	}, -# endif -# ifdef CONFIG_FTI2C010_BASE2 +#endif +#ifdef CONFIG_FTI2C010_BASE2  	{ -		.bus  = 2, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE2, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE2,  	}, -# endif -# ifdef CONFIG_FTI2C010_BASE3 +#endif +#ifdef CONFIG_FTI2C010_BASE3  	{ -		.bus  = 3, -		.regs = (void __iomem *)CONFIG_FTI2C010_BASE3, +		.regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE3,  	}, -# endif -#endif  /* #ifdef CONFIG_I2C_MULTI_BUS */ +#endif  }; -static struct fti2c010_chip *curr = chip_list; +static int fti2c010_reset(struct fti2c010_chip *chip) +{ +	ulong ts; +	int ret = -1; +	struct fti2c010_regs *regs = chip->regs; + +	writel(CR_I2CRST, ®s->cr); +	for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { +		if (!(readl(®s->cr) & CR_I2CRST)) { +			ret = 0; +			break; +		} +	} -static int fti2c010_wait(uint32_t mask) +	if (ret) +		printf("fti2c010: reset timeout\n"); + +	return ret; +} + +static int fti2c010_wait(struct fti2c010_chip *chip, uint32_t mask)  {  	int ret = -1;  	uint32_t stat, ts; -	struct fti2c010_regs *regs = curr->regs; +	struct fti2c010_regs *regs = chip->regs; -	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { +	for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) {  		stat = readl(®s->sr);  		if ((stat & mask) == mask) {  			ret = 0; @@ -84,88 +95,124 @@ static int fti2c010_wait(uint32_t mask)  	return ret;  } -/* - * u-boot I2C API - */ +static unsigned int set_i2c_bus_speed(struct fti2c010_chip *chip, +	unsigned int speed) +{ +	struct fti2c010_regs *regs = chip->regs; +	unsigned int clk = CONFIG_FTI2C010_CLOCK; +	unsigned int gsr = 0; +	unsigned int tsr = 32; +	unsigned int div, rate; + +	for (div = 0; div < 0x3ffff; ++div) { +		/* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ +		rate = clk / (2 * (div + 2) + gsr); +		if (rate <= speed) +			break; +	} + +	writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); +	writel(CDR_DIV(div), ®s->cdr); + +	return rate; +}  /*   * Initialization, must be called once on start up, may be called   * repeatedly to change the speed and slave addresses.   */ -void i2c_init(int speed, int slaveaddr) +static void fti2c010_init(struct i2c_adapter *adap, int speed, int slaveaddr)  { -	if (speed || !curr->speed) -		i2c_set_bus_speed(speed); +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; -	/* if slave mode disabled */ -	if (!slaveaddr) +	if (adap->init_done)  		return; -	/* -	 * TODO: -	 * Implement slave mode, but is it really necessary? -	 */ +#ifdef CONFIG_SYS_I2C_INIT_BOARD +	/* Call board specific i2c bus reset routine before accessing the +	 * environment, which might be in a chip on that bus. For details +	 * about this problem see doc/I2C_Edge_Conditions. +	*/ +	i2c_init_board(); +#endif + +	/* master init */ + +	fti2c010_reset(chip); + +	set_i2c_bus_speed(chip, speed); + +	/* slave init, don't care */ + +#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT +	/* Call board specific i2c bus reset routine AFTER the bus has been +	 * initialized. Use either this callpoint or i2c_init_board; +	 * which is called before fti2c010_init operations. +	 * For details about this problem see doc/I2C_Edge_Conditions. +	*/ +	i2c_board_late_init(); +#endif  }  /*   * Probe the given I2C chip address.  Returns 0 if a chip responded,   * not 0 on failure.   */ -int i2c_probe(uchar chip) +static int fti2c010_probe(struct i2c_adapter *adap, u8 dev)  { +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	struct fti2c010_regs *regs = chip->regs;  	int ret; -	struct fti2c010_regs *regs = curr->regs; - -	i2c_init(0, 0);  	/* 1. Select slave device (7bits Address + 1bit R/W) */ -	writel(I2C_WR(chip), ®s->dr); +	writel(I2C_WR(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret;  	/* 2. Select device register */  	writel(0, ®s->dr);  	writel(CR_ENABLE | CR_TBEN, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	return ret;  } -/* - * Read/Write interface: - *   chip:    I2C chip address, range 0..127 - *   addr:    Memory (register) address within the chip - *   alen:    Number of bytes to use for addr (typically 1, 2 for larger - *              memories, 0 for register type devices with only one - *              register) - *   buffer:  Where to read/write the data - *   len:     How many bytes to read/write - * - *   Returns: 0 on success, not 0 on failure - */ -int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +static void to_i2c_addr(u8 *buf, uint32_t addr, int alen) +{ +	int i, shift; + +	if (!buf || alen <= 0) +		return; + +	/* MSB first */ +	i = 0; +	shift = (alen - 1) * 8; +	while (alen-- > 0) { +		buf[i] = (u8)(addr >> shift); +		shift -= 8; +	} +} + +static int fti2c010_read(struct i2c_adapter *adap, +			u8 dev, uint addr, int alen, uchar *buf, int len)  { +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	struct fti2c010_regs *regs = chip->regs;  	int ret, pos;  	uchar paddr[4]; -	struct fti2c010_regs *regs = curr->regs; -	i2c_init(0, 0); - -	paddr[0] = (addr >> 0)  & 0xFF; -	paddr[1] = (addr >> 8)  & 0xFF; -	paddr[2] = (addr >> 16) & 0xFF; -	paddr[3] = (addr >> 24) & 0xFF; +	to_i2c_addr(paddr, addr, alen);  	/*  	 * Phase A. Set register address  	 */  	/* A.1 Select slave device (7bits Address + 1bit R/W) */ -	writel(I2C_WR(chip), ®s->dr); +	writel(I2C_WR(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret; @@ -175,7 +222,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  		writel(paddr[pos], ®s->dr);  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(SR_DT); +		ret = fti2c010_wait(chip, SR_DT);  		if (ret)  			return ret;  	} @@ -185,9 +232,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  	 */  	/* B.1 Select slave device (7bits Address + 1bit R/W) */ -	writel(I2C_RD(chip), ®s->dr); +	writel(I2C_RD(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret; @@ -201,7 +248,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  			stat |= SR_ACK;  		}  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(stat); +		ret = fti2c010_wait(chip, stat);  		if (ret)  			break;  		buf[pos] = (uchar)(readl(®s->dr) & 0xFF); @@ -210,39 +257,24 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)  	return ret;  } -/* - * Read/Write interface: - *   chip:    I2C chip address, range 0..127 - *   addr:    Memory (register) address within the chip - *   alen:    Number of bytes to use for addr (typically 1, 2 for larger - *              memories, 0 for register type devices with only one - *              register) - *   buffer:  Where to read/write the data - *   len:     How many bytes to read/write - * - *   Returns: 0 on success, not 0 on failure - */ -int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) +static int fti2c010_write(struct i2c_adapter *adap, +			u8 dev, uint addr, int alen, u8 *buf, int len)  { +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	struct fti2c010_regs *regs = chip->regs;  	int ret, pos;  	uchar paddr[4]; -	struct fti2c010_regs *regs = curr->regs; -	i2c_init(0, 0); - -	paddr[0] = (addr >> 0)  & 0xFF; -	paddr[1] = (addr >> 8)  & 0xFF; -	paddr[2] = (addr >> 16) & 0xFF; -	paddr[3] = (addr >> 24) & 0xFF; +	to_i2c_addr(paddr, addr, alen);  	/*  	 * Phase A. Set register address  	 *  	 * A.1 Select slave device (7bits Address + 1bit R/W)  	 */ -	writel(I2C_WR(chip), ®s->dr); +	writel(I2C_WR(dev), ®s->dr);  	writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); -	ret = fti2c010_wait(SR_DT); +	ret = fti2c010_wait(chip, SR_DT);  	if (ret)  		return ret; @@ -252,7 +284,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)  		writel(paddr[pos], ®s->dr);  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(SR_DT); +		ret = fti2c010_wait(chip, SR_DT);  		if (ret)  			return ret;  	} @@ -267,7 +299,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)  			ctrl |= CR_STOP;  		writel(buf[pos], ®s->dr);  		writel(ctrl, ®s->cr); -		ret = fti2c010_wait(SR_DT); +		ret = fti2c010_wait(chip, SR_DT);  		if (ret)  			break;  	} @@ -275,94 +307,40 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)  	return ret;  } -/* - * Functions for setting the current I2C bus and its speed - */ -#ifdef CONFIG_I2C_MULTI_BUS - -/* - * i2c_set_bus_num: - * - *  Change the active I2C bus.  Subsequent read/write calls will - *  go to this one. - * - *    bus - bus index, zero based - * - *    Returns: 0 on success, not 0 on failure - */ -int i2c_set_bus_num(uint bus) -{ -	if (bus >= ARRAY_SIZE(chip_list)) -		return -1; -	curr = chip_list + bus; -	i2c_init(0, 0); -	return 0; -} - -/* - * i2c_get_bus_num: - * - *  Returns index of currently active I2C bus.  Zero-based. - */ - -uint i2c_get_bus_num(void) -{ -	return curr->bus; -} - -#endif    /* #ifdef CONFIG_I2C_MULTI_BUS */ - -/* - * i2c_set_bus_speed: - * - *  Change the speed of the active I2C bus - * - *    speed - bus speed in Hz - * - *    Returns: 0 on success, not 0 on failure - */ -int i2c_set_bus_speed(uint speed) +static unsigned int fti2c010_set_bus_speed(struct i2c_adapter *adap, +			unsigned int speed)  { -	struct fti2c010_regs *regs = curr->regs; -	uint clk = CONFIG_FTI2C010_FREQ; -	uint gsr = 0, tsr = 32; -	uint spd, div; - -	if (!speed) -		speed = CONFIG_SYS_I2C_SPEED; - -	for (div = 0; div < 0x3ffff; ++div) { -		/* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ -		spd = clk / (2 * (div + 2) + gsr); -		if (spd <= speed) -			break; -	} - -	if (curr->speed == spd) -		return 0; - -	writel(CR_I2CRST, ®s->cr); -	mdelay(100); -	if (readl(®s->cr) & CR_I2CRST) { -		printf("fti2c010: reset timeout\n"); -		return -1; -	} +	struct fti2c010_chip *chip = chip_list + adap->hwadapnr; +	int ret; -	curr->speed = spd; +	fti2c010_reset(chip); +	ret = set_i2c_bus_speed(chip, speed); -	writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); -	writel(CDR_DIV(div), ®s->cdr); - -	return 0; +	return ret;  }  /* - * i2c_get_bus_speed: - * - *  Returns speed of currently active I2C bus in Hz + * Register i2c adapters   */ - -uint i2c_get_bus_speed(void) -{ -	return curr->speed; -} +U_BOOT_I2C_ADAP_COMPLETE(i2c_0, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			0) +#ifdef CONFIG_FTI2C010_BASE1 +U_BOOT_I2C_ADAP_COMPLETE(i2c_1, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			1) +#endif +#ifdef CONFIG_FTI2C010_BASE2 +U_BOOT_I2C_ADAP_COMPLETE(i2c_2, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			2) +#endif +#ifdef CONFIG_FTI2C010_BASE3 +U_BOOT_I2C_ADAP_COMPLETE(i2c_3, fti2c010_init, fti2c010_probe, fti2c010_read, +			fti2c010_write, fti2c010_set_bus_speed, +			CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, +			3) +#endif diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 3d38c035b..c7840049b 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -158,7 +158,6 @@ static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)  	udelay(1000);  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  }  static void flush_fifo(struct i2c_adapter *adap) @@ -198,8 +197,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)  		return res;  	/* No data transfer, slave addr only */ -	writew(0, &i2c_base->cnt); -	/* Set slave address */  	writew(chip, &i2c_base->sa);  	/* Stop bit needed here */  	writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | @@ -234,7 +231,6 @@ static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)  pr_exit:  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  	return res;  } @@ -372,7 +368,6 @@ static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,  rd_exit:  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  	return i2c_error;  } @@ -473,7 +468,6 @@ static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,  wr_exit:  	flush_fifo(adap);  	writew(0xFFFF, &i2c_base->stat); -	writew(0, &i2c_base->cnt);  	return i2c_error;  } diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index f77a9d1a1..fd328f054 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -23,8 +23,6 @@  #include <i2c.h>  #include "s3c24x0_i2c.h" -#ifdef CONFIG_HARD_I2C -  #define	I2C_WRITE	0  #define I2C_READ	1 @@ -127,7 +125,6 @@   * For SPL boot some boards need i2c before SDRAM is initialised so force   * variables to live in SRAM   */ -static unsigned int g_current_bus __attribute__((section(".data")));  static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]  			__attribute__((section(".data"))); @@ -254,17 +251,17 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)  	writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon);  } -static struct s3c24x0_i2c *get_base_i2c(void) +static struct s3c24x0_i2c *get_base_i2c(int bus)  {  #ifdef CONFIG_EXYNOS4  	struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()  							+ (EXYNOS4_I2C_SPACING -							* g_current_bus)); +							* bus));  	return i2c;  #elif defined CONFIG_EXYNOS5  	struct s3c24x0_i2c *i2c = (struct s3c24x0_i2c *)(samsung_get_base_i2c()  							+ (EXYNOS5_I2C_SPACING -							* g_current_bus)); +							* bus));  	return i2c;  #else  	return s3c24x0_get_base_i2c(); @@ -298,7 +295,6 @@ static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)  	writel(I2C_MODE_MT | I2C_TXRX_ENA, &i2c->iicstat);  } -#ifdef CONFIG_I2C_MULTI_BUS  static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)  {  	struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; @@ -307,8 +303,10 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)  	unsigned int i = 0, utemp0 = 0, utemp1 = 0;  	unsigned int t_ftl_cycle; -#if defined CONFIG_EXYNOS5 +#if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)  	clkin = get_i2c_clk(); +#else +	clkin = get_PCLK();  #endif  	/* FPCLK / FI2C =  	 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE @@ -330,7 +328,6 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)  	}  	return -1;  } -#endif  static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus)  { @@ -401,49 +398,18 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus)  	hsi2c_ch_init(i2c_bus);  } -/* - * MULTI BUS I2C support - */ - -#ifdef CONFIG_I2C_MULTI_BUS -int i2c_set_bus_num(unsigned int bus) -{ -	struct s3c24x0_i2c_bus *i2c_bus; - -	i2c_bus = get_bus(bus); -	if (!i2c_bus) -		return -1; -	g_current_bus = bus; - -	if (i2c_bus->is_highspeed) { -		if (hsi2c_get_clk_details(i2c_bus)) -			return -1; -		hsi2c_ch_init(i2c_bus); -	} else { -		i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, -						CONFIG_SYS_I2C_SLAVE); -	} - -	return 0; -} - -unsigned int i2c_get_bus_num(void) -{ -	return g_current_bus; -} -#endif - -void i2c_init(int speed, int slaveadd) +static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)  {  	struct s3c24x0_i2c *i2c; +	struct s3c24x0_i2c_bus *bus; +  #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)  	struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();  #endif  	ulong start_time = get_timer(0);  	/* By default i2c channel 0 is the current bus */ -	g_current_bus = 0; -	i2c = get_base_i2c(); +	i2c = get_base_i2c(adap->hwadapnr);  	/*  	 * In case the previous transfer is still going, wait to give it a @@ -505,6 +471,10 @@ void i2c_init(int speed, int slaveadd)  	}  #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */  	i2c_ch_init(i2c, speed, slaveadd); + +	bus = &i2c_bus[adap->hwadapnr]; +	bus->active = true; +	bus->regs = i2c;  }  /* @@ -728,6 +698,40 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,  	return rv;  } +static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap, +					  unsigned int speed) +{ +	struct s3c24x0_i2c_bus *i2c_bus; + +	i2c_bus = get_bus(adap->hwadapnr); +	if (!i2c_bus) +		return -1; + +	i2c_bus->clock_frequency = speed; + +	if (i2c_bus->is_highspeed) { +		if (hsi2c_get_clk_details(i2c_bus)) +			return -1; +		hsi2c_ch_init(i2c_bus); +	} else { +		i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, +			    CONFIG_SYS_I2C_S3C24X0_SLAVE); +	} + +	return 0; +} + +#ifdef CONFIG_EXYNOS5 +static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) +{ +	/* This will override the speed selected in the fdt for that port */ +	debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr); +	if (i2c_set_bus_speed(speed)) +		printf("i2c_init: failed to init bus %d for speed = %d\n", +						adap->hwadapnr, speed); +} +#endif +  /*   * cmd_type is 0 for write, 1 for read.   * @@ -840,13 +844,13 @@ bailout:  	return result;  } -int i2c_probe(uchar chip) +static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)  {  	struct s3c24x0_i2c_bus *i2c_bus;  	uchar buf[1];  	int ret; -	i2c_bus = get_bus(g_current_bus); +	i2c_bus = get_bus(adap->hwadapnr);  	if (!i2c_bus)  		return -1;  	buf[0] = 0; @@ -864,11 +868,11 @@ int i2c_probe(uchar chip)  				I2C_READ, chip << 1, 0, 0, buf, 1);  	} -  	return ret != I2C_OK;  } -int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) +static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, +			    int alen, uchar *buffer, int len)  {  	struct s3c24x0_i2c_bus *i2c_bus;  	uchar xaddr[4]; @@ -902,7 +906,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)  		chip |= ((addr >> (alen * 8)) &  			 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);  #endif -	i2c_bus = get_bus(g_current_bus); +	i2c_bus = get_bus(adap->hwadapnr);  	if (!i2c_bus)  		return -1; @@ -922,7 +926,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)  	return 0;  } -int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) +static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, +			 int alen, uchar *buffer, int len)  {  	struct s3c24x0_i2c_bus *i2c_bus;  	uchar xaddr[4]; @@ -955,7 +960,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)  		chip |= ((addr >> (alen * 8)) &  			 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);  #endif -	i2c_bus = get_bus(g_current_bus); +	i2c_bus = get_bus(adap->hwadapnr);  	if (!i2c_bus)  		return -1; @@ -1001,8 +1006,8 @@ static void process_nodes(const void *blob, int node_list[], int count,  		bus->id = pinmux_decode_periph_id(blob, node);  		bus->clock_frequency = fdtdec_get_int(blob, node, -						      "clock-frequency", -						      CONFIG_SYS_I2C_SPEED); +						"clock-frequency", +						CONFIG_SYS_I2C_S3C24X0_SPEED);  		bus->node = node;  		bus->bus_num = i;  		exynos_pinmux_config(bus->id, 0); @@ -1044,7 +1049,6 @@ int i2c_get_bus_num_fdt(int node)  	return -1;  } -#ifdef CONFIG_I2C_MULTI_BUS  int i2c_reset_port_fdt(const void *blob, int node)  {  	struct s3c24x0_i2c_bus *i2c_bus; @@ -1068,12 +1072,178 @@ int i2c_reset_port_fdt(const void *blob, int node)  		hsi2c_ch_init(i2c_bus);  	} else {  		i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency, -						CONFIG_SYS_I2C_SLAVE); +			    CONFIG_SYS_I2C_S3C24X0_SLAVE);  	}  	return 0;  }  #endif -#endif -#endif /* CONFIG_HARD_I2C */ +/* + * Register s3c24x0 i2c adapters + */ +#if defined(CONFIG_EXYNOS5420) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +U_BOOT_I2C_ADAP_COMPLETE(i2c09, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) +U_BOOT_I2C_ADAP_COMPLETE(i2c10, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) +#elif defined(CONFIG_EXYNOS5250) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, exynos_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +U_BOOT_I2C_ADAP_COMPLETE(i2c09, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 9) +U_BOOT_I2C_ADAP_COMPLETE(s3c10, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 10) +#elif defined(CONFIG_EXYNOS4) +U_BOOT_I2C_ADAP_COMPLETE(i2c00, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE(i2c01, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 1) +U_BOOT_I2C_ADAP_COMPLETE(i2c02, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 2) +U_BOOT_I2C_ADAP_COMPLETE(i2c03, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 3) +U_BOOT_I2C_ADAP_COMPLETE(i2c04, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 4) +U_BOOT_I2C_ADAP_COMPLETE(i2c05, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 5) +U_BOOT_I2C_ADAP_COMPLETE(i2c06, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 6) +U_BOOT_I2C_ADAP_COMPLETE(i2c07, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 7) +U_BOOT_I2C_ADAP_COMPLETE(i2c08, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 8) +#else +U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe, +			s3c24x0_i2c_read, s3c24x0_i2c_write, +			s3c24x0_i2c_set_bus_speed, +			CONFIG_SYS_I2C_S3C24X0_SPEED, +			CONFIG_SYS_I2C_S3C24X0_SLAVE, 0) +#endif |