Patchwork [U-Boot,2/3] i2c: common changes for multibus/multiadapter support

login
register
mail settings
Submitter Heiko Schocher
Date Oct. 22, 2012, 5:40 p.m.
Message ID <1350927621-12481-3-git-send-email-hs@denx.de>
Download mbox | patch
Permalink /patch/193248/
State Superseded
Delegated to: Heiko Schocher
Headers show

Comments

Heiko Schocher - Oct. 22, 2012, 5:40 p.m.
Signed-off-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
 README                          |   82 ++++++++++++++++++++++++++-
 arch/arm/lib/board.c            |   12 ++++-
 arch/blackfin/lib/board.c       |    7 ++
 arch/m68k/lib/board.c           |   18 +++++-
 arch/mips/lib/board.c           |    7 ++
 arch/nds32/lib/board.c          |   10 +++-
 arch/powerpc/cpu/mpc8xx/video.c |    4 +
 arch/powerpc/lib/board.c        |   18 +++++-
 common/cmd_date.c               |    9 +++
 common/cmd_dtt.c                |    9 +++
 common/cmd_i2c.c                |  118 ++++++++++++++++++++++++++-------------
 common/env_eeprom.c             |   14 +++++
 common/stdio.c                  |   13 ++++-
 include/i2c.h                   |    9 ---
 14 files changed, 269 insertions(+), 61 deletions(-)
Henrik Nordström - Oct. 22, 2012, 10:16 p.m.
mån 2012-10-22 klockan 19:40 +0200 skrev Heiko Schocher:
> +- Legacy I2C Support:	CONFIG_HARD_I2C | CONFIG_SOFT_I2C
> +
> +		NOTE: It is intended to move drivers to CONFIG_SYS_I2C which
> +		provides the following compelling advantages:
> +			1. Heiko to fill in

Something missing here?

Regards
Henrik
Heiko Schocher - Oct. 23, 2012, 3:25 a.m.
Hello Henrik Nordström,

On 23.10.2012 00:16, Henrik Nordström wrote:
> mån 2012-10-22 klockan 19:40 +0200 skrev Heiko Schocher:
>> +- Legacy I2C Support:	CONFIG_HARD_I2C | CONFIG_SOFT_I2C
>> +
>> +		NOTE: It is intended to move drivers to CONFIG_SYS_I2C which
>> +		provides the following compelling advantages:
>> +			1. Heiko to fill in
>
> Something missing here?

Oh... this is removed in the 3/3 patch. Update this in the next
patchversion, thanks!

bye,
Heiko

Patch

diff --git a/README b/README
index df4aed1..634cff4 100644
--- a/README
+++ b/README
@@ -1757,9 +1757,85 @@  The following options need to be configured:
 		on those systems that support this (optional)
 		feature, like the TQM8xxL modules.
 
