i2c: common changes for multibus/multiadapter support

Signed-off-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Simon Glass <sjg@chromium.org>
Cc: Henrik Nordström <henrik@henriknordstrom.net>
diff --git a/common/board_f.c b/common/board_f.c
index ab4242a..ca9a760 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -261,7 +261,8 @@
 void dram_init_banksize(void)
 	__attribute__((weak, alias("__dram_init_banksize")));
 
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) || \
+	defined(CONFIG_SYS_I2C)
 static int init_func_i2c(void)
 {
 	puts("I2C:   ");
@@ -919,7 +920,8 @@
 	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)
 	init_func_i2c,
 #endif
 #if defined(CONFIG_HARD_SPI)
diff --git a/common/cmd_date.c b/common/cmd_date.c
index 0ac032c..f7ae1da 100644
--- a/common/cmd_date.c
+++ b/common/cmd_date.c
@@ -50,8 +50,13 @@
 	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 @@
 	}
 
 	/* 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 edbd4a8..c3f8982 100644
--- a/common/cmd_dtt.c
+++ b/common/cmd_dtt.c
@@ -73,8 +73,13 @@
 	/* 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();
 
@@ -86,8 +91,12 @@
 		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
+#endif
 
 	return 0;
 }
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 4380794..5614a6d 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.
  *
@@ -85,6 +90,8 @@
 #include <asm/byteorder.h>
 #include <linux/compiler.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
  */
@@ -103,7 +110,8 @@
  * pairs.  The following macros take care of this */
 
 #if defined(CONFIG_SYS_I2C_NOPROBES)
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MUX) || \
+	defined(CONFIG_I2C_MULTI_BUS)
 static struct
 {
 	uchar	bus;
@@ -119,7 +127,7 @@
 #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	/* defined(CONFIG_SYS_I2C) */
 
 #define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0]))
 #endif
@@ -127,9 +135,6 @@
 #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
@@ -144,7 +149,6 @@
 __weak
 void i2c_init_board(void)
 {
-	return;
 }
 
 /* TODO: Implement architecture-specific get/set functions */
@@ -161,6 +165,11 @@
  *
  * Returns I2C bus speed in Hz.
  */
+#if !defined(CONFIG_SYS_I2C)
+/*
+ * TODO: Implement architecture-specific get/set functions
+ * Should go away, if we switched completely to new multibus support
+ */
 __weak
 unsigned int i2c_get_bus_speed(void)
 {
@@ -188,6 +197,7 @@
 
 	return 0;
 }
+#endif
 
 /**
  * get_alen() - Small parser helper function to get address length
@@ -700,7 +710,7 @@
 	int found = 0;
 #if defined(CONFIG_SYS_I2C_NOPROBES)
 	int k, skip;
-	uchar bus = GET_BUS_NUM;
+	unsigned int bus = GET_BUS_NUM;
 #endif	/* NOPROBES */
 
 	if (argc == 2)
@@ -1373,9 +1383,8 @@
 }
 #endif /* CONFIG_I2C_EDID */
 
-#if defined(CONFIG_I2C_MUX)
 /**
- * do_i2c_add_bus() - Handle the "i2c bus" command-line command
+ * do_i2c_show_bus() - Handle the "i2c bus" command-line command
  * @cmdtp:	Command data struct pointer
  * @flag:	Command flag
  * @argc:	Command-line argument count
@@ -1383,35 +1392,55 @@
  *
  * Returns zero always.
  */
-static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+#if 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_BUSES; 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_BUSES) {
+			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)
 /**
  * do_i2c_bus_num() - Handle the "i2c dev" command-line command
  * @cmdtp:	Command data struct pointer
@@ -1422,23 +1451,29 @@
  * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
  * on error.
  */
-static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS)
+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_BUSES) {
+			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  /* defined(CONFIG_SYS_I2C) */
 
 /**
  * do_i2c_bus_speed() - Handle the "i2c speed" command-line command
@@ -1508,16 +1543,21 @@
  */
 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 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 defined(CONFIG_SYS_I2C) || \
+	defined(CONFIG_I2C_MULTI_BUS)
 	U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
 #endif  /* CONFIG_I2C_MULTI_BUS */
 #if defined(CONFIG_I2C_EDID)
@@ -1576,11 +1616,12 @@
 /***************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 static char i2c_help_text[] =
-#if defined(CONFIG_I2C_MUX)
-	"bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
+#if defined(CONFIG_SYS_I2C)
+	"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 defined(CONFIG_SYS_I2C) || \
+	defined(CONFIG_I2C_MULTI_BUS)
 	"i2c dev [dev] - show or set current I2C bus\n"
 #endif  /* CONFIG_I2C_MULTI_BUS */
 #if defined(CONFIG_I2C_EDID)
diff --git a/common/env_eeprom.c b/common/env_eeprom.c
index 45c935b..fbd459a 100644
--- a/common/env_eeprom.c
+++ b/common/env_eeprom.c
@@ -49,6 +49,10 @@
 #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 @@
 				(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 @@
 #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 5d5117c..2011880 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
 
@@ -210,9 +215,15 @@
 #ifdef CONFIG_ARM_DCC
 	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