diff options
author | Tom Rini <trini@ti.com> | 2013-07-24 09:22:28 -0400 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2013-07-24 09:50:24 -0400 |
commit | c2120fbfbc4d1f6953228f86be8bdbf38bacfdab (patch) | |
tree | 14cd8ec9a0a61f7113149be38d79808cd5e955f8 /drivers/i2c/ppc4xx_i2c.c | |
parent | e85427fd66a21b39145a47e67871a8863c0e5591 (diff) | |
parent | ecbd7e1ec7280d90d151a99691f74b892588cadd (diff) | |
download | u-boot-imx-c2120fbfbc4d1f6953228f86be8bdbf38bacfdab.zip u-boot-imx-c2120fbfbc4d1f6953228f86be8bdbf38bacfdab.tar.gz u-boot-imx-c2120fbfbc4d1f6953228f86be8bdbf38bacfdab.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-i2c
The sandburst-specific i2c drivers have been deleted, conflict was just
over the SPDX conversion.
Conflicts:
board/sandburst/common/ppc440gx_i2c.c
board/sandburst/common/ppc440gx_i2c.h
Signed-off-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'drivers/i2c/ppc4xx_i2c.c')
-rw-r--r-- | drivers/i2c/ppc4xx_i2c.c | 193 |
1 files changed, 96 insertions, 97 deletions
diff --git a/drivers/i2c/ppc4xx_i2c.c b/drivers/i2c/ppc4xx_i2c.c index 52929eb..e7a15ba 100644 --- a/drivers/i2c/ppc4xx_i2c.c +++ b/drivers/i2c/ppc4xx_i2c.c @@ -16,27 +16,29 @@ #include <i2c.h> #include <asm/io.h> -#ifdef CONFIG_HARD_I2C - DECLARE_GLOBAL_DATA_PTR; -#if defined(CONFIG_I2C_MULTI_BUS) -/* - * Initialize the bus pointer to whatever one the SPD EEPROM is on. - * Default is bus 0. This is necessary because the DDR initialization - * runs from ROM, and we can't switch buses because we can't modify - * the global variables. - */ -#ifndef CONFIG_SYS_SPD_BUS_NUM -#define CONFIG_SYS_SPD_BUS_NUM 0 +static inline struct ppc4xx_i2c *ppc4xx_get_i2c(int hwadapnr) +{ + unsigned long base; + +#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ + defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) + base = CONFIG_SYS_PERIPHERAL_BASE + 0x00000700 + (hwadapnr * 0x100); +#elif defined(CONFIG_440) || defined(CONFIG_405EX) +/* all remaining 440 variants */ + base = CONFIG_SYS_PERIPHERAL_BASE + 0x00000400 + (hwadapnr * 0x100); +#else +/* all 405 variants */ + base = 0xEF600500 + (hwadapnr * 0x100); #endif -static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = - CONFIG_SYS_SPD_BUS_NUM; -#endif /* CONFIG_I2C_MULTI_BUS */ + return (struct ppc4xx_i2c *)base; +} -static void _i2c_bus_reset(void) +static void _i2c_bus_reset(struct i2c_adapter *adap) { - struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR; + struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr); int i; u8 dc; @@ -75,11 +77,10 @@ static void _i2c_bus_reset(void) out_8(&i2c->xtcntlss, 0); } -void i2c_init(int speed, int slaveaddr) +static void ppc4xx_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) { - struct ppc4xx_i2c *i2c; + struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr); int val, divisor; - int bus; #ifdef CONFIG_SYS_I2C_INIT_BOARD /* @@ -90,67 +91,57 @@ void i2c_init(int speed, int slaveaddr) i2c_init_board(); #endif - for (bus = 0; bus < CONFIG_SYS_MAX_I2C_BUS; bus++) { - I2C_SET_BUS(bus); - - /* Set i2c pointer after calling I2C_SET_BUS() */ - i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR; - - /* Handle possible failed I2C state */ - /* FIXME: put this into i2c_init_board()? */ - _i2c_bus_reset(); + /* Handle possible failed I2C state */ + /* FIXME: put this into i2c_init_board()? */ + _i2c_bus_reset(adap); - /* clear lo master address */ - out_8(&i2c->lmadr, 0); + /* clear lo master address */ + out_8(&i2c->lmadr, 0); - /* clear hi master address */ - out_8(&i2c->hmadr, 0); - - /* clear lo slave address */ - out_8(&i2c->lsadr, 0); + /* clear hi master address */ + out_8(&i2c->hmadr, 0); - /* clear hi slave address */ - out_8(&i2c->hsadr, 0); + /* clear lo slave address */ + out_8(&i2c->lsadr, 0); - /* Clock divide Register */ - /* set divisor according to freq_opb */ - divisor = (get_OPB_freq() - 1) / 10000000; - if (divisor == 0) - divisor = 1; - out_8(&i2c->clkdiv, divisor); + /* clear hi slave address */ + out_8(&i2c->hsadr, 0); - /* no interrupts */ - out_8(&i2c->intrmsk, 0); + /* Clock divide Register */ + /* set divisor according to freq_opb */ + divisor = (get_OPB_freq() - 1) / 10000000; + if (divisor == 0) + divisor = 1; + out_8(&i2c->clkdiv, divisor); - /* clear transfer count */ - out_8(&i2c->xfrcnt, 0); + /* no interrupts */ + out_8(&i2c->intrmsk, 0); - /* clear extended control & stat */ - /* write 1 in SRC SRS SWC SWS to clear these fields */ - out_8(&i2c->xtcntlss, 0xF0); + /* clear transfer count */ + out_8(&i2c->xfrcnt, 0); - /* Mode Control Register - Flush Slave/Master data buffer */ - out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB); + /* clear extended control & stat */ + /* write 1 in SRC SRS SWC SWS to clear these fields */ + out_8(&i2c->xtcntlss, 0xF0); - val = in_8(&i2c->mdcntl); + /* Mode Control Register + Flush Slave/Master data buffer */ + out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB); - /* Ignore General Call, slave transfers are ignored, - * disable interrupts, exit unknown bus state, enable hold - * SCL 100kHz normaly or FastMode for 400kHz and above - */ + val = in_8(&i2c->mdcntl); - val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL; - if (speed >= 400000) - val |= IIC_MDCNTL_FSM; - out_8(&i2c->mdcntl, val); + /* Ignore General Call, slave transfers are ignored, + * disable interrupts, exit unknown bus state, enable hold + * SCL 100kHz normaly or FastMode for 400kHz and above + */ - /* clear control reg */ - out_8(&i2c->cntl, 0x00); - } + val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL; + if (speed >= 400000) + val |= IIC_MDCNTL_FSM; + out_8(&i2c->mdcntl, val); - /* set to SPD bus as default bus upon powerup */ - I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM); + /* clear control reg */ + out_8(&i2c->cntl, 0x00); } /* @@ -178,14 +169,15 @@ void i2c_init(int speed, int slaveaddr) * * It does not check XFRCNT. */ -static int i2c_transfer(unsigned char cmd_type, +static int _i2c_transfer(struct i2c_adapter *adap, + unsigned char cmd_type, unsigned char chip, unsigned char addr[], unsigned char addr_len, unsigned char data[], unsigned short data_len) { - struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR; + struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr); u8 *ptr; int reading; int tran, cnt; @@ -329,7 +321,7 @@ static int i2c_transfer(unsigned char cmd_type, return result; } -int i2c_probe(uchar chip) +static int ppc4xx_i2c_probe(struct i2c_adapter *adap, uchar chip) { uchar buf[1]; @@ -340,11 +332,11 @@ int i2c_probe(uchar chip) * address was <ACK>ed (i.e. there was a chip at that address which * drove the data line low). */ - return (i2c_transfer(1, chip << 1, 0, 0, buf, 1) != 0); + return (_i2c_transfer(adap, 1, chip << 1, 0, 0, buf, 1) != 0); } -static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, - int len, int read) +static int ppc4xx_i2c_transfer(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len, int read) { uchar xaddr[4]; int ret; @@ -378,43 +370,50 @@ static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer, chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); #endif - if ((ret = i2c_transfer(read, chip << 1, &xaddr[4 - alen], alen, - buffer, len)) != 0) { + ret = _i2c_transfer(adap, read, chip << 1, &xaddr[4 - alen], alen, + buffer, len); + if (ret) { printf("I2C %s: failed %d\n", read ? "read" : "write", ret); - return 1; } return 0; } -int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len) +static int ppc4xx_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) { - return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 1); + return ppc4xx_i2c_transfer(adap, chip, addr, alen, buffer, len, 1); } -int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len) +static int ppc4xx_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, + int alen, uchar *buffer, int len) { - return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 0); + return ppc4xx_i2c_transfer(adap, chip, addr, alen, buffer, len, 0); } -#if defined(CONFIG_I2C_MULTI_BUS) -/* - * Functions for multiple I2C bus handling - */ -unsigned int i2c_get_bus_num(void) +static unsigned int ppc4xx_i2c_set_bus_speed(struct i2c_adapter *adap, + unsigned int speed) { - return i2c_bus_num; -} - -int i2c_set_bus_num(unsigned int bus) -{ - if (bus >= CONFIG_SYS_MAX_I2C_BUS) + if (speed != adap->speed) return -1; - - i2c_bus_num = bus; - - return 0; + return speed; } -#endif /* CONFIG_I2C_MULTI_BUS */ -#endif /* CONFIG_HARD_I2C */ + +/* + * Register ppc4xx i2c adapters + */ +#ifdef CONFIG_SYS_I2C_PPC4XX_CH0 +U_BOOT_I2C_ADAP_COMPLETE(ppc4xx_0, ppc4xx_i2c_init, ppc4xx_i2c_probe, + ppc4xx_i2c_read, ppc4xx_i2c_write, + ppc4xx_i2c_set_bus_speed, + CONFIG_SYS_I2C_PPC4XX_SPEED_0, + CONFIG_SYS_I2C_PPC4XX_SLAVE_0, 0) +#endif +#ifdef CONFIG_SYS_I2C_PPC4XX_CH1 +U_BOOT_I2C_ADAP_COMPLETE(ppc4xx_1, ppc4xx_i2c_init, ppc4xx_i2c_probe, + ppc4xx_i2c_read, ppc4xx_i2c_write, + ppc4xx_i2c_set_bus_speed, + CONFIG_SYS_I2C_PPC4XX_SPEED_1, + CONFIG_SYS_I2C_PPC4XX_SLAVE_1, 1) +#endif |