-- I2C Support:	CONFIG_HARD_I2C | CONFIG_SOFT_I2C
-
-		These enable I2C serial bus commands. Defining either of
+- I2C Support:	CONFIG_SYS_I2C
+
+		This enable the NEW i2c subsystem, and will allow you to use
+		i2c commands at the u-boot command line (as long as you set
+		CONFIG_CMD_I2C in CONFIG_COMMANDS) and communicate with i2c
+		based realtime clock chips or other i2c devices. See
+		common/cmd_i2c.c for a description of the command line
+		interface.
+
+		additional defines:
+
+		CONFIG_SYS_NUM_I2C_ADAPTERS
+		define how many i2c adapters you want to use on your
+		hardware. If you need only 1 i2c adapter, you can ommit
+		this define.
+
+		CONFIG_SYS_I2C_ADAPTERS
+		hold a list of adapters you want to use, for example:
+		{&soft_i2c_adap[0], &mpc5xxx_i2c_adap[0]}
+		with this configuration you have one soft_i2c adapter,
+		and one mpc5xxx i2c adapter.
+
+		No I2C adapters current suppor this new interface.
+
+		You need to define for each adapter a speed and a
+		slave address.
+
+		CONFIG_SYS_NUM_I2C_BUSSES
+		Hold the number of i2c busses you want to use. If you
+		don't use/have i2c muxes on your i2c bus, this
+		is equal to CONFIG_SYS_NUM_I2C_ADAPTERS, and you can
+		omit this define.
+
+		CONFIG_SYS_I2C_DIRECT_BUS
+		define this, if you don't use i2c muxes on your hardware.
+		if CONFIG_SYS_I2C_MAX_HOPS is not defined or == 0 you can
+		omit this define.
+
+		CONFIG_SYS_I2C_MAX_HOPS
+		define how many muxes are maximal consecutively connected
+		on one i2c bus.
+
+		CONFIG_SYS_I2C_BUSSES
+		hold a list of busses you want to use, only used if
+		CONFIG_SYS_I2C_DIRECT_BUS is not defined, for example
+		a board with CONFIG_SYS_I2C_MAX_HOPS = 1 and
+		CONFIG_SYS_NUM_I2C_BUSSES = 9:
+
+		 CONFIG_SYS_I2C_BUSSES	{{0, {I2C_NULL_HOP}}, \
+					{0, {{I2C_MUX_PCA9547, 0x70, 1}}}, \
+					{0, {{I2C_MUX_PCA9547, 0x70, 2}}}, \
+					{0, {{I2C_MUX_PCA9547, 0x70, 3}}}, \
+					{0, {{I2C_MUX_PCA9547, 0x70, 4}}}, \
+					{0, {{I2C_MUX_PCA9547, 0x70, 5}}}, \
+					{1, {I2C_NULL_HOP}}, \
+					{1, {{I2C_MUX_PCA9544, 0x72, 1}}}, \
+					{1, {{I2C_MUX_PCA9544, 0x72, 2}}}, \
+					}
+
+		which defines
+			bus 0 on adapter 0 without a mux
+			bus 1 on adapter 0 without a PCA9547 on address 0x70 port 1
+			bus 2 on adapter 0 without a PCA9547 on address 0x70 port 2
+			bus 3 on adapter 0 without a PCA9547 on address 0x70 port 3
+			bus 4 on adapter 0 without a PCA9547 on address 0x70 port 4
+			bus 5 on adapter 0 without a PCA9547 on address 0x70 port 5
+			bus 6 on adapter 1 without a mux
+			bus 7 on adapter 1 without a PCA9544 on address 0x72 port 1
+			bus 8 on adapter 1 without a PCA9544 on address 0x72 port 2
+
+- Legacy I2C Support:	CONFIG_HARD_I2C | CONFIG_SOFT_I2C
+
+		NOTE: It is intended to move drivers to CONFIG_SYS_I2C which
+		provides the following compelling advantages:
+			1. Heiko to fill in
+
+		** Please consider updating your I2C driver now. **
+
+		These enable legacy I2C serial bus commands. Defining either of
 		(but not both of) CONFIG_HARD_I2C or CONFIG_SOFT_I2C will
 		include the appropriate I2C driver for the selected CPU.
 
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 0b47ab3..b5b53f4 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -74,7 +74,8 @@  extern void dataflash_print_info(void);
 #endif
 
 #if defined(CONFIG_HARD_I2C) || \
-    defined(CONFIG_SOFT_I2C)
+	defined(CONFIG_SOFT_I2C) || \
+	defined(CONFIG_SYS_I2C)
 #include <i2c.h>
 #endif
 
@@ -174,7 +175,11 @@  static int display_dram_config(void)
 static int init_func_i2c(void)
 {
 	puts("I2C:   ");
+#ifdef CONFIG_SYS_I2C
+	i2c_init_all();
+#else
 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
 	puts("ready\n");
 	return (0);
 }
