[U-Boot] [PATCH] 1/12 Multiadapter/multibus I2C, common part 1

ksi at koi8.net ksi at koi8.net
Thu Feb 12 23:12:03 CET 2009


Signed-off-by: Sergey Kubushyn <ksi at koi8.net>
---
diff -purN u-boot-i2c.orig/common/cmd_date.c u-boot-i2c/common/cmd_date.c
--- u-boot-i2c.orig/common/cmd_date.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/common/cmd_date.c	2009-02-12 10:46:00.000000000 -0800
@@ -46,8 +46,13 @@ int do_date (cmd_tbl_t *cmdtp, int flag,
 	int old_bus;
 
 	/* switch to correct I2C bus */
+#ifdef CONFIG_NEW_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 */
@@ -94,7 +99,11 @@ int do_date (cmd_tbl_t *cmdtp, int flag,
 	}
 
 	/* switch back to original I2C bus */
+#ifdef CONFIG_NEW_I2C
+	i2c_set_bus_num(old_bus);
+#else
 	I2C_SET_BUS(old_bus);
+#endif
 
 	return rcode;
 }
diff -purN u-boot-i2c.orig/common/cmd_dtt.c u-boot-i2c/common/cmd_dtt.c
--- u-boot-i2c.orig/common/cmd_dtt.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/common/cmd_dtt.c	2009-02-12 10:46:00.000000000 -0800
@@ -35,8 +35,13 @@ int do_dtt (cmd_tbl_t * cmdtp, int flag,
 	int old_bus;
 
 	/* switch to correct I2C bus */
+#ifdef CONFIG_NEW_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
 
 	/*
 	 * Loop through sensors, read
@@ -46,7 +51,11 @@ int do_dtt (cmd_tbl_t * cmdtp, int flag,
 		printf ("DTT%d: %i C\n", i + 1, dtt_get_temp (sensors[i]));
 
 	/* switch back to original I2C bus */
+#ifdef CONFIG_NEW_I2C
+	i2c_set_bus_num(old_bus);
+#else
 	I2C_SET_BUS(old_bus);
+#endif
 
 	return 0;
 }	/* do_dtt() */
diff -purN u-boot-i2c.orig/common/cmd_i2c.c u-boot-i2c/common/cmd_i2c.c
--- u-boot-i2c.orig/common/cmd_i2c.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/common/cmd_i2c.c	2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,9 @@
 /*
+ * (C) Copyright 2009
+ * Sergey Kubushyn, himself, ksi at koi8.net
+ *
+ * Changes for unified multibus/multiadapter I2C support.
+ *
  * (C) Copyright 2001
  * Gerald Van Baren, Custom IDEAS, vanbaren at cideas.com.
  *
@@ -106,7 +111,7 @@ 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
 static struct
 {
 	uchar	bus;
@@ -122,19 +127,11 @@ static uchar i2c_no_probes[] = CONFIG_SY
 #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
 
-#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
-
 static int
 mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[]);
 
@@ -548,10 +545,10 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrfl
  */
 int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-	int j;
+	int		j;
 #if defined(CONFIG_SYS_I2C_NOPROBES)
-	int k, skip;
-	uchar bus = GET_BUS_NUM;
+	int		k, skip;
+	unsigned int	bus = GET_BUS_NUM;
 #endif	/* NOPROBES */
 
 	puts ("Valid chip addresses:");
@@ -1189,59 +1186,79 @@ int do_sdram (cmd_tbl_t * cmdtp, int fla
 #if defined(CONFIG_I2C_CMD_TREE)
 int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
-	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+	i2c_init (ADAP(i2c_get_bus_num())->speed, ADAP(i2c_get_bus_num())->slaveaddr);
 	return 0;
 }
 
