[U-Boot] [PATCH] 5/12 Multiadapter/multibus I2C, drivers part 2

Signed-off-by: Sergey Kubushyn ksi@koi8.net --- diff -purN u-boot-i2c.orig/drivers/i2c/omap1510_i2c.c u-boot-i2c/drivers/i2c/omap1510_i2c.c --- u-boot-i2c.orig/drivers/i2c/omap1510_i2c.c 2009-02-12 10:43:41.000000000 -0800 +++ u-boot-i2c/drivers/i2c/omap1510_i2c.c 2009-02-12 10:46:00.000000000 -0800 @@ -1,4 +1,8 @@ /* + * Copyright (c) 2009 Sergey Kubushyn ksi@koi8.net + * + * Changes for multibus/multiadapter I2C support. + * * Basic I2C functions * * Copyright (c) 2003 Texas Instruments @@ -19,11 +23,51 @@ */
#include <common.h> +#include <i2c.h> + +i2c_adap_t omap1510_i2c_adap; + +DECLARE_GLOBAL_DATA_PTR; + +static void wait_for_bb (void) +{ + int timeout = 10; + + while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) { + inw (I2C_IV); + udelay (1000); + } + + if (timeout <= 0) { + printf ("timed out in wait_for_bb: I2C_STAT=%x\n", + inw (I2C_STAT)); + } +} + +static u16 wait_for_pin (void) +{ + u16 status, iv; + int timeout = 10; + + do { + udelay (1000); + status = inw (I2C_STAT); + iv = inw (I2C_IV); + } while (!iv && + !(status & + (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | + I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | + I2C_STAT_AL)) && timeout--); + + if (timeout <= 0) { + printf ("timed out in wait_for_pin: I2C_STAT=%x\n", + inw (I2C_STAT)); + }
-static void wait_for_bb (void); -static u16 wait_for_pin (void); + return status; +}
-void i2c_init (int speed, int slaveadd) +static void omap1510_i2c_init (int speed, int slaveadd) { u16 scl;
@@ -46,6 +90,10 @@ void i2c_init (int speed, int slaveadd) outw (slaveadd, I2C_OA); outw (0, I2C_CNT); udelay (1000); + + if (gd->flags & GD_FLG_RELOC) { + omap1510_i2c_adap.init_done = 1; + } }
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) @@ -158,7 +206,7 @@ static int i2c_write_byte (u8 devaddr, u return i2c_error; }
-int i2c_probe (uchar chip) +static int omap1510_i2c_probe (uchar chip) { int res = 1;
@@ -188,24 +236,24 @@ int i2c_probe (uchar chip) return res; }
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +static int omap1510_i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { int i;
if (alen > 1) { - printf ("I2C read: addr len %d not supported\n", alen); + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); return 1; }
if (addr + len > 256) { - printf ("I2C read: address out of range\n"); + printf ("%s: address out of range\n", __FUNCTION__); return 1; }
for (i = 0; i < len; i++) { if (i2c_read_byte (chip, addr + i, &buffer[i])) { - printf ("I2C read: I/O error\n"); - i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + printf ("%s: I/O error\n", __FUNCTION__); + i2c_init (CONFIG_SYS_OMAP1510_I2C_SPEED, CONFIG_SYS_OMAP1510_I2C_SLAVE); return 1; } } @@ -213,24 +261,24 @@ int i2c_read (uchar chip, uint addr, int return 0; }
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) +static int omap1510_i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) { int i;
if (alen > 1) { - printf ("I2C read: addr len %d not supported\n", alen); + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); return 1; }
if (addr + len > 256) { - printf ("I2C read: address out of range\n"); + printf ("%s: address out of range\n", __FUNCTION__); return 1; }
for (i = 0; i < len; i++) { if (i2c_write_byte (chip, addr + i, buffer[i])) { - printf ("I2C read: I/O error\n"); - i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + printf ("%s: I/O error\n", __FUNCTION__); + i2c_init (CONFIG_SYS_OMAP1510_I2C_SPEED, CONFIG_SYS_OMAP1510_I2C_SLAVE); return 1; } } @@ -238,40 +286,25 @@ int i2c_write (uchar chip, uint addr, in return 0; }
-static void wait_for_bb (void) +static unsigned int omap1510_i2c_set_bus_speed(unsigned int speed) { - int timeout = 10; - - while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) { - inw (I2C_IV); - udelay (1000); - } - - if (timeout <= 0) { - printf ("timed out in wait_for_bb: I2C_STAT=%x\n", - inw (I2C_STAT)); - } + return(omap1510_i2c_adap.speed); }
-static u16 wait_for_pin (void) +static unsigned int omap1510_i2c_get_bus_speed(void) { - u16 status, iv; - int timeout = 10; - - do { - udelay (1000); - status = inw (I2C_STAT); - iv = inw (I2C_IV); - } while (!iv && - !(status & - (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | - I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | - I2C_STAT_AL)) && timeout--); - - if (timeout <= 0) { - printf ("timed out in wait_for_pin: I2C_STAT=%x\n", - inw (I2C_STAT)); - } - - return status; + return(omap1510_i2c_adap.speed); } + +i2c_adap_t omap1510_i2c_adap = { + .init = omap1510_i2c_init, + .probe = omap1510_i2c_probe, + .read = omap1510_i2c_read, + .write = omap1510_i2c_write, + .set_bus_speed = omap1510_i2c_set_bus_speed, + .get_bus_speed = omap1510_i2c_get_bus_speed, + .speed = CONFIG_SYS_OMAP1510_I2C_SPEED, + .slaveaddr = CONFIG_SYS_OMAP1510_I2C_SLAVE, + .init_done = 0, + .name = "omap1510_i2c" +}; diff -purN u-boot-i2c.orig/drivers/i2c/omap24xx_i2c.c u-boot-i2c/drivers/i2c/omap24xx_i2c.c --- u-boot-i2c.orig/drivers/i2c/omap24xx_i2c.c 2009-02-12 10:43:41.000000000 -0800 +++ u-boot-i2c/drivers/i2c/omap24xx_i2c.c 2009-02-12 10:46:00.000000000 -0800 @@ -1,4 +1,8 @@ /* + * Copyright (c) 2009 Sergey Kubushyn ksi@koi8.net + * + * Changes for multibus/multiadapter I2C support. + * * Basic I2C functions * * Copyright (c) 2004 Texas Instruments @@ -24,65 +28,134 @@
#include <asm/arch/i2c.h> #include <asm/io.h> +#include <i2c.h>
-static void wait_for_bb (void); -static u16 wait_for_pin (void); -static void flush_fifo(void); +#define OMAP24XX_NAME(arg) "omap24xx_i2c@" MK_NAME(arg) +#define MK_NAME(arg) #arg + +#ifndef CONFIG_SYS_OMAP24XX_I2C_BASE +#define CONFIG_SYS_OMAP24XX_I2C_BASE I2C_BASE1 +#endif
-void i2c_init (int speed, int slaveadd) +i2c_adap_t omap24xx_i2c_adap[]; + +DECLARE_GLOBAL_DATA_PTR; + +static void flush_fifo(ulong base) +{ + u16 stat; + + /* note: if you try and read data when its not there or ready + * you get a bus error + */ + while(1){ + stat = readw(base + I2C_STAT); + if(stat == I2C_STAT_RRDY){ +#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) + readb(base + I2C_DATA); +#else + readw(base + I2C_DATA); +#endif + writew(I2C_STAT_RRDY, base + I2C_STAT); + udelay(1000); + }else + break; + } +} + +static void wait_for_bb (ulong base) +{ + int timeout = 10; + u16 stat; + + writew(0xFFFF, base + I2C_STAT); /* clear current interruts...*/ + while ((stat = readw (base + I2C_STAT) & I2C_STAT_BB) && timeout--) { + writew (stat, base + I2C_STAT); + udelay (50000); + } + + if (timeout <= 0) { + printf ("timed out in wait_for_bb: I2C_STAT=%x\n", + readw (base + I2C_STAT)); + } + writew(0xFFFF, base + I2C_STAT); /* clear delayed stuff*/ +} + +static u16 wait_for_pin (ulong base) +{ + u16 status; + int timeout = 10; + + do { + udelay (1000); + status = readw (base + I2C_STAT); + } while ( !(status & + (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | + I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | + I2C_STAT_AL)) && timeout--); + + if (timeout <= 0) { + printf ("timed out in wait_for_pin: I2C_STAT=%x\n", + readw (base + I2C_STAT)); + writew(0xFFFF, base + I2C_STAT); + } + return status; +} + +static void _i2c_init (int speed, int slaveadd, ulong base) { u16 scl;
- writew(0x2, I2C_SYSC); /* for ES2 after soft reset */ + writew(0x2, base + I2C_SYSC); /* for ES2 after soft reset */ udelay(1000); - writew(0x0, I2C_SYSC); /* will probably self clear but */ + writew(0x0, base + I2C_SYSC); /* will probably self clear but */
- if (readw (I2C_CON) & I2C_CON_EN) { - writew (0, I2C_CON); + if (readw (base + I2C_CON) & I2C_CON_EN) { + writew (0, base + I2C_CON); udelay (50000); }
/* 12MHz I2C module clock */ - writew (0, I2C_PSC); + writew (0, base + I2C_PSC); speed = speed/1000; /* 100 or 400 */ scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */ - writew (scl, I2C_SCLL); - writew (scl, I2C_SCLH); + writew (scl, base + I2C_SCLL); + writew (scl, base + I2C_SCLH); /* own address */ - writew (slaveadd, I2C_OA); - writew (I2C_CON_EN, I2C_CON); + writew (slaveadd, base + I2C_OA); + writew (I2C_CON_EN, base + I2C_CON);
/* have to enable intrrupts or OMAP i2c module doesn't work */ writew (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | - I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE); + I2C_IE_NACK_IE | I2C_IE_AL_IE, base + I2C_IE); udelay (1000); - flush_fifo(); - writew (0xFFFF, I2C_STAT); - writew (0, I2C_CNT); + flush_fifo(base); + writew (0xFFFF, base + I2C_STAT); + writew (0, base + I2C_CNT); }
-static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) +static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value, ulong base) { int i2c_error = 0; u16 status;
/* wait until bus not busy */ - wait_for_bb (); + wait_for_bb (base);
/* one byte only */ - writew (1, I2C_CNT); + writew (1, base + I2C_CNT); /* set slave address */ - writew (devaddr, I2C_SA); + writew (devaddr, base + I2C_SA); /* no stop bit needed here */ - writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, base + I2C_CON);
- status = wait_for_pin (); + status = wait_for_pin (base);
if (status & I2C_STAT_XRDY) { /* Important: have to use byte access */ - writeb (regoffset, I2C_DATA); + writeb (regoffset, base + I2C_DATA); udelay (20000); - if (readw (I2C_STAT) & I2C_STAT_NACK) { + if (readw (base + I2C_STAT) & I2C_STAT_NACK) { i2c_error = 1; } } else { @@ -91,28 +164,29 @@ static int i2c_read_byte (u8 devaddr, u8
if (!i2c_error) { /* free bus, otherwise we can't use a combined transction */ - writew (0, I2C_CON); - while (readw (I2C_STAT) || (readw (I2C_CON) & I2C_CON_MST)) { + writew (0, base + I2C_CON); + while (readw (base + I2C_STAT) || + (readw (base + I2C_CON) & I2C_CON_MST)) { udelay (10000); /* Have to clear pending interrupt to clear I2C_STAT */ - writew (0xFFFF, I2C_STAT); + writew (0xFFFF, base + I2C_STAT); }
- wait_for_bb (); + wait_for_bb (base); /* set slave address */ - writew (devaddr, I2C_SA); + writew (devaddr, base + I2C_SA); /* read one byte from slave */ - writew (1, I2C_CNT); + writew (1, base + I2C_CNT); /* need stop bit here */ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, - I2C_CON); + base + I2C_CON);
- status = wait_for_pin (); + status = wait_for_pin (base); if (status & I2C_STAT_RRDY) { #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) - *value = readb (I2C_DATA); + *value = readb (base + I2C_DATA); #else - *value = readw (I2C_DATA); + *value = readw (base + I2C_DATA); #endif udelay (20000); } else { @@ -120,60 +194,60 @@ static int i2c_read_byte (u8 devaddr, u8 }
if (!i2c_error) { - writew (I2C_CON_EN, I2C_CON); - while (readw (I2C_STAT) - || (readw (I2C_CON) & I2C_CON_MST)) { + writew (I2C_CON_EN, base + I2C_CON); + while (readw (base + I2C_STAT) + || (readw (base + I2C_CON) & I2C_CON_MST)) { udelay (10000); - writew (0xFFFF, I2C_STAT); + writew (0xFFFF, base + I2C_STAT); } } } - flush_fifo(); - writew (0xFFFF, I2C_STAT); - writew (0, I2C_CNT); + flush_fifo(base); + writew (0xFFFF, base + I2C_STAT); + writew (0, base + I2C_CNT); return i2c_error; }
-static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value) +static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value, ulong base) { int i2c_error = 0; u16 status, stat;
/* wait until bus not busy */ - wait_for_bb (); + wait_for_bb (base);
/* two bytes */ - writew (2, I2C_CNT); + writew (2, base + I2C_CNT); /* set slave address */ - writew (devaddr, I2C_SA); + writew (devaddr, base + I2C_SA); /* stop bit needed here */ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | - I2C_CON_STP, I2C_CON); + I2C_CON_STP, base + I2C_CON);
/* wait until state change */ - status = wait_for_pin (); + status = wait_for_pin (base);
if (status & I2C_STAT_XRDY) { #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) /* send out 1 byte */ - writeb (regoffset, I2C_DATA); - writew (I2C_STAT_XRDY, I2C_STAT); + writeb (regoffset, base + I2C_DATA); + writew (I2C_STAT_XRDY, base + I2C_STAT);
- status = wait_for_pin (); + status = wait_for_pin (base); if ((status & I2C_STAT_XRDY)) { /* send out next 1 byte */ - writeb (value, I2C_DATA); - writew (I2C_STAT_XRDY, I2C_STAT); + writeb (value, base + I2C_DATA); + writew (I2C_STAT_XRDY, base + I2C_STAT); } else { i2c_error = 1; } #else /* send out two bytes */ - writew ((value << 8) + regoffset, I2C_DATA); + writew ((value << 8) + regoffset, base + I2C_DATA); #endif /* must have enough delay to allow BB bit to go low */ udelay (50000); - if (readw (I2C_STAT) & I2C_STAT_NACK) { + if (readw (base + I2C_STAT) & I2C_STAT_NACK) { i2c_error = 1; } } else { @@ -183,96 +257,96 @@ static int i2c_write_byte (u8 devaddr, u if (!i2c_error) { int eout = 200;
- writew (I2C_CON_EN, I2C_CON); - while ((stat = readw (I2C_STAT)) || (readw (I2C_CON) & I2C_CON_MST)) { + writew (I2C_CON_EN, base + I2C_CON); + while ((stat = readw (base + I2C_STAT)) || + (readw (base + I2C_CON) & I2C_CON_MST)) { udelay (1000); /* have to read to clear intrrupt */ - writew (0xFFFF, I2C_STAT); + writew (0xFFFF, base + I2C_STAT); if(--eout == 0) /* better leave with error than hang */ break; } } - flush_fifo(); - writew (0xFFFF, I2C_STAT); - writew (0, I2C_CNT); + flush_fifo(base); + writew (0xFFFF, base + I2C_STAT); + writew (0, base + I2C_CNT); return i2c_error; }
-static void flush_fifo(void) -{ u16 stat; - - /* note: if you try and read data when its not there or ready - * you get a bus error - */ - while(1){ - stat = readw(I2C_STAT); - if(stat == I2C_STAT_RRDY){ -#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) - readb(I2C_DATA); -#else - readw(I2C_DATA); -#endif - writew(I2C_STAT_RRDY,I2C_STAT); - udelay(1000); - }else - break; - } -}
-int i2c_probe (uchar chip) +static int _i2c_probe (uchar chip, ulong base) { int res = 1; /* default = fail */
- if (chip == readw (I2C_OA)) { + if (chip == readw (base + I2C_OA)) { return res; }
/* wait until bus not busy */ - wait_for_bb (); + wait_for_bb (base);
/* try to read one byte */ - writew (1, I2C_CNT); + writew (1, base + I2C_CNT); /* set slave address */ - writew (chip, I2C_SA); + writew (chip, base + I2C_SA); /* stop bit needed here */ - writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON); + writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, base + I2C_CON); /* enough delay for the NACK bit set */ udelay (50000);
- if (!(readw (I2C_STAT) & I2C_STAT_NACK)) { + if (!(readw (base + I2C_STAT) & I2C_STAT_NACK)) { res = 0; /* success case */ - flush_fifo(); - writew(0xFFFF, I2C_STAT); + flush_fifo(base); + writew(0xFFFF, base + I2C_STAT); } else { - writew(0xFFFF, I2C_STAT); /* failue, clear sources*/ - writew (readw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */ + writew(0xFFFF, base + I2C_STAT); /* failure, clear sources*/ + writew (readw (base + I2C_CON) | I2C_CON_STP, base + I2C_CON); /* finish up xfer */ udelay(20000); - wait_for_bb (); + wait_for_bb (base); } - flush_fifo(); - writew (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/ - writew(0xFFFF, I2C_STAT); + flush_fifo(base); + writew (0, base + I2C_CNT); /* don't allow any more data in...we don't want it.*/ + writew(0xFFFF, base + I2C_STAT); return res; }
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) + +static void omap24xx_i2c_init (int speed, int slaveadd) +{ + _i2c_init(speed, slaveadd, CONFIG_SYS_OMAP24XX_I2C_BASE); + + if (gd->flags & GD_FLG_RELOC) { + omap24xx_i2c_adap[0].speed = speed; + omap24xx_i2c_adap[0].slaveaddr = slaveadd; + omap24xx_i2c_adap[0].init_done = 1; + } +} + +static int omap24xx_i2c_probe (uchar chip) +{ + return(_i2c_probe(chip, CONFIG_SYS_OMAP24XX_I2C_BASE)); +} + +static int omap24xx_i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { int i;
if (alen > 1) { - printf ("I2C read: addr len %d not supported\n", alen); + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); return 1; }
if (addr + len > 256) { - printf ("I2C read: address out of range\n"); + printf ("%s: address out of range\n", __FUNCTION__); return 1; }
for (i = 0; i < len; i++) { - if (i2c_read_byte (chip, addr + i, &buffer[i])) { - printf ("I2C read: I/O error\n"); - i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + if (i2c_read_byte (chip, addr + i, &buffer[i], CONFIG_SYS_OMAP24XX_I2C_BASE)) { + printf ("%s: I/O error\n", __FUNCTION__); + _i2c_init (CONFIG_SYS_OMAP24XX_I2C_SPEED, + CONFIG_SYS_OMAP24XX_I2C_SLAVE, + CONFIG_SYS_OMAP24XX_I2C_BASE); return 1; } } @@ -280,24 +354,26 @@ int i2c_read (uchar chip, uint addr, int return 0; }
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) +static int omap24xx_i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) { int i;
if (alen > 1) { - printf ("I2C read: addr len %d not supported\n", alen); + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); return 1; }
if (addr + len > 256) { - printf ("I2C read: address out of range\n"); + printf ("%s: address out of range\n", __FUNCTION__); return 1; }
for (i = 0; i < len; i++) { - if (i2c_write_byte (chip, addr + i, buffer[i])) { - printf ("I2C read: I/O error\n"); - i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + if (i2c_write_byte (chip, addr + i, buffer[i], CONFIG_SYS_OMAP24XX_I2C_BASE)) { + printf ("%s: I/O error\n", __FUNCTION__); + _i2c_init (CONFIG_SYS_OMAP24XX_I2C_SPEED, + CONFIG_SYS_OMAP24XX_I2C_SLAVE, + CONFIG_SYS_OMAP24XX_I2C_BASE); return 1; } } @@ -305,41 +381,219 @@ int i2c_write (uchar chip, uint addr, in return 0; }
-static void wait_for_bb (void) +static unsigned int omap24xx_i2c_set_bus_speed(unsigned int speed) { - int timeout = 10; - u16 stat; + return(omap24xx_i2c_adap[0].speed); +}
- writew(0xFFFF, I2C_STAT); /* clear current interruts...*/ - while ((stat = readw (I2C_STAT) & I2C_STAT_BB) && timeout--) { - writew (stat, I2C_STAT); - udelay (50000); +static unsigned int omap24xx_i2c_get_bus_speed(void) +{ + return(omap24xx_i2c_adap[0].speed); +} + +#ifdef CONFIG_SYS_OMAP24XX_I2C2_BASE +static void omap24xx_i2c2_init (int speed, int slaveadd) +{ + _i2c_init(speed, slaveadd, CONFIG_SYS_OMAP24XX_I2C2_BASE); + + if (gd->flags & GD_FLG_RELOC) { + omap24xx_i2c_adap[1].speed = speed; + omap24xx_i2c_adap[1].slaveaddr = slaveadd; + omap24xx_i2c_adap[1].init_done = 1; + } +} + +static int omap24xx_i2c2_probe (uchar chip) +{ + return(_i2c_probe(chip, CONFIG_SYS_OMAP24XX_I2C2_BASE)); +} + +static int omap24xx_i2c2_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ + int i; + + if (alen > 1) { + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); + return 1; }
- if (timeout <= 0) { - printf ("timed out in wait_for_bb: I2C_STAT=%x\n", - readw (I2C_STAT)); + if (addr + len > 256) { + printf ("%s: address out of range\n", __FUNCTION__); + return 1; + } + + for (i = 0; i < len; i++) { + if (i2c_read_byte (chip, addr + i, &buffer[i], CONFIG_SYS_OMAP24XX_I2C2_BASE)) { + printf ("%s: I/O error\n", __FUNCTION__); + _i2c_init (CONFIG_SYS_OMAP24XX_I2C2_SPEED, + CONFIG_SYS_OMAP24XX_I2C2_SLAVE, + CONFIG_SYS_OMAP24XX_I2C2_BASE); + return 1; + } } - writew(0xFFFF, I2C_STAT); /* clear delayed stuff*/ + + return 0; }
-static u16 wait_for_pin (void) +static int omap24xx_i2c2_write (uchar chip, uint addr, int alen, uchar * buffer, int len) { - u16 status; - int timeout = 10; + int i;
- do { - udelay (1000); - status = readw (I2C_STAT); - } while ( !(status & - (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | - I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | - I2C_STAT_AL)) && timeout--); + if (alen > 1) { + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); + return 1; + }
- if (timeout <= 0) { - printf ("timed out in wait_for_pin: I2C_STAT=%x\n", - readw (I2C_STAT)); - writew(0xFFFF, I2C_STAT); + if (addr + len > 256) { + printf ("%s: address out of range\n", __FUNCTION__); + return 1; + } + + for (i = 0; i < len; i++) { + if (i2c_write_byte (chip, addr + i, buffer[i], CONFIG_SYS_OMAP24XX_I2C2_BASE)) { + printf ("%s: I/O error\n", __FUNCTION__); + _i2c_init (CONFIG_SYS_OMAP24XX_I2C2_SPEED, + CONFIG_SYS_OMAP24XX_I2C2_SLAVE, + CONFIG_SYS_OMAP24XX_I2C2_BASE); + return 1; + } + } + + return 0; } - return status; + +static unsigned int omap24xx_i2c2_set_bus_speed(unsigned int speed) +{ + return(omap24xx_i2c_adap[1].speed); +} + +static unsigned int omap24xx_i2c2_get_bus_speed(void) +{ + return(omap24xx_i2c_adap[1].speed); +} +#endif + +#ifdef CONFIG_SYS_OMAP24XX_I2C3_BASE +static void omap24xx_i2c3_init (int speed, int slaveadd) +{ + _i2c_init(speed, slaveadd, CONFIG_SYS_OMAP24XX_I2C3_BASE); + + if (gd->flags & GD_FLG_RELOC) { + omap24xx_i2c_adap[2].speed = speed; + omap24xx_i2c_adap[2].slaveaddr = slaveadd; + omap24xx_i2c_adap[2].init_done = 1; + } +} + +static int omap24xx_i2c3_probe (uchar chip) +{ + return(_i2c_probe(chip, CONFIG_SYS_OMAP24XX_I2C3_BASE)); } + +static int omap24xx_i2c3_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ + int i; + + if (alen > 1) { + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); + return 1; + } + + if (addr + len > 256) { + printf ("%s: address out of range\n", __FUNCTION__); + return 1; + } + + for (i = 0; i < len; i++) { + if (i2c_read_byte (chip, addr + i, &buffer[i], CONFIG_SYS_OMAP24XX_I2C3_BASE)) { + printf ("%s: I/O error\n", __FUNCTION__); + _i2c_init (CONFIG_SYS_OMAP24XX_I2C3_SPEED, + CONFIG_SYS_OMAP24XX_I2C3_SLAVE, + CONFIG_SYS_OMAP24XX_I2C3_BASE); + return 1; + } + } + + return 0; +} + +static int omap24xx_i2c3_write (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ + int i; + + if (alen > 1) { + printf ("%s: addr len %d not supported\n", __FUNCTION__, alen); + return 1; + } + + if (addr + len > 256) { + printf ("%s: address out of range\n", __FUNCTION__); + return 1; + } + + for (i = 0; i < len; i++) { + if (i2c_write_byte (chip, addr + i, buffer[i], CONFIG_SYS_OMAP24XX_I2C3_BASE)) { + printf ("%s: I/O error\n", __FUNCTION__); + _i2c_init (CONFIG_SYS_OMAP24XX_I2C3_SPEED, + CONFIG_SYS_OMAP24XX_I2C3_SLAVE, + CONFIG_SYS_OMAP24XX_I2C3_BASE); + return 1; + } + } + + return 0; +} + +static unsigned int omap24xx_i2c3_set_bus_speed(unsigned int speed) +{ + return(omap24xx_i2c_adap[2].speed); +} + +static unsigned int omap24xx_i2c3_get_bus_speed(void) +{ + return(omap24xx_i2c_adap[2].speed); +} +#endif + +i2c_adap_t omap24xx_i2c_adap[3] = { + { + .init = omap24xx_i2c_init, + .probe = omap24xx_i2c_probe, + .read = omap24xx_i2c_read, + .write = omap24xx_i2c_write, + .set_bus_speed = omap24xx_i2c_set_bus_speed, + .get_bus_speed = omap24xx_i2c_get_bus_speed, + .speed = CONFIG_SYS_OMAP24XX_I2C_SPEED, + .slaveaddr = CONFIG_SYS_OMAP24XX_I2C_SLAVE, + .init_done = 0, + .name = OMAP24XX_NAME(CONFIG_SYS_OMAP24XX_I2C_BASE) + }, +#ifdef CONFIG_SYS_OMAP24XX_I2C2_BASE + { + .init = omap24xx_i2c2_init, + .probe = omap24xx_i2c2_probe, + .read = omap24xx_i2c2_read, + .write = omap24xx_i2c2_write, + .set_bus_speed = omap24xx_i2c2_set_bus_speed, + .get_bus_speed = omap24xx_i2c2_get_bus_speed, + .speed = CONFIG_SYS_OMAP24XX_I2C2_SPEED, + .slaveaddr = CONFIG_SYS_OMAP24XX_I2C2_SLAVE, + .init_done = 0, + .name = OMAP24XX_NAME(CONFIG_SYS_OMAP24XX_I2C2_BASE) + }, +#endif +#ifdef CONFIG_SYS_OMAP24XX_I2C3_BASE + { + .init = omap24xx_i2c3_init, + .probe = omap24xx_i2c3_probe, + .read = omap24xx_i2c3_read, + .write = omap24xx_i2c3_write, + .set_bus_speed = omap24xx_i2c3_set_bus_speed, + .get_bus_speed = omap24xx_i2c3_get_bus_speed, + .speed = CONFIG_SYS_OMAP24XX_I2C3_SPEED, + .slaveaddr = CONFIG_SYS_OMAP24XX_I2C3_SLAVE, + .init_done = 0, + .name = OMAP24XX_NAME(CONFIG_SYS_OMAP24XX_I2C3_BASE) + } +#endif +}; diff -purN u-boot-i2c.orig/drivers/i2c/tsi108_i2c.c u-boot-i2c/drivers/i2c/tsi108_i2c.c --- u-boot-i2c.orig/drivers/i2c/tsi108_i2c.c 2009-02-12 10:43:41.000000000 -0800 +++ u-boot-i2c/drivers/i2c/tsi108_i2c.c 2009-02-12 10:46:00.000000000 -0800 @@ -1,4 +1,8 @@ /* + * Copyright (c) 2009 Sergey Kubushyn ksi@koi8.net + * + * Changes for multibus/multiadapter I2C support. + * * (C) Copyright 2004 Tundra Semiconductor Corp. * Author: Alex Bounine * @@ -26,8 +30,7 @@ #include <common.h>
#include <tsi108.h> - -#if defined(CONFIG_CMD_I2C) +#include <i2c.h>
#define I2C_DELAY 100000 #undef DEBUG_I2C @@ -38,6 +41,8 @@ #define DPRINT(x) #endif
+i2c_adap_t tsi108_i2c_adap; + /* All functions assume that Tsi108 I2C block is the only master on the bus */ /* I2C read helper function */
@@ -132,7 +137,7 @@ static int i2c_read_byte ( * Returns: 0 on success, not 0 on failure */
-int i2c_read (uchar chip_addr, uint byte_addr, int alen, +static int tsi108_i2c_read (uchar chip_addr, uint byte_addr, int alen, uchar * buffer, int len) { u32 op_status = TSI108_I2C_PARAM_ERR; @@ -238,7 +243,7 @@ static int i2c_write_byte (uchar chip_ad * Returns: 0 on success, not 0 on failure */
-int i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer, +static int tsi108_i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer, int len) { u32 op_status = TSI108_I2C_PARAM_ERR; @@ -266,7 +271,7 @@ int i2c_write (uchar chip_addr, uint byt * Returns 0 if a chip responded, not 0 on failure. */
-int i2c_probe (uchar chip) +static int tsi108_i2c_probe (uchar chip) { u32 tmp;
@@ -278,4 +283,31 @@ int i2c_probe (uchar chip) return i2c_read (chip, 0, 1, (uchar *)&tmp, 1); }
-#endif +static unsigned int tsi108_i2c_set_bus_speed(unsigned int speed) +{ + return(tsi108_i2c_adap.speed); +} + +static unsigned int tsi108_i2c_get_bus_speed(void) +{ + return(tsi108_i2c_adap.speed); +} + +static void tsi108_i2c_init(int speed, int slaveaddr) +{ + /* Dummy */ +} + +i2c_adap_t tsi108_i2c_adap = { + .init = tsi108_i2c_init, + .probe = tsi108_i2c_probe, + .read = tsi108_i2c_read, + .write = tsi108_i2c_write, + .set_bus_speed = tsi108_i2c_set_bus_speed, + .get_bus_speed = tsi108_i2c_get_bus_speed, + .speed = CONFIG_SYS_TSI108_I2C_SPEED, + .slaveaddr = CONFIG_SYS_TSI108_I2C_SLAVE, + .init_done = 0, + .name = "tsi108_i2c" +}; + diff -purN u-boot-i2c.orig/include/asm-arm/arch-omap24xx/i2c.h u-boot-i2c/include/asm-arm/arch-omap24xx/i2c.h --- u-boot-i2c.orig/include/asm-arm/arch-omap24xx/i2c.h 2009-02-12 10:43:41.000000000 -0800 +++ u-boot-i2c/include/asm-arm/arch-omap24xx/i2c.h 2009-02-12 10:46:00.000000000 -0800 @@ -23,24 +23,24 @@ #ifndef _OMAP24XX_I2C_H_ #define _OMAP24XX_I2C_H_
-#define I2C_BASE 0x48070000 +#define I2C_BASE1 0x48070000 #define I2C_BASE2 0x48072000 /* nothing hooked up on h4 */
-#define I2C_REV (I2C_BASE + 0x00) -#define I2C_IE (I2C_BASE + 0x04) -#define I2C_STAT (I2C_BASE + 0x08) -#define I2C_IV (I2C_BASE + 0x0c) -#define I2C_BUF (I2C_BASE + 0x14) -#define I2C_CNT (I2C_BASE + 0x18) -#define I2C_DATA (I2C_BASE + 0x1c) -#define I2C_SYSC (I2C_BASE + 0x20) -#define I2C_CON (I2C_BASE + 0x24) -#define I2C_OA (I2C_BASE + 0x28) -#define I2C_SA (I2C_BASE + 0x2c) -#define I2C_PSC (I2C_BASE + 0x30) -#define I2C_SCLL (I2C_BASE + 0x34) -#define I2C_SCLH (I2C_BASE + 0x38) -#define I2C_SYSTEST (I2C_BASE + 0x3c) +#define I2C_REV (0x00) +#define I2C_IE (0x04) +#define I2C_STAT (0x08) +#define I2C_IV (0x0c) +#define I2C_BUF (0x14) +#define I2C_CNT (0x18) +#define I2C_DATA (0x1c) +#define I2C_SYSC (0x20) +#define I2C_CON (0x24) +#define I2C_OA (0x28) +#define I2C_SA (0x2c) +#define I2C_PSC (0x30) +#define I2C_SCLL (0x34) +#define I2C_SCLH (0x38) +#define I2C_SYSTEST (0x3c)
/* I2C masks */
diff -purN u-boot-i2c.orig/include/asm-arm/arch-omap3/i2c.h u-boot-i2c/include/asm-arm/arch-omap3/i2c.h --- u-boot-i2c.orig/include/asm-arm/arch-omap3/i2c.h 2009-02-12 10:43:41.000000000 -0800 +++ u-boot-i2c/include/asm-arm/arch-omap3/i2c.h 2009-02-12 10:46:00.000000000 -0800 @@ -20,26 +20,24 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ -#ifndef _I2C_H_ -#define _I2C_H_ +#ifndef _OMAP3_I2C_H_ +#define _OMAP3_I2C_H_
-#define I2C_DEFAULT_BASE I2C_BASE1 - -#define I2C_REV (I2C_DEFAULT_BASE + 0x00) -#define I2C_IE (I2C_DEFAULT_BASE + 0x04) -#define I2C_STAT (I2C_DEFAULT_BASE + 0x08) -#define I2C_IV (I2C_DEFAULT_BASE + 0x0c) -#define I2C_BUF (I2C_DEFAULT_BASE + 0x14) -#define I2C_CNT (I2C_DEFAULT_BASE + 0x18) -#define I2C_DATA (I2C_DEFAULT_BASE + 0x1c) -#define I2C_SYSC (I2C_DEFAULT_BASE + 0x20) -#define I2C_CON (I2C_DEFAULT_BASE + 0x24) -#define I2C_OA (I2C_DEFAULT_BASE + 0x28) -#define I2C_SA (I2C_DEFAULT_BASE + 0x2c) -#define I2C_PSC (I2C_DEFAULT_BASE + 0x30) -#define I2C_SCLL (I2C_DEFAULT_BASE + 0x34) -#define I2C_SCLH (I2C_DEFAULT_BASE + 0x38) -#define I2C_SYSTEST (I2C_DEFAULT_BASE + 0x3c) +#define I2C_REV (0x00) +#define I2C_IE (0x04) +#define I2C_STAT (0x08) +#define I2C_IV (0x0c) +#define I2C_BUF (0x14) +#define I2C_CNT (0x18) +#define I2C_DATA (0x1c) +#define I2C_SYSC (0x20) +#define I2C_CON (0x24) +#define I2C_OA (0x28) +#define I2C_SA (0x2c) +#define I2C_PSC (0x30) +#define I2C_SCLL (0x34) +#define I2C_SCLH (0x38) +#define I2C_SYSTEST (0x3c)
/* I2C masks */
@@ -125,4 +123,4 @@ #define I2C_PSC_MAX 0x0f #define I2C_PSC_MIN 0x00
-#endif /* _I2C_H_ */ +#endif /* _OMAP3_I2C_H_ */

Hello ksi
ksi@koi8.net wrote:
Signed-off-by: Sergey Kubushyn ksi@koi8.net
Patch apply with warnings:
Applying: 5/12 Multiadapter/multibus I2C, drivers part 2 /home/hs/i2c/u-boot-i2c/.git/rebase-apply/patch:698: trailing whitespace. #ifdef CONFIG_SYS_OMAP24XX_I2C2_BASE /home/hs/i2c/u-boot-i2c/.git/rebase-apply/patch:799: trailing whitespace. #ifdef CONFIG_SYS_OMAP24XX_I2C3_BASE /home/hs/i2c/u-boot-i2c/.git/rebase-apply/patch:894: trailing whitespace. #ifdef CONFIG_SYS_OMAP24XX_I2C2_BASE /home/hs/i2c/u-boot-i2c/.git/rebase-apply/patch:908: trailing whitespace. #ifdef CONFIG_SYS_OMAP24XX_I2C3_BASE /home/hs/i2c/u-boot-i2c/.git/rebase-apply/patch:1013: trailing whitespace.
warning: 5 lines add whitespace errors.
please fix bye Heiko

On 14:20 Thu 12 Feb , ksi@koi8.net wrote:
Signed-off-by: Sergey Kubushyn ksi@koi8.net
btw retrun is not a function
Best Regards, J.

Dear ksi@koi8.net,
In message Pine.LNX.4.64ksi.0902121417310.21067@home-gw.koi8.net you wrote:
...
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +static int omap1510_i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { int i;
if (alen > 1) {
printf ("I2C read: addr len %d not supported\n", alen);
printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
return 1; }
if (addr + len > 256) {
printf ("I2C read: address out of range\n");
printf ("%s: address out of range\n", __FUNCTION__);
These are changes really to the worse: instead of
I2C read: address out of range
we now get
omap1510_i2c_read: address out of range
More difficult to read, higher memory footprint.
Please revert this.
Best regards,
Wolfgang Denk

On Mon, 16 Feb 2009, Wolfgang Denk wrote:
Dear ksi@koi8.net,
In message Pine.LNX.4.64ksi.0902121417310.21067@home-gw.koi8.net you wrote:
...
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +static int omap1510_i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) { int i;
if (alen > 1) {
printf ("I2C read: addr len %d not supported\n", alen);
printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
return 1; }
if (addr + len > 256) {
printf ("I2C read: address out of range\n");
printf ("%s: address out of range\n", __FUNCTION__);
These are changes really to the worse: instead of
I2C read: address out of range
we now get
omap1510_i2c_read: address out of range
More difficult to read, higher memory footprint.
Please revert this.
No problems, will do.
--- ****************************************************************** * KSI@home KOI8 Net < > The impossible we do immediately. * * Las Vegas NV, USA < > Miracles require 24-hour notice. * ******************************************************************
participants (4)
-
Heiko Schocher
-
Jean-Christophe PLAGNIOL-VILLARD
-
ksi@koi8.net
-
Wolfgang Denk