@@ -559,6 +564,11 @@  void board_init_r(gd_t *id, ulong dest_addr)
 	dataflash_print_info();
 #endif
 
+#if defined(CONFIG_SYS_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+	/* Adjust I2C subsystem pointers after relocation */
+	i2c_reloc_fixup();
+#endif
+
 	/* initialize environment */
 	env_relocate();
 
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index e47b606..999857c 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -37,6 +37,10 @@ 
 int post_flag;
 #endif
 
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+#include <i2c.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 __attribute__((always_inline))
@@ -364,6 +368,9 @@  void board_init_r(gd_t * id, ulong dest_addr)
 	mmc_initialize(bd);
 #endif
 
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+	i2c_reloc_fixup();
+#endif
 	/* relocate environment function pointers etc. */
 	env_relocate();
 
diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c
index 67c9a13..ba8c957 100644
--- a/arch/m68k/lib/board.c
+++ b/arch/m68k/lib/board.c
@@ -55,7 +55,8 @@ 
 #include <version.h>
 
 #if defined(CONFIG_HARD_I2C) || \
-    defined(CONFIG_SOFT_I2C)
+	defined(CONFIG_SOFT_I2C) || \
+	defined(CONFIG_SYS_I2C_ADAPTERS)
 #include <i2c.h>
 #endif
 
@@ -140,11 +141,16 @@  static int init_func_ram (void)
 
 /***********************************************************************/
 
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) \
+		|| defined(CONFIG_SYS_I2C_ADAPTERS)
 static int init_func_i2c (void)
 {
 	puts ("I2C:   ");
+#ifdef CONFIG_SYS_I2C
+	i2c_init_all();
+#else
 	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
 	puts ("ready\n");
 	return (0);
 }
@@ -176,7 +182,8 @@  init_fnc_t *init_sequence[] = {
 	display_options,
 	checkcpu,
 	checkboard,
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) \
+		|| defined(CONFIG_SYS_I2C_ADAPTERS)
 	init_func_i2c,
 #endif
 #if defined(CONFIG_HARD_SPI)
@@ -501,6 +508,11 @@  void board_init_r (gd_t *id, ulong dest_addr)
 	spi_init_r ();
 #endif
 
+#if defined(CONFIG_SYS_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+	/* Adjust I2C subsystem pointers after relocation */
+	i2c_reloc_fixup();
+#endif
+
 	/* relocate environment function pointers etc. */
 	env_relocate ();
 
diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c
index b14b33e..f274b0e 100644
--- a/arch/mips/lib/board.c
+++ b/arch/mips/lib/board.c
@@ -35,6 +35,9 @@ 
 #ifdef CONFIG_BITBANGMII
 #include <miiphy.h>
 #endif
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+#include <i2c.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -309,6 +312,10 @@  void board_init_r(gd_t *id, ulong dest_addr)
 	onenand_init();
 #endif
 
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+	i2c_reloc_fixup();
+#endif
+
 	/* relocate environment function pointers etc. */
 	env_relocate();
 
diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c
index 89900fe..e5d3870 100644
--- a/arch/nds32/lib/board.c
+++ b/arch/nds32/lib/board.c
@@ -39,6 +39,10 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined(CONFIG_SYS_I2C)
+#include <i2c.h>
+#endif
+
 ulong monitor_flash_len;
 
 /*
@@ -172,7 +176,7 @@  init_fnc_t *init_sequence[] = {
 #if defined(CONFIG_DISPLAY_BOARDINFO)
 	checkboard,		/* display board info */
 #endif
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 	init_func_i2c,
 #endif
 	dram_init,		/* configure available RAM banks */
@@ -358,6 +362,10 @@  void board_init_r(gd_t *id, ulong dest_addr)
 	mmc_initialize(gd->bd);
 #endif
 
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+	i2c_reloc_fixup();
+#endif
+
 	/* initialize environment */
 	env_relocate();
 