-#if defined(CONFIG_I2C_MUX)
-int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+int do_i2c_show_bus(cmd_tbl_t * cmdtp, int flag, int argc, char *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, ADAP(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 at 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 {
-		I2C_MUX_DEVICE *dev;
 
-		dev = i2c_mux_ident_muxstring ((uchar *)argv[1]);
-		ret = 0;
+	} else {
+		/* 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, ADAP(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 at 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 */
 
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
 int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char *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 */
 
 int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
@@ -1262,16 +1279,16 @@ int do_i2c_bus_speed(cmd_tbl_t * cmdtp, 
 
 int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
-#if defined(CONFIG_I2C_MUX)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
 	if (!strncmp(argv[1], "bu", 2))
-		return do_i2c_add_bus(cmdtp, flag, --argc, ++argv);
-#endif  /* CONFIG_I2C_MUX */
+		return do_i2c_show_bus(cmdtp, flag, --argc, ++argv);
+#endif  /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
 	if (!strncmp(argv[1], "sp", 2))
 		return do_i2c_bus_speed(cmdtp, flag, --argc, ++argv);
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
 	if (!strncmp(argv[1], "de", 2))
 		return do_i2c_bus_num(cmdtp, flag, --argc, ++argv);
-#endif  /* CONFIG_I2C_MULTI_BUS */
+#endif  /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
 	if (!strncmp(argv[1], "md", 2))
 		return do_i2c_md(cmdtp, flag, --argc, ++argv);
 	if (!strncmp(argv[1], "mm", 2))
@@ -1304,13 +1321,11 @@ int do_i2c(cmd_tbl_t * cmdtp, int flag, 
 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.\n"
-#endif  /* CONFIG_I2C_MUX */
-	"speed [speed] - show or set I2C bus speed\n"
-#if defined(CONFIG_I2C_MULTI_BUS)
+#if CONFIG_SYS_NUM_I2C_BUSSES > 1
+	"bus [bus_no] - show I2C bus info.\n"
 	"i2c dev [dev] - show or set current I2C bus\n"
-#endif  /* CONFIG_I2C_MULTI_BUS */
+#endif  /* CONFIG_SYS_NUM_I2C_BUSSES > 1 */
+	"i2c speed [speed] - show or set I2C bus speed\n"
 	"i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n"
 	"i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n"
 	"i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n"
@@ -1323,7 +1338,7 @@ U_BOOT_CMD(
 	"i2c sdram chip - print SDRAM configuration information\n"
 #endif
 );
-#endif /* CONFIG_I2C_CMD_TREE */
+#else /* CONFIG_I2C_CMD_TREE */
 U_BOOT_CMD(
 	imd,	4,	1,	do_i2c_md,		\
 	"i2c memory display",				\
@@ -1378,221 +1393,4 @@ U_BOOT_CMD(
 	"      (valid chip values 50..57)\n"
 );
 #endif
-
-#if defined(CONFIG_I2C_MUX)
-
-int i2c_mux_add_device(I2C_MUX_DEVICE *dev)
-{
-	I2C_MUX_DEVICE	*devtmp = i2c_mux_devices;
-
-	if (i2c_mux_devices == NULL) {
-		i2c_mux_devices = dev;
-		return 0;
-	}
-	while (devtmp->next != NULL)
-		devtmp = devtmp->next;
-
-	devtmp->next = dev;
-	return 0;
-}
-
-I2C_MUX_DEVICE	*i2c_mux_search_device(int id)
-{
-	I2C_MUX_DEVICE	*device = i2c_mux_devices;
-
-	while (device != NULL) {
-		if (device->busid == id)
-			return device;
-		device = device->next;
-	}
-	return NULL;
-}
-
-/* searches in the buf from *pos the next ':'.
- * returns:
- *     0 if found (with *pos = where)
- *   < 0 if an error occured
- *   > 0 if the end of buf is reached
- */
-static int i2c_mux_search_next (int *pos, uchar	*buf, int len)
-{
-	while ((buf[*pos] != ':') && (*pos < len)) {
-		*pos += 1;
-	}
-	if (*pos >= len)
-		return 1;
-	if (buf[*pos] != ':')
-		return -1;
-	return 0;
-}
-
-static int i2c_mux_get_busid (void)
-{
-	int	tmp = i2c_mux_busid;
-
-	i2c_mux_busid ++;
-	return tmp;
-}
-
-/* Analyses a Muxstring and sends immediately the
-   Commands to the Muxes. Runs from Flash.
- */
-int i2c_mux_ident_muxstring_f (uchar *buf)
-{
-	int	pos = 0;
-	int	oldpos;
-	int	ret = 0;
-	int	len = strlen((char *)buf);
-	int	chip;
-	uchar	channel;
-	int	was = 0;
-
-	while (ret == 0) {
-		oldpos = pos;
-		/* search name */
-		ret = i2c_mux_search_next(&pos, buf, len);
-		if (ret != 0)
-			printf ("ERROR\n");
-		/* search address */
-		pos ++;
-		oldpos = pos;
-		ret = i2c_mux_search_next(&pos, buf, len);
-		if (ret != 0)
-			printf ("ERROR\n");
-		buf[pos] = 0;
-		chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
-		buf[pos] = ':';
-		/* search channel */
-		pos ++;
-		oldpos = pos;
-		ret = i2c_mux_search_next(&pos, buf, len);
-		if (ret < 0)
-			printf ("ERROR\n");
-		was = 0;
-		if (buf[pos] != 0) {
-			buf[pos] = 0;
-			was = 1;
-		}
-		channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
-		if (was)
-			buf[pos] = ':';
-		if (i2c_write(chip, 0, 0, &channel, 1) != 0) {
-			printf ("Error setting Mux: chip:%x channel: \
-				%x\n", chip, channel);
-			return -1;
-		}
-		pos ++;
-		oldpos = pos;
-
-	}
-
-	return 0;
-}
-
-/* Analyses a Muxstring and if this String is correct
- * adds a new I2C Bus.
- */
-I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf)
-{
-	I2C_MUX_DEVICE	*device;
-	I2C_MUX		*mux;
-	int	pos = 0;
-	int	oldpos;
-	int	ret = 0;
-	int	len = strlen((char *)buf);
-	int	was = 0;
-
-	device = (I2C_MUX_DEVICE *)malloc (sizeof(I2C_MUX_DEVICE));
-	device->mux = NULL;
-	device->busid = i2c_mux_get_busid ();
-	device->next = NULL;
-	while (ret == 0) {
-		mux = (I2C_MUX *)malloc (sizeof(I2C_MUX));
-		mux->next = NULL;
-		/* search name of mux */
-		oldpos = pos;
-		ret = i2c_mux_search_next(&pos, buf, len);
-		if (ret != 0)
-			printf ("%s no name.\n", __FUNCTION__);
-		mux->name = (char *)malloc (pos - oldpos + 1);
-		memcpy (mux->name, &buf[oldpos], pos - oldpos);
-		mux->name[pos - oldpos] = 0;
-		/* search address */
-		pos ++;
-		oldpos = pos;
-		ret = i2c_mux_search_next(&pos, buf, len);
-		if (ret != 0)
-			printf ("%s no mux address.\n", __FUNCTION__);
-		buf[pos] = 0;
-		mux->chip = simple_strtoul((char *)&buf[oldpos], NULL, 16);
-		buf[pos] = ':';
-		/* search channel */
-		pos ++;
-		oldpos = pos;
-		ret = i2c_mux_search_next(&pos, buf, len);
-		if (ret < 0)
-			printf ("%s no mux channel.\n", __FUNCTION__);
-		was = 0;
-		if (buf[pos] != 0) {
-			buf[pos] = 0;
-			was = 1;
-		}
-		mux->channel = simple_strtoul((char *)&buf[oldpos], NULL, 16);
-		if (was)
-			buf[pos] = ':';
-		if (device->mux == NULL)
-			device->mux = mux;
-		else {
-			I2C_MUX		*muxtmp = device->mux;
-			while (muxtmp->next != NULL) {
-				muxtmp = muxtmp->next;
-			}
-			muxtmp->next = mux;
-		}
-		pos ++;
-		oldpos = pos;
-	}
-	if (ret > 0) {
-		/* Add Device */
-		i2c_mux_add_device (device);
-		return device;
-	}
-
-	return NULL;
-}
-
-int i2x_mux_select_mux(int bus)
-{
-	I2C_MUX_DEVICE  *dev;
-	I2C_MUX		*mux;
-
-	if ((gd->flags & GD_FLG_RELOC) != GD_FLG_RELOC) {
-		/* select Default Mux Bus */
-#if defined(CONFIG_SYS_I2C_IVM_BUS)
-		i2c_mux_ident_muxstring_f ((uchar *)CONFIG_SYS_I2C_IVM_BUS);
-#else
-		{
-		unsigned char *buf;
-		buf = (unsigned char *) getenv("EEprom_ivm");
-		if (buf != NULL)
-			i2c_mux_ident_muxstring_f (buf);
-		}
-#endif
-		return 0;
-	}
-	dev = i2c_mux_search_device(bus);
-	if (dev == NULL)
-		return -1;
-
-	mux = dev->mux;
-	while (mux != NULL) {
-		if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) {
-			printf ("Error setting Mux: chip:%x channel: \
-				%x\n", mux->chip, mux->channel);
-			return -1;
-		}
-		mux = mux->next;
-	}
-	return 0;
-}
-#endif /* CONFIG_I2C_MUX */
+#endif /* CONFIG_I2C_CMD_TREE */
diff -purN u-boot-i2c.orig/common/devices.c u-boot-i2c/common/devices.c
--- u-boot-i2c.orig/common/devices.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/common/devices.c	2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,8 @@
 /*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi at koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
  * (C) Copyright 2000
  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
  *
@@ -30,7 +34,7 @@
 #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
 
@@ -215,9 +219,15 @@ int devices_init (void)
 	/* Initialize the list */
 	INIT_LIST_HEAD(&(devs.list));
 
+#ifdef CONFIG_NEW_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 -purN u-boot-i2c.orig/drivers/hwmon/adm1021.c u-boot-i2c/drivers/hwmon/adm1021.c
--- u-boot-i2c.orig/drivers/hwmon/adm1021.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/hwmon/adm1021.c	2009-02-12 10:46:00.000000000 -0800
@@ -174,7 +174,11 @@ dtt_init (void)
 	const char *const header = "DTT:   ";
 
 	/* switch to correct I2C bus */
+#ifdef CONFIG_NEW_I2C
+	i2c_set_bus_num(CONFIG_SYS_DTT_BUS_NUM);
+#else
 	I2C_SET_BUS(CONFIG_SYS_DTT_BUS_NUM);
+#endif
 
 	for (i = 0; i < sizeof(sensors); i++) {
 		if (_dtt_init(sensors[i]) != 0)
diff -purN u-boot-i2c.orig/drivers/hwmon/lm75.c u-boot-i2c/drivers/hwmon/lm75.c
--- u-boot-i2c.orig/drivers/hwmon/lm75.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/hwmon/lm75.c	2009-02-12 10:46:00.000000000 -0800
@@ -156,8 +156,13 @@ int dtt_init (void)
 	int old_bus;
 
 	/* switch to correct I2C bus */
+#ifdef CONFIG_NEW_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
 
 	for (i = 0; i < sizeof(sensors); i++) {
 	if (_dtt_init(sensors[i]) != 0)
@@ -167,7 +172,11 @@ int dtt_init (void)
 		dtt_get_temp(sensors[i]));
 	}
 	/* switch back to original I2C bus */
+#ifdef CONFIG_NEW_I2C
+	i2c_set_bus_num(old_bus);
+#else
 	I2C_SET_BUS(old_bus);
+#endif
 
 	return (0);
 } /* dtt_init() */
diff -purN u-boot-i2c.orig/drivers/i2c/i2c_core.c u-boot-i2c/drivers/i2c/i2c_core.c
--- u-boot-i2c.orig/drivers/i2c/i2c_core.c	1969-12-31 16:00:00.000000000 -0800
+++ u-boot-i2c/drivers/i2c/i2c_core.c	2009-02-12 11:06:54.000000000 -0800
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi at koi8.net>
+ *
+ * Multibus/multiadapter I2C core functions (wrappers)
+ */
+#include <common.h>
+#include <i2c.h>
+
+#ifdef CONFIG_BFIN_TWI_I2C
+extern i2c_adap_t	bfin_twi_i2c_adap;
+#endif
+
+#ifdef CONFIG_FSL_I2C
+extern i2c_adap_t	fsl_i2c_adap[];
+#endif
+
+#ifdef CONFIG_MXC_I2C
+extern i2c_adap_t	mxc_i2c_adap[];
+#endif
+
+#ifdef CONFIG_OMAP1510_I2C
+extern i2c_adap_t	omap1510_i2c_adap;
+#endif
+
+#ifdef CONFIG_OMAP24XX_I2C
+extern i2c_adap_t	omap24xx_i2c_adap[];
+#endif
+
+#ifdef CONFIG_SM502_I2C
+extern i2c_adap_t	sm501_i2c_adap;
+#endif
+
+#ifdef CONFIG_SOFT_I2C
+extern i2c_adap_t	soft_i2c_adap[];
+#endif
+
+#ifdef CONFIG_TSI108_I2C
+extern i2c_adap_t	tsi108_i2c_adap;
+#endif
+
+i2c_adap_t	*i2c_adap[CONFIG_SYS_NUM_I2C_ADAPTERS] = CONFIG_SYS_I2C_ADAPTERS;
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+i2c_bus_t	i2c_bus[CONFIG_SYS_NUM_I2C_BUSSES] = CONFIG_SYS_I2C_BUSSES;
+#endif
+
+static unsigned int	i2c_cur_bus __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM;
+
+DECLARE_GLOBAL_DATA_PTR;
+ 
+void i2c_reloc_fixup(void)
+{
+	int		i;
+	unsigned long	addr;
+
+	for (i = 0; i < CONFIG_SYS_NUM_I2C_ADAPTERS; i++) {
+		/* Adapter itself */
+		addr = (unsigned long)i2c_adap[i];
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i] = (i2c_adap_t *)addr;
+		/* i2c_init() */
+		addr = (unsigned long)i2c_adap[i]->init;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->init = (void (*)(int, int))addr;
+		/* i2c_probe() */
+		addr = (unsigned long)i2c_adap[i]->probe;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->probe = (int (*)(u_int8_t))addr;
+		/* i2c_read() */
+		addr = (unsigned long)i2c_adap[i]->read;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->read = (int (*)(u_int8_t, uint, int, u_int8_t *, int))addr;
+		/* i2c_write() */
+		addr = (unsigned long)i2c_adap[i]->write;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->write = (int (*)(u_int8_t, uint, int, u_int8_t *, int))addr;
+		/* i2c_set_bus_speed() */
+		addr = (unsigned long)i2c_adap[i]->set_bus_speed;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->set_bus_speed = (uint (*)(uint))addr;
+		/* i2c_get_bus_speed() */
+		addr = (unsigned long)i2c_adap[i]->get_bus_speed;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->get_bus_speed = (uint (*)(void))addr;
+		/* name */
+		addr = (unsigned long)i2c_adap[i]->name;
+		if (addr != 0) addr += gd->reloc_off;
+		i2c_adap[i]->name = (char *)addr;
+	}
+}
+
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+/*
+ * i2c_mux_set()
+ * -------------
+ *
+ * This turns on the given channel on I2C multiplexer chip connected to
+ * a given I2C adapter directly or via other multiplexers. In the latter
+ * case the entire multiplexer chain must be initialized first starting
+ * with the one connected directly to the adapter. When disabling a chain
+ * muxes must be programmed in reverse order, starting with the one
+ * farthest from the adapter.
+ *
+ * mux_id is the multiplexer chip type from defined in i2c.h. So far only
+ * NXP (Philips) PCA954x multiplexers are supported. Switches are NOT
+ * supported (anybody uses them?)
+ */
+ 
+static int i2c_mux_set(int adapter, int mux_id, int chip, int channel)
+{
+	u_int8_t	buf;
+
+	/* channel < 0 - turn off the mux */
+	if (channel < 0) {
+		buf = 0;
+		return(i2c_adap[adapter]->write(chip, 0, 0, &buf, 1));
+	}
+
+	switch (mux_id) {
+		case I2C_MUX_PCA9540_ID:
+		case I2C_MUX_PCA9542_ID:
+			if (channel > 1) return(-1);
+			buf = (u_int8_t)((channel & 0x01) | (1 << 2));
+			break;
+		case I2C_MUX_PCA9544_ID:
+			if (channel > 3) return(-1);
+			buf = (u_int8_t)((channel & 0x03) | (1 << 2));
+			break;
+		case I2C_MUX_PCA9547_ID:
+			if (channel > 7) return(-1);
+			buf = (u_int8_t)((channel & 0x07) | (1 << 3));
+			break;
+		default:
+			return(-1);
+	}
+
+	return(i2c_adap[adapter]->write(chip, 0, 0, &buf, 1));
+}
+#endif
+
+/*
+ * i2c_get_bus_num():
+ * ------------------
+ *
+ *  Returns index of currently active I2C bus.  Zero-based.
+ */
+unsigned int i2c_get_bus_num(void)
+{
+	return(i2c_cur_bus);
+}
+
+/*
+ * i2c_set_bus_num():
+ * ------------------
+ *
+ *  Change the active I2C bus.  Subsequent read/write calls will
+ *  go to this one. Sets all of the muxes in a proper condition
+ *  if that bus is behind muxes. Fails if called before relocation.
+ *  If previously selected bus is behind the muxes turns off all the
+ *  muxes along the path to that bus.
+ *
+ *	bus - bus index, zero based
+ *
+ *	Returns: 0 on success, not 0 on failure
+ */
+int i2c_set_bus_num(unsigned int bus)
+{
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+	int		i;
+	u_int8_t	buf;
+#endif
+
+	if ((bus >= CONFIG_SYS_NUM_I2C_BUSSES) || !(gd->flags & GD_FLG_RELOC))
+		return(-1);
+
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+	/* Disconnect current bus (turn off muxes if any) */
+	if ((i2c_bus[i2c_cur_bus].next_hop[0].chip != 0) &&
+			(ADAP(i2c_cur_bus)->init_done != 0)) {
+
+		i = CONFIG_SYS_I2C_MAX_HOPS;
+
+		do {
+			u_int8_t	chip;
+			
+			if ((chip = i2c_bus[i2c_cur_bus].next_hop[--i].chip) == 0)
+				continue;
+
+			ADAP(i2c_cur_bus)->write(chip, 0, 0, &buf, 1);
+
+		} while (i > 0);
+	}
+
+	/* Connect requested bus if behind muxes */
+	if ((i2c_bus[bus].next_hop[0].chip != 0) &&
+			(ADAP(bus)->init_done != 0)) {
+
+		/* Set all muxes along the path to that bus */
+		for (i = 0; i < CONFIG_SYS_I2C_MAX_HOPS; i++) {
+
+			if (i2c_bus[bus].next_hop[i].chip == 0) break;
+
+			i2c_mux_set(i2c_bus[bus].adapter,
+					i2c_bus[bus].next_hop[i].mux.id,
+					i2c_bus[bus].next_hop[i].chip,
+					i2c_bus[bus].next_hop[i].channel);
+		}
+	}
+#endif
+
+	i2c_cur_bus = bus;
+	return(0);
+}
+
+/*
+ * i2c_init_bus():
+ * ---------------
+ *
+ * Initializes one bus. Will initialize the parent adapter. No current bus
+ * changes, no mux (if any) setup.
+ */
+static void i2c_init_bus(unsigned int bus_no, int speed, int slaveaddr)
+{
+	if (bus_no >= CONFIG_SYS_NUM_I2C_BUSSES)
+		return;
+
+	ADAP(bus_no)->init(speed, slaveaddr);
+	
+	if (gd->flags & GD_FLG_RELOC) {
+		ADAP(bus_no)->init_done = 1;
+		ADAP(bus_no)->speed = speed;
+		ADAP(bus_no)->slaveaddr = slaveaddr;
+	}
+}
+
+/*
+ * i2c_init_all():
+ *
+ * Initializes all I2C adapters in the system. All i2c_adap_t structures in
+ * i2c_adap[] must be initialized beforehead with function pointers and
+ * data, including speed and slaveaddr.
+ */
+void i2c_init_all(void)
+{
+	int	i;
+
+	for (i = 0; i < CONFIG_SYS_NUM_I2C_ADAPTERS; i++) {
+		if ((i2c_adap[i]->speed != 0) && (i2c_adap[i]->init != NULL)) {
+			i2c_adap[i]->init(i2c_adap[i]->speed, i2c_adap[i]->slaveaddr);
+			if (gd->flags & GD_FLG_RELOC)
+				i2c_adap[i]->init_done = 1;
+		}
+	}
+}
+
+/*
+ * Probe the given I2C chip address.  Returns 0 if a chip responded,
+ * not 0 on failure.
+ */
+int i2c_probe(u_int8_t chip)
+{
+	return(ADAP(i2c_cur_bus)->probe(chip));
+}
+
+/*
+ * Read/Write interface:
+ *   chip:    I2C chip address, range 0..127
+ *   addr:    Memory (register) address within the chip
+ *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:  Where to read/write the data
+ *   len:     How many bytes to read/write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(u_int8_t chip, unsigned int addr, int alen,
+				u_int8_t *buffer, int len)
+{
+	return(ADAP(i2c_cur_bus)->read(chip, addr, alen, buffer, len));
+}
+
+int i2c_write(u_int8_t chip, unsigned int addr, int alen,
+				u_int8_t *buffer, int len)
+{
+	return(ADAP(i2c_cur_bus)->write(chip, addr, alen, buffer, len));
+}
+
+unsigned int i2c_set_bus_speed(unsigned int speed)
+{
+	return(ADAP(i2c_cur_bus)->set_bus_speed(speed));
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+	return(ADAP(i2c_cur_bus)->get_bus_speed());
+}
+
+u_int8_t i2c_reg_read(u_int8_t addr, u_int8_t reg)
+{
+	u_int8_t buf;
+
+#ifdef CONFIG_8xx
+	/* MPC8xx needs this.  Maybe one day we can get rid of it. */
+	i2c_init_bus(i2c_cur_bus, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+	i2c_read(addr, reg, 1, &buf, 1);
+
+#ifdef DEBUG
+	printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
+		 __func__, i2c_cur_bus, addr, reg, buf);
+#endif
+
+	return buf;
+}
+
+void i2c_reg_write(u_int8_t addr, u_int8_t reg, u_int8_t val)
+{
+#ifdef CONFIG_8xx
+	/* MPC8xx needs this.  Maybe one day we can get rid of it. */
+	i2c_init_bus(i2c_cur_bus, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+
+#ifdef DEBUG
+	printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
+	       __func__, i2c_cur_bus, addr, reg, val);
+#endif
+
+	i2c_write(addr, reg, 1, &val, 1);
+}
+
+void inline __i2c_init(unsigned int speed, int slaveaddr)
+{
+	i2c_init_bus(i2c_cur_bus, speed, slaveaddr);
+}
+
+void inline i2c_init(unsigned int speed, int slaveaddr)
+	__attribute__((weak, alias("__i2c_init")));
diff -purN u-boot-i2c.orig/drivers/i2c/Makefile u-boot-i2c/drivers/i2c/Makefile
--- u-boot-i2c.orig/drivers/i2c/Makefile	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/i2c/Makefile	2009-02-12 10:46:00.000000000 -0800
@@ -27,12 +27,13 @@ LIB	:= $(obj)libi2c.a
 
 COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
-COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
-COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
-COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
-COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += omap24xx_i2c.o
+COBJS-$(CONFIG_MXC_I2C) += mxc_i2c.o
+COBJS-$(CONFIG_OMAP1510_I2C) += omap1510_i2c.o
+COBJS-$(CONFIG_OMAP24XX_I2C) += omap24xx_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_SM502_I2C) += sm502_i2c.o
+COBJS-$(CONFIG_NEW_I2C) += i2c_core.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff -purN u-boot-i2c.orig/include/i2c.h u-boot-i2c/include/i2c.h
--- u-boot-i2c.orig/include/i2c.h	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/i2c.h	2009-02-12 11:00:50.000000000 -0800
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2009 Sergey Kubushyn <ksi at koi8.net>
+ * Changes for multibus/multiadapter I2C support.
+ *
  * (C) Copyright 2001
  * Gerald Van Baren, Custom IDEAS, vanbaren at cideas.com.
  *
