[U-Boot-Users] [PATCH 2/2] Multi-bus I2C implementation of MPC834x
Timur Tabi
timur at freescale.com
Wed Aug 30 23:39:58 CEST 2006
Ben Warren wrote:
> Hello,
>
> Attached is a patch implementing multiple I2C buses on the MPC834x CPU
> family and the MPC8349EMDS board in particular.
Here's my patch which does the same thing.
CHANGELOG:
* The current support for dual I2C busses is specific to the MPC 8349. This patch
makes it more generic. If two I2C busses are present (i.e. CFG_I2C2_OFFSET is
defined), then the macro 'I2C' becomes a variable. Any code which needs to
reference the I2C bus should make sure that 'I2C' points to the right bus before
calling an i2c_* function. i2c_init() and do_i2c_probe() have been updated to
automatically process both busses. And lastly, some hard-code constants have
been replaced by macros.
Signed-off-by: Timur Tabi <timur at freescale.com>
---
board/mpc8349emds/pci.c | 2 +-
common/cmd_i2c.c | 29 ++++++++++++++++++++++++-----
cpu/mpc83xx/i2c.c | 35 +++++++++++++++++++++++++++++------
include/asm-ppc/i2c.h | 9 ++++-----
4 files changed, 58 insertions(+), 17 deletions(-)
4fa4904374e01e31ea155dbe340d72abd944617a
diff --git a/board/mpc8349emds/pci.c b/board/mpc8349emds/pci.c
index 63e4405..e91bfef 100644
--- a/board/mpc8349emds/pci.c
+++ b/board/mpc8349emds/pci.c
@@ -72,7 +72,7 @@ pib_init(void)
/*
* Assign PIB PMC slot to desired PCI bus
*/
- mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C2_OFFSET);
+ I2C = (i2c_t*) (CFG_IMMRBAR + CFG_I2C2_OFFSET);
i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
val8 = 0;
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index c543bb5..9f0980b 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -529,11 +529,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrfl
return 0;
}
-/*
- * Syntax:
- * iprobe {addr}{.0, .1, .2}
- */
-int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+static void _do_i2c_probe(void)
{
int j;
#if defined(CFG_I2C_NOPROBES)
@@ -565,6 +561,29 @@ int do_i2c_probe (cmd_tbl_t *cmdtp, int
printf(" %02X", i2c_no_probes[k] );
putc ('\n');
#endif
+}
+
+/*
+ * Syntax:
+ * iprobe {addr}{.0, .1, .2}
+ */
+int do_i2c_probe(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#ifdef CFG_I2C2_OFFSET
+
+/* If we have two I2C busses, then we need to probe each one separately.
+ Note that if an I2C address is defined in i2c_no_probes[], we skip it
+ on both busses.
+*/
+ printf("I2C1 ");
+ I2C = (i2c_t *) (CFG_IMMRBAR + CFG_I2C_OFFSET);
+ _do_i2c_probe();
+
+ printf("I2C2 ");
+ I2C = (i2c_t *) (CFG_IMMRBAR + CFG_I2C2_OFFSET);
+#endif
+
+ _do_i2c_probe();
return 0;
}
diff --git a/cpu/mpc83xx/i2c.c b/cpu/mpc83xx/i2c.c
index 70450f9..308a65d 100644
--- a/cpu/mpc83xx/i2c.c
+++ b/cpu/mpc83xx/i2c.c
@@ -41,21 +41,30 @@
#include <i2c.h>
#include <asm/i2c.h>
-#if defined(CONFIG_MPC8349EMDS) || defined(CONFIG_TQM834X)
-i2c_t * mpc8349_i2c = (i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET);
+#ifdef CFG_I2C2_OFFSET
+/*
+To configure DDR RAM, we need to query the I2C bus. Since RAM hasn't
+been initialized, U-Boot has not been copied yet to RAM. That means that
+the global variable 'I2C' is located in flash, which means it can't be
+modified. Therefore, 'I2C' needs to be initialized to the I2C bus that
+DDR is on.
+
+CFG_I2C_DDR_OFFSET is the offset of the I2C bus that DDR is using. It
+should be set to either CFG_I2C_OFFSET or CFG_I2C2_OFFSET.
+*/
+volatile i2c_t *I2C = (i2c_t *) (CFG_IMMRBAR + CFG_I2C_DDR_OFFSET);
#endif
-void
-i2c_init(int speed, int slaveadd)
+static void _i2c_init(int slaveadd)
{
/* stop I2C controller */
writeb(0x00 , &I2C->cr);
/* set clock */
- writeb(0x3f, &I2C->fdr);
+ writeb(IC2_FDR, &I2C->fdr);
/* set default filter */
- writeb(0x10,&I2C->dfsrr);
+ writeb(I2C_CR_MTX, &I2C->dfsrr);
/* write slave address */
writeb(slaveadd, &I2C->adr);
@@ -67,6 +76,20 @@ i2c_init(int speed, int slaveadd)
writeb(I2C_CR_MEN, &I2C->cr);
}
+void
+i2c_init(int speed, int slaveadd)
+{
+#ifdef CFG_I2C2_OFFSET
+ /* If it exists, initialize the 2nd I2C bus */
+ I2C = (i2c_t *) (CFG_IMMRBAR + CFG_I2C_OFFSET);
+ _i2c_init(slaveadd);
+
+ I2C = (i2c_t *) (CFG_IMMRBAR + CFG_I2C2_OFFSET);
+#endif
+ _i2c_init(slaveadd);
+
+}
+
static __inline__ int
i2c_wait4bus (void)
{
diff --git a/include/asm-ppc/i2c.h b/include/asm-ppc/i2c.h
index 1680d3a..bd6a51d 100644
--- a/include/asm-ppc/i2c.h
+++ b/include/asm-ppc/i2c.h
@@ -87,14 +87,13 @@ typedef struct i2c
#error CFG_I2C_OFFSET is not defined in /include/configs/${BOARD}.h
#endif
-#if defined(CONFIG_MPC8349EMDS) || defined(CONFIG_TQM834X)
+#ifdef CFG_I2C2_OFFSET
/*
- * MPC8349 have two i2c bus
+ * If we have two I2C busses, then 'I2C' should be a variable, not a constant.
*/
-extern i2c_t * mpc8349_i2c;
-#define I2C mpc8349_i2c
+extern volatile i2c_t *I2C;
#else
-#define I2C ((i2c_t*)(CFG_IMMRBAR + CFG_I2C_OFFSET))
+#define I2C ((i2c_t*) (CFG_IMMRBAR + CFG_I2C_OFFSET))
#endif
#define I2C_READ 1
--
1.2.4
--
Timur Tabi
Linux Kernel Developer @ Freescale
More information about the U-Boot
mailing list