diff --git a/arch/powerpc/cpu/mpc8xx/video.c b/arch/powerpc/cpu/mpc8xx/video.c
index 1bbf4cc..10e3e88 100644
--- a/arch/powerpc/cpu/mpc8xx/video.c
+++ b/arch/powerpc/cpu/mpc8xx/video.c
@@ -809,7 +809,11 @@  static void video_encoder_init (void)
 
 	/* Initialize the I2C */
 	debug ("[VIDEO ENCODER] Initializing I2C bus...\n");
+#ifdef CONFIG_SYS_I2C
+	i2c_init_all();
+#else
 	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
 
 #ifdef CONFIG_FADS
 	/* Reset ADV7176 chip */
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index b860141..0cd3408 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -99,7 +99,8 @@  extern void sc3_read_eeprom(void);
 void doc_init(void);
 #endif
 #if defined(CONFIG_HARD_I2C) || \
-    defined(CONFIG_SOFT_I2C)
+	defined(CONFIG_SOFT_I2C) || \
+	defined(CONFIG_SYS_I2C_ADAPTERS)
 #include <i2c.h>
 #endif
 #include <spi.h>
@@ -214,11 +215,16 @@  static int init_func_ram(void)
 
 /***********************************************************************/
 
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) \
+		|| defined(CONFIG_SYS_I2C_ADAPTERS)
 static int init_func_i2c(void)
 {
 	puts("I2C:   ");
+#ifdef CONFIG_SYS_I2C
+	i2c_init_all();
+#else
 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
 	puts("ready\n");
 	return 0;
 }
@@ -317,7 +323,8 @@  init_fnc_t *init_sequence[] = {
 	misc_init_f,
 #endif
 	INIT_FUNC_WATCHDOG_RESET
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) \
+		|| defined(CONFIG_SYS_I2C_ADAPTERS)
 	init_func_i2c,
 #endif
 #if defined(CONFIG_HARD_SPI)
@@ -814,6 +821,11 @@  void board_init_r(gd_t *id, ulong dest_addr)
 	mmc_initialize(bd);
 #endif
 
+#if defined(CONFIG_SYS_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+	/* Adjust I2C subsystem pointers after relocation */
+	i2c_reloc_fixup();
+#endif
+
 	/* relocate environment function pointers etc. */
 	env_relocate();
 
diff --git a/common/cmd_date.c b/common/cmd_date.c
index 335bc05..d454974 100644
--- a/common/cmd_date.c
+++ b/common/cmd_date.c
@@ -50,8 +50,13 @@  int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	int old_bus;
 
 	/* switch to correct I2C bus */
+#ifdef CONFIG_SYS_I2C
+	old_bus = i2c_get_bus_num();
+	i2c_set_bus_num(CONFIG_SYS_RTC_BUS_NUM);
+#else
 	old_bus = I2C_GET_BUS();
 	I2C_SET_BUS(CONFIG_SYS_RTC_BUS_NUM);
+#endif
 
 	switch (argc) {
 	case 2:			/* set date & time */
@@ -97,7 +102,11 @@  int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	}
 
 	/* switch back to original I2C bus */
+#ifdef CONFIG_SYS_I2C
+	i2c_set_bus_num(old_bus);
+#else
 	I2C_SET_BUS(old_bus);
+#endif
 
 	return rcode;
 }
diff --git a/common/cmd_dtt.c b/common/cmd_dtt.c
index cd94423..cb73614 100644
--- a/common/cmd_dtt.c
+++ b/common/cmd_dtt.c
@@ -69,8 +69,13 @@  int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 	/* Force a compilation error, if there are more then 32 sensors */
 	BUILD_BUG_ON(sizeof(sensors) > 32);
 	/* switch to correct I2C bus */
+#ifdef CONFIG_SYS_I2C
+	old_bus = i2c_get_bus_num();
+	i2c_set_bus_num(CONFIG_SYS_DTT_BUS_NUM);
+#else
 	old_bus = I2C_GET_BUS();
 	I2C_SET_BUS(CONFIG_SYS_DTT_BUS_NUM);