@@ -46,14 +49,20 @@
  */
 #define I2C_RXTX_LEN	128	/* maximum tx/rx buffer length */
 
-#if defined(CONFIG_I2C_MULTI_BUS)
-#define CONFIG_SYS_MAX_I2C_BUS		2
-#define I2C_GET_BUS()		i2c_get_bus_num()
-#define I2C_SET_BUS(a)		i2c_set_bus_num(a)
+#ifndef CONFIG_SYS_NUM_I2C_ADAPTERS
+#define CONFIG_SYS_NUM_I2C_ADAPTERS	1
+#endif
+
+#if !defined(CONFIG_SYS_I2C_MAX_HOPS) || (CONFIG_SYS_I2C_MAX_HOPS == 0)
+#define CONFIG_SYS_I2C_DIRECT_BUS	1
+#if !defined(CONFIG_SYS_NUM_I2C_BUSSES) || (CONFIG_SYS_NUM_I2C_BUSSES != CONFIG_SYS_NUM_I2C_ADAPTERS)
+#define CONFIG_SYS_NUM_I2C_BUSSES	CONFIG_SYS_NUM_I2C_ADAPTERS
+#endif
 #else
-#define CONFIG_SYS_MAX_I2C_BUS		1
-#define I2C_GET_BUS()		0
-#define I2C_SET_BUS(a)
+#undef CONFIG_SYS_I2C_DIRECT_BUS
+#ifndef CONFIG_SYS_NUM_I2C_BUSSES
+#define CONFIG_SYS_NUM_I2C_BUSSES	1
+#endif
 #endif
 
 /* define the I2C bus number for RTC and DTT if not already done */
