[FE training-materials-updates] Add patch to fix I2C issue with U-Boot 2013.10
Thomas Petazzoni
thomas.petazzoni at free-electrons.com
Wed Nov 27 15:55:23 CET 2013
Repository : git://git.free-electrons.com/training-materials.git
On branch : master
Link : http://git.free-electrons.com/training-materials/commit/?id=214721504a37b7e3ed978488f9776c3a139f4b65
>---------------------------------------------------------------
commit 214721504a37b7e3ed978488f9776c3a139f4b65
Author: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
Date: Wed Nov 27 15:51:33 2013 +0100
Add patch to fix I2C issue with U-Boot 2013.10
Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
>---------------------------------------------------------------
214721504a37b7e3ed978488f9776c3a139f4b65
...OMAP-I2C-New-read-write-and-probe-functio.patch | 664 ++++++++++++++++++++
1 file changed, 664 insertions(+)
diff --git a/lab-data/sysdev/bootloader/data/0001-Revert-ARM-OMAP-I2C-New-read-write-and-probe-functio.patch b/lab-data/sysdev/bootloader/data/0001-Revert-ARM-OMAP-I2C-New-read-write-and-probe-functio.patch
new file mode 100644
index 0000000..107ae78
--- /dev/null
+++ b/lab-data/sysdev/bootloader/data/0001-Revert-ARM-OMAP-I2C-New-read-write-and-probe-functio.patch
@@ -0,0 +1,664 @@
+From 9413ec0ce7afbc9eba7fe26ad8527d4231a65fbd Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
+Date: Wed, 27 Nov 2013 10:48:45 +0100
+Subject: [PATCH] Revert "ARM: OMAP: I2C: New read, write and probe functions"
+
+This reverts commit 960187ffa125b3938fec4b827bd9e8c04a204af8.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
+---
+ drivers/i2c/omap24xx_i2c.c | 490 ++++++++++++++++++---------------------------
+ 1 file changed, 191 insertions(+), 299 deletions(-)
+
+diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
+index ef38d71..54e9b15 100644
+--- a/drivers/i2c/omap24xx_i2c.c
++++ b/drivers/i2c/omap24xx_i2c.c
+@@ -18,20 +18,6 @@
+ *
+ * Adapted for OMAP2420 I2C, r-woodruff2 at ti.com
+ *
+- * Copyright (c) 2013 Lubomir Popov <lpopov at mm-sol.com>, MM Solutions
+- * New i2c_read, i2c_write and i2c_probe functions, tested on OMAP4
+- * (4430/60/70), OMAP5 (5430) and AM335X (3359); should work on older
+- * OMAPs and derivatives as well. The only anticipated exception would
+- * be the OMAP2420, which shall require driver modification.
+- * - Rewritten i2c_read to operate correctly with all types of chips
+- * (old function could not read consistent data from some I2C slaves).
+- * - Optimized i2c_write.
+- * - New i2c_probe, performs write access vs read. The old probe could
+- * hang the system under certain conditions (e.g. unconfigured pads).
+- * - The read/write/probe functions try to identify unconfigured bus.
+- * - Status functions now read irqstatus_raw as per TRM guidelines
+- * (except for OMAP243X and OMAP34XX).
+- * - Driver now supports up to I2C5 (OMAP5).
+ */
+
+ #include <common.h>
+@@ -45,11 +31,8 @@ DECLARE_GLOBAL_DATA_PTR;
+
+ #define I2C_TIMEOUT 1000
+
+-/* Absolutely safe for status update at 100 kHz I2C: */
+-#define I2C_WAIT 200
+-
+ static int wait_for_bb(void);
+-static u16 wait_for_event(void);
++static u16 wait_for_pin(void);
+ static void flush_fifo(void);
+
+ /*
+@@ -154,14 +137,10 @@ void i2c_init(int speed, int slaveadd)
+ /* own address */
+ writew(slaveadd, &i2c_base->oa);
+ writew(I2C_CON_EN, &i2c_base->con);
+-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+- /*
+- * Have to enable interrupts for OMAP2/3, these IPs don't have
+- * an 'irqstatus_raw' register and we shall have to poll 'stat'
+- */
++
++ /* 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_base->ie);
+-#endif
++ I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
+ udelay(1000);
+ flush_fifo();
+ writew(0xFFFF, &i2c_base->stat);
+@@ -171,6 +150,88 @@ void i2c_init(int speed, int slaveadd)
+ bus_initialized[current_bus] = 1;
+ }
+
++static int i2c_read_byte(u8 devaddr, u16 regoffset, u8 alen, u8 *value)
++{
++ int i2c_error = 0;
++ u16 status;
++ int i = 2 - alen;
++ u8 tmpbuf[2] = {(regoffset) >> 8, regoffset & 0xff};
++ u16 w;
++
++ /* wait until bus not busy */
++ if (wait_for_bb())
++ return 1;
++
++ /* one byte only */
++ writew(alen, &i2c_base->cnt);
++ /* set slave address */
++ writew(devaddr, &i2c_base->sa);
++ /* no stop bit needed here */
++ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
++ I2C_CON_TRX, &i2c_base->con);
++
++ /* send register offset */
++ while (1) {
++ status = wait_for_pin();
++ if (status == 0 || status & I2C_STAT_NACK) {
++ i2c_error = 1;
++ goto read_exit;
++ }
++ if (status & I2C_STAT_XRDY) {
++ w = tmpbuf[i++];
++#if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
++ defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
++ defined(CONFIG_OMAP54XX))
++ w |= tmpbuf[i++] << 8;
++#endif
++ writew(w, &i2c_base->data);
++ writew(I2C_STAT_XRDY, &i2c_base->stat);
++ }
++ if (status & I2C_STAT_ARDY) {
++ writew(I2C_STAT_ARDY, &i2c_base->stat);
++ break;
++ }
++ }
++
++ /* set slave address */
++ writew(devaddr, &i2c_base->sa);
++ /* read one byte from slave */
++ writew(1, &i2c_base->cnt);
++ /* need stop bit here */
++ writew(I2C_CON_EN | I2C_CON_MST |
++ I2C_CON_STT | I2C_CON_STP,
++ &i2c_base->con);
++
++ /* receive data */
++ while (1) {
++ status = wait_for_pin();
++ if (status == 0 || status & I2C_STAT_NACK) {
++ i2c_error = 1;
++ goto read_exit;
++ }
++ if (status & I2C_STAT_RRDY) {
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
++ defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
++ defined(CONFIG_OMAP54XX)
++ *value = readb(&i2c_base->data);
++#else
++ *value = readw(&i2c_base->data);
++#endif
++ writew(I2C_STAT_RRDY, &i2c_base->stat);
++ }
++ if (status & I2C_STAT_ARDY) {
++ writew(I2C_STAT_ARDY, &i2c_base->stat);
++ break;
++ }
++ }
++
++read_exit:
++ flush_fifo();
++ writew(0xFFFF, &i2c_base->stat);
++ writew(0, &i2c_base->cnt);
++ return i2c_error;
++}
++
+ static void flush_fifo(void)
+ { u16 stat;
+
+@@ -180,7 +241,13 @@ static void flush_fifo(void)
+ while (1) {
+ stat = readw(&i2c_base->stat);
+ if (stat == I2C_STAT_RRDY) {
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
++ defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
++ defined(CONFIG_OMAP54XX)
+ readb(&i2c_base->data);
++#else
++ readw(&i2c_base->data);
++#endif
+ writew(I2C_STAT_RRDY, &i2c_base->stat);
+ udelay(1000);
+ } else
+@@ -188,10 +255,6 @@ static void flush_fifo(void)
+ }
+ }
+
+-/*
+- * i2c_probe: Use write access. Allows to identify addresses that are
+- * write-only (like the config register of dual-port EEPROMs)
+- */
+ int i2c_probe(uchar chip)
+ {
+ u16 status;
+@@ -200,81 +263,61 @@ int i2c_probe(uchar chip)
+ if (chip == readw(&i2c_base->oa))
+ return res;
+
+- /* Wait until bus is free */
++ /* wait until bus not busy */
+ if (wait_for_bb())
+ return res;
+
+- /* No data transfer, slave addr only */
+- writew(0, &i2c_base->cnt);
+- /* Set slave address */
++ /* try to read one byte */
++ writew(1, &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 |
+- I2C_CON_STP, &i2c_base->con);
+-
+- status = wait_for_event();
+-
+- if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) {
+- /*
+- * With current high-level command implementation, notifying
+- * the user shall flood the console with 127 messages. If
+- * silent exit is desired upon unconfigured bus, remove the
+- * following 'if' section:
+- */
+- if (status == I2C_STAT_XRDY)
+- printf("i2c_probe: pads on bus %d probably not configured (status=0x%x)\n",
+- current_bus, status);
+-
+- goto pr_exit;
+- }
++ /* stop bit needed here */
++ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, &i2c_base->con);
+
+- /* Check for ACK (!NAK) */
+- if (!(status & I2C_STAT_NACK)) {
+- res = 0; /* Device found */
+- udelay(I2C_WAIT); /* Required by AM335X in SPL */
+- /* Abort transfer (force idle state) */
+- writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */
+- udelay(1000);
+- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX |
+- I2C_CON_STP, &i2c_base->con); /* STP */
++ while (1) {
++ status = wait_for_pin();
++ if (status == 0 || status & I2C_STAT_AL) {
++ res = 1;
++ goto probe_exit;
++ }
++ if (status & I2C_STAT_NACK) {
++ res = 1;
++ writew(0xff, &i2c_base->stat);
++ writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con);
++
++ if (wait_for_bb())
++ res = 1;
++
++ break;
++ }
++ if (status & I2C_STAT_ARDY) {
++ writew(I2C_STAT_ARDY, &i2c_base->stat);
++ break;
++ }
++ if (status & I2C_STAT_RRDY) {
++ res = 0;
++#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
++ defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
++ defined(CONFIG_OMAP54XX)
++ readb(&i2c_base->data);
++#else
++ readw(&i2c_base->data);
++#endif
++ writew(I2C_STAT_RRDY, &i2c_base->stat);
++ }
+ }
+-pr_exit:
++
++probe_exit:
+ flush_fifo();
+- writew(0xFFFF, &i2c_base->stat);
++ /* don't allow any more data in... we don't want it. */
+ writew(0, &i2c_base->cnt);
++ writew(0xFFFF, &i2c_base->stat);
+ return res;
+ }
+
+-/*
+- * i2c_read: Function now uses a single I2C read transaction with bulk transfer
+- * of the requested number of bytes (note that the 'i2c md' command
+- * limits this to 16 bytes anyway). If CONFIG_I2C_REPEATED_START is
+- * defined in the board config header, this transaction shall be with
+- * Repeated Start (Sr) between the address and data phases; otherwise
+- * Stop-Start (P-S) shall be used (some I2C chips do require a P-S).
+- * The address (reg offset) may be 0, 1 or 2 bytes long.
+- * Function now reads correctly from chips that return more than one
+- * byte of data per addressed register (like TI temperature sensors),
+- * or that do not need a register address at all (such as some clock
+- * distributors).
+- */
+ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+ {
+- int i2c_error = 0;
+- u16 status;
+-
+- if (alen < 0) {
+- puts("I2C read: addr len < 0\n");
+- return 1;
+- }
+- if (len < 0) {
+- puts("I2C read: data len < 0\n");
+- return 1;
+- }
+- if (buffer == NULL) {
+- puts("I2C read: NULL pointer passed\n");
+- return 1;
+- }
++ int i;
+
+ if (alen > 2) {
+ printf("I2C read: addr len %d not supported\n", alen);
+@@ -286,122 +329,24 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+ return 1;
+ }
+
+- /* Wait until bus not busy */
+- if (wait_for_bb())
+- return 1;
+-
+- /* Zero, one or two bytes reg address (offset) */
+- writew(alen, &i2c_base->cnt);
+- /* Set slave address */
+- writew(chip, &i2c_base->sa);
+-
+- if (alen) {
+- /* Must write reg offset first */
+-#ifdef CONFIG_I2C_REPEATED_START
+- /* No stop bit, use Repeated Start (Sr) */
+- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
+- I2C_CON_TRX, &i2c_base->con);
+-#else
+- /* Stop - Start (P-S) */
+- writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP |
+- I2C_CON_TRX, &i2c_base->con);
+-#endif
+- /* Send register offset */
+- while (1) {
+- status = wait_for_event();
+- /* Try to identify bus that is not padconf'd for I2C */
+- if (status == I2C_STAT_XRDY) {
+- i2c_error = 2;
+- printf("i2c_read (addr phase): pads on bus %d probably not configured (status=0x%x)\n",
+- current_bus, status);
+- goto rd_exit;
+- }
+- if (status == 0 || status & I2C_STAT_NACK) {
+- i2c_error = 1;
+- printf("i2c_read: error waiting for addr ACK (status=0x%x)\n",
+- status);
+- goto rd_exit;
+- }
+- if (alen) {
+- if (status & I2C_STAT_XRDY) {
+- alen--;
+- /* Do we have to use byte access? */
+- writeb((addr >> (8 * alen)) & 0xff,
+- &i2c_base->data);
+- writew(I2C_STAT_XRDY, &i2c_base->stat);
+- }
+- }
+- if (status & I2C_STAT_ARDY) {
+- writew(I2C_STAT_ARDY, &i2c_base->stat);
+- break;
+- }
+- }
+- }
+- /* Set slave address */
+- writew(chip, &i2c_base->sa);
+- /* Read len bytes from slave */
+- writew(len, &i2c_base->cnt);
+- /* Need stop bit here */
+- writew(I2C_CON_EN | I2C_CON_MST |
+- I2C_CON_STT | I2C_CON_STP,
+- &i2c_base->con);
+-
+- /* Receive data */
+- while (1) {
+- status = wait_for_event();
+- /*
+- * Try to identify bus that is not padconf'd for I2C. This
+- * state could be left over from previous transactions if
+- * the address phase is skipped due to alen=0.
+- */
+- if (status == I2C_STAT_XRDY) {
+- i2c_error = 2;
+- printf("i2c_read (data phase): pads on bus %d probably not configured (status=0x%x)\n",
+- current_bus, status);
+- goto rd_exit;
+- }
+- if (status == 0 || status & I2C_STAT_NACK) {
+- i2c_error = 1;
+- goto rd_exit;
+- }
+- if (status & I2C_STAT_RRDY) {
+- *buffer++ = readb(&i2c_base->data);
+- writew(I2C_STAT_RRDY, &i2c_base->stat);
+- }
+- if (status & I2C_STAT_ARDY) {
+- writew(I2C_STAT_ARDY, &i2c_base->stat);
+- break;
++ for (i = 0; i < len; i++) {
++ if (i2c_read_byte(chip, addr + i, alen, &buffer[i])) {
++ puts("I2C read: I/O error\n");
++ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
++ return 1;
+ }
+ }
+
+-rd_exit:
+- flush_fifo();
+- writew(0xFFFF, &i2c_base->stat);
+- writew(0, &i2c_base->cnt);
+- return i2c_error;
++ return 0;
+ }
+
+-/* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */
+ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+ {
+ int i;
+ u16 status;
+ int i2c_error = 0;
+-
+- if (alen < 0) {
+- puts("I2C write: addr len < 0\n");
+- return 1;
+- }
+-
+- if (len < 0) {
+- puts("I2C write: data len < 0\n");
+- return 1;
+- }
+-
+- if (buffer == NULL) {
+- puts("I2C write: NULL pointer passed\n");
+- return 1;
+- }
++ u16 w;
++ u8 tmpbuf[2] = {addr >> 8, addr & 0xff};
+
+ if (alen > 2) {
+ printf("I2C write: addr len %d not supported\n", alen);
+@@ -410,137 +355,92 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+
+ if (addr + len > (1 << 16)) {
+ printf("I2C write: address 0x%x + 0x%x out of range\n",
+- addr, len);
++ addr, len);
+ return 1;
+ }
+
+- /* Wait until bus not busy */
++ /* wait until bus not busy */
+ if (wait_for_bb())
+ return 1;
+
+- /* Start address phase - will write regoffset + len bytes data */
++ /* start address phase - will write regoffset + len bytes data */
++ /* TODO consider case when !CONFIG_OMAP243X/34XX/44XX */
+ writew(alen + len, &i2c_base->cnt);
+- /* Set slave address */
++ /* set slave address */
+ writew(chip, &i2c_base->sa);
+- /* Stop bit needed here */
++ /* stop bit needed here */
+ writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
+- I2C_CON_STP, &i2c_base->con);
+-
+- while (alen) {
+- /* Must write reg offset (one or two bytes) */
+- status = wait_for_event();
+- /* Try to identify bus that is not padconf'd for I2C */
+- if (status == I2C_STAT_XRDY) {
+- i2c_error = 2;
+- printf("i2c_write: pads on bus %d probably not configured (status=0x%x)\n",
+- current_bus, status);
+- goto wr_exit;
+- }
+- if (status == 0 || status & I2C_STAT_NACK) {
+- i2c_error = 1;
+- printf("i2c_write: error waiting for addr ACK (status=0x%x)\n",
+- status);
+- goto wr_exit;
+- }
+- if (status & I2C_STAT_XRDY) {
+- alen--;
+- writeb((addr >> (8 * alen)) & 0xff, &i2c_base->data);
+- writew(I2C_STAT_XRDY, &i2c_base->stat);
+- } else {
+- i2c_error = 1;
+- printf("i2c_write: bus not ready for addr Tx (status=0x%x)\n",
+- status);
+- goto wr_exit;
+- }
+- }
+- /* Address phase is over, now write data */
+- for (i = 0; i < len; i++) {
+- status = wait_for_event();
++ I2C_CON_STP, &i2c_base->con);
++
++ /* Send address and data */
++ for (i = -alen; i < len; i++) {
++ status = wait_for_pin();
++
+ if (status == 0 || status & I2C_STAT_NACK) {
+ i2c_error = 1;
+- printf("i2c_write: error waiting for data ACK (status=0x%x)\n",
+- status);
+- goto wr_exit;
++ printf("i2c error waiting for data ACK (status=0x%x)\n",
++ status);
++ goto write_exit;
+ }
++
+ if (status & I2C_STAT_XRDY) {
+- writeb(buffer[i], &i2c_base->data);
++ w = (i < 0) ? tmpbuf[2+i] : buffer[i];
++#if !(defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \
++ defined(CONFIG_OMAP44XX) || defined(CONFIG_AM33XX) || \
++ defined(CONFIG_OMAP54XX))
++ w |= ((++i < 0) ? tmpbuf[2+i] : buffer[i]) << 8;
++#endif
++ writew(w, &i2c_base->data);
+ writew(I2C_STAT_XRDY, &i2c_base->stat);
+ } else {
+ i2c_error = 1;
+- printf("i2c_write: bus not ready for data Tx (i=%d)\n",
+- i);
+- goto wr_exit;
++ printf("i2c bus not ready for Tx (i=%d)\n", i);
++ goto write_exit;
+ }
+ }
+
+-wr_exit:
++write_exit:
+ flush_fifo();
+ writew(0xFFFF, &i2c_base->stat);
+- writew(0, &i2c_base->cnt);
+ return i2c_error;
+ }
+
+-/*
+- * Wait for the bus to be free by checking the Bus Busy (BB)
+- * bit to become clear
+- */
+ static int wait_for_bb(void)
+ {
+ int timeout = I2C_TIMEOUT;
+ u16 stat;
+
+ writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/
+-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+ while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
+-#else
+- /* Read RAW status */
+- while ((stat = readw(&i2c_base->irqstatus_raw) &
+- I2C_STAT_BB) && timeout--) {
+-#endif
+ writew(stat, &i2c_base->stat);
+- udelay(I2C_WAIT);
++ udelay(1000);
+ }
+
+ if (timeout <= 0) {
+- printf("Timed out in wait_for_bb: status=%04x\n",
+- stat);
++ printf("timed out in wait_for_bb: I2C_STAT=%x\n",
++ readw(&i2c_base->stat));
+ return 1;
+ }
+ writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/
+ return 0;
+ }
+
+-/*
+- * Wait for the I2C controller to complete current action
+- * and update status
+- */
+-static u16 wait_for_event(void)
++static u16 wait_for_pin(void)
+ {
+ u16 status;
+ int timeout = I2C_TIMEOUT;
+
+ do {
+- udelay(I2C_WAIT);
+-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
++ udelay(1000);
+ status = readw(&i2c_base->stat);
+-#else
+- /* Read RAW status */
+- status = readw(&i2c_base->irqstatus_raw);
+-#endif
+ } 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_event: status=%04x\n",
+- status);
+- /*
+- * If status is still 0 here, probably the bus pads have
+- * not been configured for I2C, and/or pull-ups are missing.
+- */
+- printf("Check if pads/pull-ups of bus %d are properly configured\n",
+- current_bus);
++ printf("timed out in wait_for_pin: I2C_STAT=%x\n",
++ readw(&i2c_base->stat));
+ writew(0xFFFF, &i2c_base->stat);
+ status = 0;
+ }
+@@ -550,36 +450,28 @@ static u16 wait_for_event(void)
+
+ int i2c_set_bus_num(unsigned int bus)
+ {
+- if (bus >= I2C_BUS_MAX) {
+- printf("Bad bus: %x\n", bus);
++ if ((bus < 0) || (bus >= I2C_BUS_MAX)) {
++ printf("Bad bus: %d\n", bus);
+ return -1;
+ }
+
+- switch (bus) {
+- default:
+- bus = 0; /* Fall through */
+- case 0:
+- i2c_base = (struct i2c *)I2C_BASE1;
+- break;
+- case 1:
+- i2c_base = (struct i2c *)I2C_BASE2;
+- break;
+-#if (I2C_BUS_MAX > 2)
+- case 2:
+- i2c_base = (struct i2c *)I2C_BASE3;
+- break;
+-#if (I2C_BUS_MAX > 3)
+- case 3:
++#if I2C_BUS_MAX == 4
++ if (bus == 3)
+ i2c_base = (struct i2c *)I2C_BASE4;
+- break;
+-#if (I2C_BUS_MAX > 4)
+- case 4:
+- i2c_base = (struct i2c *)I2C_BASE5;
+- break;
+-#endif
++ else
++ if (bus == 2)
++ i2c_base = (struct i2c *)I2C_BASE3;
++ else
+ #endif
++#if I2C_BUS_MAX == 3
++ if (bus == 2)
++ i2c_base = (struct i2c *)I2C_BASE3;
++ else
+ #endif
+- }
++ if (bus == 1)
++ i2c_base = (struct i2c *)I2C_BASE2;
++ else
++ i2c_base = (struct i2c *)I2C_BASE1;
+
+ current_bus = bus;
+
+--
+1.8.1.2
+
More information about the training-materials-updates
mailing list