+#endif
 
 	_initialize_dtt();
 
@@ -82,7 +87,11 @@  int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 		printf("DTT%d: %i C\n", i + 1, dtt_get_temp(sensors[i]));
 
 	/* switch back to original I2C bus */
+#ifdef CONFIG_SYS_I2C
+	i2c_set_bus_num(old_bus);
+#else
 	I2C_SET_BUS(old_bus);
+#endif
 
 	return 0;
 }	/* do_dtt() */
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 795814d..79145e9 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -1,4 +1,9 @@ 
 /*
+ * (C) Copyright 2009
+ * Sergey Kubushyn, himself, ksi@koi8.net
+ *
+ * Changes for unified multibus/multiadapter I2C support.
+ *
  * (C) Copyright 2001
  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
  *
@@ -83,6 +88,8 @@ 
 #include <malloc.h>
 #include <asm/byteorder.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
  */
@@ -101,7 +108,8 @@  static uint	i2c_mm_last_alen;
  * pairs.  The following macros take care of this */
 
 #if defined(CONFIG_SYS_I2C_NOPROBES)
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if (CONFIG_SYS_NUM_I2C_BUSSES > 1) || defined(CONFIG_I2C_MUX) || \
+	defined(CONFIG_I2C_MULTI_BUS)
 static struct
 {
 	uchar	bus;
@@ -117,7 +125,7 @@  static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
 #define COMPARE_BUS(b,i)	((b) == 0)	/* Make compiler happy */
 #define COMPARE_ADDR(a,i)	(i2c_no_probes[(i)] == (a))
 #define NO_PROBE_ADDR(i)	i2c_no_probes[(i)]
-#endif	/* CONFIG_MULTI_BUS */
+#endif	/* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
 
 #define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0]))
 #endif
@@ -125,9 +133,6 @@  static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
 #if defined(CONFIG_I2C_MUX)
 static I2C_MUX_DEVICE	*i2c_mux_devices = NULL;
 static	int	i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS;
-
-DECLARE_GLOBAL_DATA_PTR;
-
 #endif
 
 #define DISP_LINE_LEN	16
@@ -135,12 +140,15 @@  DECLARE_GLOBAL_DATA_PTR;
 /* implement possible board specific board init */
 void __def_i2c_init_board(void)
 {
-	return;
 }
 void i2c_init_board(void)
 	__attribute__((weak, alias("__def_i2c_init_board")));
 
-/* TODO: Implement architecture-specific get/set functions */
+#if !defined(CONFIG_SYS_I2C)
+/*
+ * TODO: Implement architecture-specific get/set functions
+ * Should go away, if we switched completely to new multibus support
+ */
 unsigned int __def_i2c_get_bus_speed(void)
 {
 	return CONFIG_SYS_I2C_SPEED;
@@ -157,6 +165,7 @@  int __def_i2c_set_bus_speed(unsigned int speed)
 }
 int i2c_set_bus_speed(unsigned int)
 	__attribute__((weak, alias("__def_i2c_set_bus_speed")));
+#endif
 
 /*
  * get_alen: small parser helper function to get address length
@@ -564,7 +573,7 @@  static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
 	int j;
 #if defined(CONFIG_SYS_I2C_NOPROBES)
 	int k, skip;
-	uchar bus = GET_BUS_NUM;
+	unsigned int bus = GET_BUS_NUM;
 #endif	/* NOPROBES */
 
 	puts ("Valid chip addresses:");
@@ -1186,53 +1195,78 @@  static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 }
 #endif
 