@@ -67,66 +76,95 @@
 #define CONFIG_SYS_SPD_BUS_NUM		0
 #endif
 
-#ifndef I2C_SOFT_DECLARATIONS
-# if defined(CONFIG_MPC8260)
-#  define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT);
-# elif defined(CONFIG_8xx)
-#  define I2C_SOFT_DECLARATIONS	volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
-# else
-#  define I2C_SOFT_DECLARATIONS
-# endif
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+#define		ADAP(bus)	i2c_adap[i2c_bus[(bus)].adapter]
+#else
+#define		ADAP(bus)	i2c_adap[(bus)]
 #endif
 
-#ifdef CONFIG_8xx
-/* Set default values for the I2C bus speed and slave address on 8xx. In the
- * future, we'll define these in all 8xx board config files.
- */
-#ifndef	CONFIG_SYS_I2C_SPEED
-#define	CONFIG_SYS_I2C_SPEED	50000
-#endif
+typedef struct i2c_adapter {
+	void		(*init)(int speed, int slaveaddr);
+	int		(*probe)(u_int8_t chip);
+	int		(*read)(u_int8_t chip, uint addr, int alen,
+				u_int8_t *buffer, int len);
+	int		(*write)(u_int8_t chip, uint addr, int alen,
+				u_int8_t *buffer, int len);
+	uint 		(*set_bus_speed)(uint speed);
+	uint		(*get_bus_speed)(void);
+
+	int		speed;
+	int		slaveaddr;
+	int		init_done;
+	char		*name;	
+} i2c_adap_t;
+
+#ifndef CONFIG_SYS_I2C_DIRECT_BUS
+#define I2C_MUX_PCA9540_ID	1
+#define I2C_MUX_PCA9540		{I2C_MUX_PCA9540_ID, "PCA9540B"}
+#define I2C_MUX_PCA9542_ID	2
+#define I2C_MUX_PCA9542		{I2C_MUX_PCA9542_ID, "PCA9542A"}
+#define I2C_MUX_PCA9544_ID	3
+#define I2C_MUX_PCA9544		{I2C_MUX_PCA9544_ID, "PCA9544A"}
+#define I2C_MUX_PCA9547_ID	4
+#define I2C_MUX_PCA9547		{I2C_MUX_PCA9547_ID, "PCA9547A"}
+
+typedef struct i2c_mux {
+	int	id;
+	char	name[16];
+} i2c_mux_t;
+
+typedef struct i2c_next_hop {
+	i2c_mux_t		mux;
+	u_int8_t		chip;
+	u_int8_t		channel;
+} i2c_next_hop_t;
+
+typedef struct i2c_bus_hose {
+	int		adapter;
+	i2c_next_hop_t	next_hop[CONFIG_SYS_I2C_MAX_HOPS];
+} i2c_bus_t;
 