-#if defined(CONFIG_I2C_MUX)
-static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+#if (CONFIG_SYS_NUM_I2C_BUSSES > 1) && defined(CONFIG_SYS_I2C)
+int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	int ret=0;
+	int	i;
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+	int	j;
+#endif
 
 	if (argc == 1) {
 		/* show all busses */
-		I2C_MUX		*mux;
-		I2C_MUX_DEVICE	*device = i2c_mux_devices;
-
-		printf ("Busses reached over muxes:\n");
-		while (device != NULL) {
-			printf ("Bus ID: %x\n", device->busid);
-			printf ("  reached over Mux(es):\n");
-			mux = device->mux;
-			while (mux != NULL) {
-				printf ("    %s@%x ch: %x\n", mux->name, mux->chip, mux->channel);
-				mux = mux->next;
+		for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSSES; i++) {
+			printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+			for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
+				if (i2c_bus[i].next_hop[j].chip == 0)
+					break;
+				printf("->%s@0x%2x:%d",
+					i2c_bus[i].next_hop[j].mux.name,
+					i2c_bus[i].next_hop[j].chip,
+					i2c_bus[i].next_hop[j].channel);
 			}
-			device = device->next;
+#endif
+			printf("\n");
 		}
 	} else {
-		(void)i2c_mux_ident_muxstring ((uchar *)argv[1]);
-		ret = 0;
+		/* show specific bus */
+		i = simple_strtoul(argv[1], NULL, 10);
+		if (i >= CONFIG_SYS_NUM_I2C_BUSSES) {
+			printf("Invalid bus %d\n", i);
+			return -1;
+		}
+		printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+			for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
+				if (i2c_bus[i].next_hop[j].chip == 0)
+					break;
+				printf("->%s@0x%2x:%d",
+					i2c_bus[i].next_hop[j].mux.name,
+					i2c_bus[i].next_hop[j].chip,
+					i2c_bus[i].next_hop[j].channel);
+			}
+#endif
+		printf("\n");
 	}
-	return ret;
+
+	return 0;
 }
-#endif  /* CONFIG_I2C_MUX */
+#endif
 
-#if defined(CONFIG_I2C_MULTI_BUS)
-static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
+int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	int bus_idx, ret=0;
+	int		ret = 0;
+	unsigned int	bus_no;
 
 	if (argc == 1)
 		/* querying current setting */
 		printf("Current bus is %d\n", i2c_get_bus_num());
 	else {
-		bus_idx = simple_strtoul(argv[1], NULL, 10);
-		printf("Setting bus to %d\n", bus_idx);
-		ret = i2c_set_bus_num(bus_idx);
+		bus_no = simple_strtoul(argv[1], NULL, 10);
+		if (bus_no >= CONFIG_SYS_NUM_I2C_BUSSES) {
+			printf("Invalid bus %d\n", bus_no);
+			return -1;
+		}
+		printf("Setting bus to %d\n", bus_no);
+		ret = i2c_set_bus_num(bus_no);
 		if (ret)
 			printf("Failure changing bus number (%d)\n", ret);
 	}
 	return ret;
 }
-#endif  /* CONFIG_I2C_MULTI_BUS */
+#endif  /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
 
 static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
@@ -1263,16 +1297,20 @@  static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 
 static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
+#if defined(CONFIG_SYS_I2C)
+	i2c_init(I2C_ADAP->speed, I2C_ADAP->slaveaddr);
+#else
 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
 	return 0;
 }
 
 static cmd_tbl_t cmd_i2c_sub[] = {
-#if defined(CONFIG_I2C_MUX)
-	U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_add_bus, "", ""),
+#if (CONFIG_SYS_NUM_I2C_BUSSES > 1) && defined(CONFIG_SYS_I2C)
+	U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""),
 #endif  /* CONFIG_I2C_MUX */
 	U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if (CONFIG_SYS_NUM_I2C_BUSSES > 1) && defined(CONFIG_SYS_I2C)
 	U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
 #endif  /* CONFIG_I2C_MULTI_BUS */
 	U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""),
@@ -1319,11 +1357,11 @@  static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
 	i2c, 6, 1, do_i2c,
 	"I2C sub-system",
-#if defined(CONFIG_I2C_MUX)
-	"bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
+	"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
 #endif  /* CONFIG_I2C_MUX */
 	"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
 	"i2c dev [dev] - show or set current I2C bus\n"
 #endif  /* CONFIG_I2C_MULTI_BUS */
 	"i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n"
diff --git a/common/env_eeprom.c b/common/env_eeprom.c
index b66bba2..9a0b4c3 100644
--- a/common/env_eeprom.c
+++ b/common/env_eeprom.c
@@ -49,6 +49,10 @@  static int eeprom_bus_read(unsigned dev_addr, unsigned offset,
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
 	int old_bus = i2c_get_bus_num();
 
+#if defined(CONFIG_SYS_I2C)
+	if (old_bus != CONFIG_I2C_ENV_EEPROM_BUS)
+		i2c_set_bus_num(CONFIG_I2C_ENV_EEPROM_BUS);
+#else
 	if (gd->flags & GD_FLG_RELOC) {
 		if (env_eeprom_bus == -1) {
 			I2C_MUX_DEVICE *dev = NULL;
@@ -68,11 +72,16 @@  static int eeprom_bus_read(unsigned dev_addr, unsigned offset,
 				(uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
 	}
 #endif
+#endif
 
 	rcode = eeprom_read(dev_addr, offset, buffer, cnt);
 
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
+#if defined(CONFIG_SYS_I2C)
+	if (old_bus != CONFIG_I2C_ENV_EEPROM_BUS)
+#else
 	if (old_bus != env_eeprom_bus)
+#endif
 		i2c_set_bus_num(old_bus);
 #endif
 	return rcode;
@@ -85,8 +94,13 @@  static int eeprom_bus_write(unsigned dev_addr, unsigned offset,
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
 	int old_bus = i2c_get_bus_num();
 
+#if defined(CONFIG_SYS_I2C)
+	if (old_bus != CONFIG_I2C_ENV_EEPROM_BUS)
+		i2c_set_bus_num(CONFIG_I2C_ENV_EEPROM_BUS);
+#else
 	rcode = i2c_mux_ident_muxstring_f((uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
 #endif
+#endif
 	rcode = eeprom_write(dev_addr, offset, buffer, cnt);
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
 	i2c_set_bus_num(old_bus);
diff --git a/common/stdio.c b/common/stdio.c
index 605ff3f..9b2e6b2 100644
--- a/common/stdio.c
+++ b/common/stdio.c
@@ -1,4 +1,8 @@ 
 /*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
  * (C) Copyright 2000
  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
  *
@@ -30,7 +34,8 @@ 
 #ifdef CONFIG_LOGBUFFER
 #include <logbuff.h>
 #endif
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) \
+		|| defined(CONFIG_SYS_I2C_ADAPTERS)
 #include <i2c.h>
 #endif
 
@@ -211,9 +216,15 @@  int stdio_init (void)
 #ifdef CONFIG_ARM_DCC_MULTI
 	drv_arm_dcc_init ();
 #endif
+#ifdef CONFIG_SYS_I2C
+#ifdef CONFIG_SYS_I2C_ADAPTERS
+	i2c_init_all();
+#endif
+#else
 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 #endif
+#endif
 #ifdef CONFIG_LCD
 	drv_lcd_init ();
 #endif
diff --git a/include/i2c.h b/include/i2c.h
index 44a05cd..afb4409 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -202,15 +202,6 @@  int i2c_mux_ident_muxstring_f (uchar *buf);
 
 #ifdef CONFIG_SYS_I2C
 /*
- * Initialization, must be called once on start up, may be called
- * repeatedly to change the speed and slave addresses.
- */
-void i2c_init(unsigned int speed, int slaveaddr);
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-void i2c_init_board(void);
-#endif
-
-/*
  * i2c_get_bus_num:
  *
  *  Returns index of currently active I2C bus.  Zero-based.