-#ifndef	CONFIG_SYS_I2C_SLAVE
-#define	CONFIG_SYS_I2C_SLAVE	0xFE
-#endif
+#define I2C_NULL_HOP	{{-1, ""}, 0, 0}
+
+extern i2c_bus_t	i2c_bus[];
 #endif
 
+extern i2c_adap_t	*i2c_adap[];
+
 /*
- * Initialization, must be called once on start up, may be called
- * repeatedly to change the speed and slave addresses.
+ * i2c_get_bus_num:
+ *
+ *  Returns index of currently active I2C bus.  Zero-based.
  */
-void i2c_init(int speed, int slaveaddr);
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-void i2c_init_board(void);
-#endif
+unsigned int i2c_get_bus_num(void);
 
-#if defined(CONFIG_I2C_MUX)
+/*
+ * i2c_set_bus_num:
+ *
+ *  Change the active I2C bus.  Subsequent read/write calls will
+ *  go to this one.
+ *
+ *	bus - bus index, zero based
+ *
+ *	Returns: 0 on success, not 0 on failure
+ *
+ */
+int i2c_set_bus_num(unsigned int bus);
 
-typedef struct _mux {
-	uchar	chip;
-	uchar	channel;
-	char	*name;
-	struct _mux	*next;
-} I2C_MUX;
-
-typedef struct _mux_device {
-	int	busid;
-	I2C_MUX	*mux;	/* List of muxes, to reach the device */
-	struct _mux_device	*next;
-} I2C_MUX_DEVICE;
-
-int	i2c_mux_add_device(I2C_MUX_DEVICE *dev);
-
-I2C_MUX_DEVICE	*i2c_mux_search_device(int id);
-I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf);
-int i2x_mux_select_mux(int bus);
-int i2c_mux_ident_muxstring_f (uchar *buf);
-#endif
+/*
+ * i2c_init_all():
+ *
+ * Initializes all I2C adapters in the system. All i2c_adap structures must
+ * be initialized beforehead with function pointers and data, including
+ * speed and slaveaddr. Returns 0 on success, non-0 on failure.
+ */
+void i2c_init_all(void);
 
 /*
  * Probe the given I2C chip address.  Returns 0 if a chip responded,
  * not 0 on failure.
  */
-int i2c_probe(uchar chip);
+int i2c_probe(u_int8_t chip);
 
 /*
  * Read/Write interface:
@@ -140,88 +178,62 @@ int i2c_probe(uchar chip);
  *
  *   Returns: 0 on success, not 0 on failure
  */
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len);
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len);
+int i2c_read(u_int8_t chip, unsigned int addr, int alen,
+				u_int8_t *buffer, int len);
+
+int i2c_write(u_int8_t chip, unsigned int addr, int alen,
+				u_int8_t *buffer, int len);
 
 /*
  * Utility routines to read/write registers.
  */
-static inline u8 i2c_reg_read(u8 addr, u8 reg)
-{
-	u8 buf;
-
-#ifdef CONFIG_8xx
-	/* MPC8xx needs this.  Maybe one day we can get rid of it. */
-	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
-
-#ifdef DEBUG
-	printf("%s: addr=0x%02x, reg=0x%02x\n", __func__, addr, reg);
-#endif
-
-	i2c_read(addr, reg, 1, &buf, 1);
+u_int8_t i2c_reg_read(u_int8_t addr, u_int8_t reg);
 
-	return buf;
-}
-
-static inline void i2c_reg_write(u8 addr, u8 reg, u8 val)
-{
-#ifdef CONFIG_8xx
-	/* MPC8xx needs this.  Maybe one day we can get rid of it. */
-	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
-
-#ifdef DEBUG
-	printf("%s: addr=0x%02x, reg=0x%02x, val=0x%02x\n",
-	       __func__, addr, reg, val);
-#endif
-
-	i2c_write(addr, reg, 1, &val, 1);
-}
-
-/*
- * Functions for setting the current I2C bus and its speed
- */
+void i2c_reg_write(u_int8_t addr, u_int8_t reg, u_int8_t val);
 
 /*
- * i2c_set_bus_num:
+ * i2c_set_bus_speed:
  *
- *  Change the active I2C bus.  Subsequent read/write calls will
- *  go to this one.
+ *  Change the speed of the active I2C bus
  *
- *	bus - bus index, zero based
+ *	speed - bus speed in Hz
  *
- *	Returns: 0 on success, not 0 on failure
+ *	Returns: new bus speed
  *
  */
-int i2c_set_bus_num(unsigned int bus);
+unsigned int i2c_set_bus_speed(unsigned int speed);
 
 /*
- * i2c_get_bus_num:
+ * i2c_get_bus_speed:
  *
- *  Returns index of currently active I2C bus.  Zero-based.
+ *  Returns speed of currently active I2C bus in Hz
  */
 
-unsigned int i2c_get_bus_num(void);
+unsigned int i2c_get_bus_speed(void);
 
 /*
- * i2c_set_bus_speed:
- *
- *  Change the speed of the active I2C bus
- *
- *	speed - bus speed in Hz
- *
- *	Returns: 0 on success, not 0 on failure
+ * i2c_reloc_fixup:
  *
+ * Adjusts I2C pointers after U-Boot is relocated to DRAM
  */
-int i2c_set_bus_speed(unsigned int);
+void i2c_reloc_fixup(void);
+
+#ifndef I2C_SOFT_DEFS
+# if defined(CONFIG_MPC8260)
+#  define I2C_SOFT_DEFS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT);
+# elif defined(CONFIG_8xx)
+#  define I2C_SOFT_DEFS	volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+# else
+#  define I2C_SOFT_DEFS
+# endif
 
 /*
- * i2c_get_bus_speed:
- *
- *  Returns speed of currently active I2C bus in Hz
+ * Initialization, must be called once on start up, may be called
+ * repeatedly to change the speed and slave addresses.
  */
-
-unsigned int i2c_get_bus_speed(void);
+void i2c_init(unsigned int speed, int slaveaddr);
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+void i2c_init_board(void);
+#endif
 
 #endif	/* _I2C_H_ */


More information about the U-Boot mailing list