U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
February 2009
- 181 participants
- 548 discussions
Signed-off-by: Derek Ou <dou(a)siconix.com>
---
drivers/mtd/nand/nand_util.c | 25 ++++++++++++++++++-------
1 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
index 6ba52b3..b9d292a 100644
--- a/drivers/mtd/nand/nand_util.c
+++ b/drivers/mtd/nand/nand_util.c
@@ -475,25 +475,36 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
{
int rval;
size_t left_to_write = *length;
+ size_t page_offset, pad_len = 0;
size_t len_incl_bad;
u_char *p_buffer = buffer;
- /* Reject writes, which are not page aligned */
- if ((offset & (nand->writesize - 1)) != 0 ||
- (*length & (nand->writesize - 1)) != 0) {
- printf ("Attempt to write non page aligned data\n");
+ /* Reject writes when offset is not page aligned */
+ if ((offset & (nand->writesize - 1)) != 0 ) {
+ printf ("Attempt to write address non page aligned\n");
return -EINVAL;
}
- len_incl_bad = get_len_incl_bad (nand, offset, *length);
+ /* Pad write length if it's not page aligned */
+ page_offset = left_to_write & (nand->writesize - 1);
+ if (page_offset != 0) {
+ pad_len = nand->writesize - page_offset;
+ left_to_write += pad_len;
+ }
+
+ len_incl_bad = get_len_incl_bad (nand, offset, left_to_write);
if ((offset + len_incl_bad) >= nand->size) {
printf ("Attempt to write outside the flash area\n");
return -EINVAL;
}
- if (len_incl_bad == *length) {
- rval = nand_write (nand, offset, length, buffer);
+ /* now, pad data with 0xff */
+ if (page_offset != 0)
+ memset(buffer + *length, 0xff, pad_len);
+
+ if (len_incl_bad == left_to_write) {
+ rval = nand_write (nand, offset, &left_to_write, buffer);
if (rval != 0)
printf ("NAND write to offset %zx failed %d\n",
offset, rval);
--
1.5.4.3
5
9
Add missing #endif in include/i2c.h
Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
---
diff -purN u-boot-i2c.ORIG/include/i2c.h u-boot-i2c/include/i2c.h
--- u-boot-i2c.ORIG/include/i2c.h 2009-02-13 16:34:36.000000000 -0800
+++ u-boot-i2c/include/i2c.h 2009-02-13 16:25:52.000000000 -0800
@@ -226,6 +226,7 @@ void i2c_reloc_fixup(void);
# else
# define I2C_SOFT_DEFS
# endif
+#endif
/*
* Initialization, must be called once on start up, may be called
2
2

17 Feb '09
Initial multiadapter/multibus I2C support.
Signed-off-by: Sergey Kubushyn <ksi(a)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(a)koi8.net
+ *
+ * Changes for unified multibus/multiadapter I2C support.
+ *
* (C) Copyright 2001
* Gerald Van Baren, Custom IDEAS, vanbaren(a)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@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@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(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio(a)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(a)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(a)koi8.net>
+ * Changes for multibus/multiadapter I2C support.
+ *
* (C) Copyright 2001
* Gerald Van Baren, Custom IDEAS, vanbaren(a)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_ */
2
2

17 Feb '09
Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
---
diff -purN u-boot-i2c.orig/include/configs/ATUM8548.h u-boot-i2c/include/configs/ATUM8548.h
--- u-boot-i2c.orig/include/configs/ATUM8548.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/ATUM8548.h 2009-02-12 10:46:00.000000000 -0800
@@ -229,14 +229,14 @@
/*
* I2C
*/
-#define CONFIG_FSL_I2C /* Use FSL common I2C driver */
-#define CONFIG_HARD_I2C /* I2C with hardware support*/
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */
-#define CONFIG_SYS_I2C_EEPROM_ADDR 0x57
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_NOPROBES {0x69} /* Don't probe these addrs */
-#define CONFIG_SYS_I2C_OFFSET 0x3000
+#define CONFIG_NEW_I2C /* New I2C code */
+#define CONFIG_FSL_I2C /* Use FSL common I2C driver */
+#define CONFIG_SYS_FSL_I2C_SPEED 400000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C_EEPROM_ADDR 0x57
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_I2C_NOPROBES {0x69} /* Don't probe these addrs */
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x3000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
/*
* General PCI
diff -purN u-boot-i2c.orig/include/configs/CPU86.h u-boot-i2c/include/configs/CPU86.h
--- u-boot-i2c.orig/include/configs/CPU86.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/CPU86.h 2009-02-12 10:46:00.000000000 -0800
@@ -123,10 +123,12 @@
/*-----------------------------------------------------------------------
* I2C/EEPROM/RTC configuration
*/
-#define CONFIG_SOFT_I2C /* Software I2C support enabled */
-
-# define CONFIG_SYS_I2C_SPEED 50000
-# define CONFIG_SYS_I2C_SLAVE 0xFE
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
diff -purN u-boot-i2c.orig/include/configs/CPU87.h u-boot-i2c/include/configs/CPU87.h
--- u-boot-i2c.orig/include/configs/CPU87.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/CPU87.h 2009-02-12 10:46:00.000000000 -0800
@@ -127,10 +127,12 @@
/*-----------------------------------------------------------------------
* I2C/EEPROM/RTC configuration
*/
-#define CONFIG_SOFT_I2C /* Software I2C support enabled */
-
-# define CONFIG_SYS_I2C_SPEED 50000
-# define CONFIG_SYS_I2C_SLAVE 0xFE
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
diff -purN u-boot-i2c.orig/include/configs/GEN860T.h u-boot-i2c/include/configs/GEN860T.h
--- u-boot-i2c.orig/include/configs/GEN860T.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/GEN860T.h 2009-02-12 10:46:00.000000000 -0800
@@ -180,6 +180,11 @@
#endif
#ifdef CONFIG_SOFT_I2C
+#define CONFIG_NEW_I2C
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
#define PB_SCL 0x00000020 /* PB 26 */
#define PB_SDA 0x00000010 /* PB 27 */
#define I2C_INIT (immr->im_cpm.cp_pbdir |= PB_SCL)
diff -purN u-boot-i2c.orig/include/configs/HIDDEN_DRAGON.h u-boot-i2c/include/configs/HIDDEN_DRAGON.h
--- u-boot-i2c.orig/include/configs/HIDDEN_DRAGON.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/HIDDEN_DRAGON.h 2009-02-12 10:46:00.000000000 -0800
@@ -177,6 +177,11 @@
#ifdef CONFIG_SOFT_I2C
#error "Soft I2C is not configured properly. Please review!"
+#define CONFIG_NEW_I2C
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */
#define I2C_ACTIVE (iop->pdir |= 0x00010000)
#define I2C_TRISTATE (iop->pdir &= ~0x00010000)
diff -purN u-boot-i2c.orig/include/configs/HMI10.h u-boot-i2c/include/configs/HMI10.h
--- u-boot-i2c.orig/include/configs/HMI10.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/HMI10.h 2009-02-12 10:46:00.000000000 -0800
@@ -91,12 +91,12 @@
#undef CONFIG_SYS_LOADS_BAUD_CHANGE /* don't allow baudrate change */
/* enable I2C and select the hardware/software driver */
-#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-
-#define CONFIG_SYS_I2C_SPEED 40000 /* 40 kHz is supposed to work */
-#define CONFIG_SYS_I2C_SLAVE 0xFE
-
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 40000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/* Software (bit-bang) I2C driver configuration */
#define PB_SCL 0x00000020 /* PB 26 */
#define PB_SDA 0x00000010 /* PB 27 */
diff -purN u-boot-i2c.orig/include/configs/IAD210.h u-boot-i2c/include/configs/IAD210.h
--- u-boot-i2c.orig/include/configs/IAD210.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/IAD210.h 2009-02-12 10:46:00.000000000 -0800
@@ -109,10 +109,12 @@
/* enable I2C and select the hardware/software driver */
#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-# define CONFIG_SYS_I2C_SPEED 50000
-# define CONFIG_SYS_I2C_SLAVE 0xDD
-# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xDD
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
@@ -131,6 +133,8 @@
#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
+#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
+
/*
* Command line configuration.
diff -purN u-boot-i2c.orig/include/configs/ICU862.h u-boot-i2c/include/configs/ICU862.h
--- u-boot-i2c.orig/include/configs/ICU862.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/ICU862.h 2009-02-12 10:46:00.000000000 -0800
@@ -105,11 +105,12 @@
/* enable I2C and select the hardware/software driver */
#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-# define CONFIG_SYS_I2C_SPEED 50000
-# define CONFIG_SYS_I2C_SLAVE 0xFE
-# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
-# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
@@ -131,6 +132,9 @@
#define CONFIG_RTC_MPC8xx /* use internal RTC of MPC8xx */
+#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
+
/*
* Command line configuration.
diff -purN u-boot-i2c.orig/include/configs/IDS8247.h u-boot-i2c/include/configs/IDS8247.h
--- u-boot-i2c.orig/include/configs/IDS8247.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/IDS8247.h 2009-02-12 10:46:00.000000000 -0800
@@ -72,10 +72,12 @@
/* enable I2C and select the hardware/software driver */
#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 400000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0x7F
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
diff -purN u-boot-i2c.orig/include/configs/IP860.h u-boot-i2c/include/configs/IP860.h
--- u-boot-i2c.orig/include/configs/IP860.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/IP860.h 2009-02-12 10:46:00.000000000 -0800
@@ -59,7 +59,12 @@
/* enable I2C and select the hardware/software driver */
#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 50000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
@@ -76,9 +81,6 @@
else immr->im_cpm.cp_pbdat &= ~PB_SCL
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
-
-# define CONFIG_SYS_I2C_SPEED 50000
-# define CONFIG_SYS_I2C_SLAVE 0xFE
# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* EEPROM X24C16 */
# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 /* bytes of address */
/* mask of address bits that overflow into the "EEPROM chip address" */
diff -purN u-boot-i2c.orig/include/configs/IPHASE4539.h u-boot-i2c/include/configs/IPHASE4539.h
--- u-boot-i2c.orig/include/configs/IPHASE4539.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/IPHASE4539.h 2009-02-12 10:46:00.000000000 -0800
@@ -109,14 +109,15 @@
* configuration items that the driver uses to drive the port pins.
*/
#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 400000
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0x7F
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
-#ifdef CONFIG_SOFT_I2C
#define I2C_PORT 3 /* Port A=0, B=1, C=2, D=3 */
#define I2C_ACTIVE (iop->pdir |= 0x00010000)
#define I2C_TRISTATE (iop->pdir &= ~0x00010000)
@@ -126,7 +127,6 @@
#define I2C_SCL(bit) if(bit) iop->pdat |= 0x00020000; \
else iop->pdat &= ~0x00020000
#define I2C_DELAY udelay(5) /* 1/4 I2C clock duration */
-#endif /* CONFIG_SOFT_I2C */
/*
diff -purN u-boot-i2c.orig/include/configs/KUP4K.h u-boot-i2c/include/configs/KUP4K.h
--- u-boot-i2c.orig/include/configs/KUP4K.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/KUP4K.h 2009-02-12 10:46:00.000000000 -0800
@@ -107,12 +107,12 @@
* enable I2C and select the hardware/software driver
*/
#undef CONFIG_HARD_I2C /* I2C with hardware support */
-#define CONFIG_SOFT_I2C 1 /* I2C bit-banged */
-
-#define CONFIG_SYS_I2C_SPEED 93000 /* 93 kHz is supposed to work */
-#define CONFIG_SYS_I2C_SLAVE 0xFE
-
-#ifdef CONFIG_SOFT_I2C
+#define CONFIG_NEW_I2C
+#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
+#define CONFIG_SYS_SOFT_I2C_SPEED 93000 /* 93 kHz is supposed to work */
+#define CONFIG_SYS_SOFT_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_ADAPTERS {&soft_i2c_adap[0]}
/*
* Software (bit-bang) I2C driver configuration
*/
@@ -128,7 +128,6 @@
#define I2C_SCL(bit) if(bit) immr->im_cpm.cp_pbdat |= PB_SCL; \
else immr->im_cpm.cp_pbdat &= ~PB_SCL
#define I2C_DELAY udelay(2) /* 1/4 I2C clock duration */
-#endif /* CONFIG_SOFT_I2C */
/*-----------------------------------------------------------------------
diff -purN u-boot-i2c.orig/include/configs/M52277EVB.h u-boot-i2c/include/configs/M52277EVB.h
--- u-boot-i2c.orig/include/configs/M52277EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M52277EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -144,13 +144,13 @@
#define CONFIG_MCFTMR
#undef CONFIG_MCFPIT
-/* I2c */
+/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hardware support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000 /* I2C speed and slave address */
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x58000
+#define CONFIG_SYS_FSL_I2C_SPEED 80000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x58000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
/* DSPI and Serial Flash */
diff -purN u-boot-i2c.orig/include/configs/M5235EVB.h u-boot-i2c/include/configs/M5235EVB.h
--- u-boot-i2c.orig/include/configs/M5235EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5235EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -101,12 +101,12 @@
#undef CONFIG_MCFPIT
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x00000300
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x00000300
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_SYS_I2C_PINMUX_REG (gpio->par_qspi)
#define CONFIG_SYS_I2C_PINMUX_CLR ~(GPIO_PAR_FECI2C_SCL_MASK | GPIO_PAR_FECI2C_SDA_MASK)
diff -purN u-boot-i2c.orig/include/configs/M5253DEMO.h u-boot-i2c/include/configs/M5253DEMO.h
--- u-boot-i2c.orig/include/configs/M5253DEMO.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5253DEMO.h 2009-02-12 10:46:00.000000000 -0800
@@ -119,11 +119,12 @@
#define CONFIG_HOSTNAME M5253DEMO
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x00000280
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x00000280
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_SYS_I2C_PINMUX_REG (*(u32 *) (CONFIG_SYS_MBAR+0x19C))
#define CONFIG_SYS_I2C_PINMUX_CLR (0xFFFFE7FF)
diff -purN u-boot-i2c.orig/include/configs/M5271EVB.h u-boot-i2c/include/configs/M5271EVB.h
--- u-boot-i2c.orig/include/configs/M5271EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5271EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -111,12 +111,12 @@
#endif
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x00000300
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x00000300
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_BOOTDELAY 1 /* autoboot after 1 seconds */
diff -purN u-boot-i2c.orig/include/configs/M5275EVB.h u-boot-i2c/include/configs/M5275EVB.h
--- u-boot-i2c.orig/include/configs/M5275EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5275EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -111,12 +111,12 @@
#endif
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x00000300
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x00000300
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_SYS_I2C_PINMUX_REG (gpio_reg->par_feci2c)
#define CONFIG_SYS_I2C_PINMUX_CLR (0xFFF0)
diff -purN u-boot-i2c.orig/include/configs/M53017EVB.h u-boot-i2c/include/configs/M53017EVB.h
--- u-boot-i2c.orig/include/configs/M53017EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M53017EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -98,12 +98,12 @@
#undef CONFIG_MCFPIT
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x58000
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x58000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_BOOTDELAY 1 /* autoboot after 5 seconds */
diff -purN u-boot-i2c.orig/include/configs/M5329EVB.h u-boot-i2c/include/configs/M5329EVB.h
--- u-boot-i2c.orig/include/configs/M5329EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5329EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -97,12 +97,12 @@
#undef CONFIG_MCFPIT
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x58000
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x58000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_BOOTDELAY 1 /* autoboot after 5 seconds */
diff -purN u-boot-i2c.orig/include/configs/M5373EVB.h u-boot-i2c/include/configs/M5373EVB.h
--- u-boot-i2c.orig/include/configs/M5373EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5373EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -97,12 +97,12 @@
#undef CONFIG_MCFPIT
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x58000
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x58000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
#define CONFIG_BOOTDELAY 1 /* autoboot after 5 seconds */
diff -purN u-boot-i2c.orig/include/configs/M54451EVB.h u-boot-i2c/include/configs/M54451EVB.h
--- u-boot-i2c.orig/include/configs/M54451EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M54451EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -157,12 +157,12 @@
#undef CONFIG_MCFPIT
/* I2c */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hardware support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000 /* I2C speed and slave address */
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x58000
+#define CONFIG_SYS_FSL_I2C_SPEED 80000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x58000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
/* DSPI and Serial Flash */
diff -purN u-boot-i2c.orig/include/configs/M54455EVB.h u-boot-i2c/include/configs/M54455EVB.h
--- u-boot-i2c.orig/include/configs/M54455EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M54455EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -192,12 +192,12 @@
#undef CONFIG_MCFPIT
/* I2c */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hardware support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000 /* I2C speed and slave address */
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x58000
+#define CONFIG_SYS_FSL_I2C_SPEED 80000 /* I2C speed and slave address */
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSLI2C_OFFSET 0x58000
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
/* DSPI and Serial Flash */
diff -purN u-boot-i2c.orig/include/configs/M5475EVB.h u-boot-i2c/include/configs/M5475EVB.h
--- u-boot-i2c.orig/include/configs/M5475EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5475EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -122,12 +122,12 @@
#endif
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x00008F00
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x00008F00
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
/* PCI */
diff -purN u-boot-i2c.orig/include/configs/M5485EVB.h u-boot-i2c/include/configs/M5485EVB.h
--- u-boot-i2c.orig/include/configs/M5485EVB.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/configs/M5485EVB.h 2009-02-12 10:46:00.000000000 -0800
@@ -119,12 +119,12 @@
#endif
/* I2C */
+#define CONFIG_NEW_I2C
#define CONFIG_FSL_I2C
-#define CONFIG_HARD_I2C /* I2C with hw support */
-#undef CONFIG_SOFT_I2C /* I2C bit-banged */
-#define CONFIG_SYS_I2C_SPEED 80000
-#define CONFIG_SYS_I2C_SLAVE 0x7F
-#define CONFIG_SYS_I2C_OFFSET 0x00008F00
+#define CONFIG_SYS_FSL_I2C_SPEED 80000
+#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
+#define CONFIG_SYS_FSL_I2C_OFFSET 0x00008F00
+#define CONFIG_SYS_I2C_ADAPTERS {&fsl_i2c_adap[0]}
#define CONFIG_SYS_IMMR CONFIG_SYS_MBAR
/* PCI */
2
2

17 Feb '09
Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
---
diff -purN u-boot-i2c.orig/drivers/i2c/soft_i2c.c u-boot-i2c/drivers/i2c/soft_i2c.c
--- u-boot-i2c.orig/drivers/i2c/soft_i2c.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/i2c/soft_i2c.c 2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,8 @@
/*
+ * Copyright (c) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
* (C) Copyright 2001, 2002
* Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
*
@@ -72,375 +76,461 @@ DECLARE_GLOBAL_DATA_PTR;
#define PRINTD(fmt,args...)
#endif
-#if defined(CONFIG_I2C_MULTI_BUS)
-static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0;
-#endif /* CONFIG_I2C_MULTI_BUS */
-
/*-----------------------------------------------------------------------
* Local functions
*/
-#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
-static void send_reset (void);
+#ifndef I2C_INIT
+#define I2C_INIT do {} while(0)
#endif
-static void send_start (void);
-static void send_stop (void);
-static void send_ack (int);
-static int write_byte (uchar byte);
-static uchar read_byte (int);
-
-#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
-/*-----------------------------------------------------------------------
- * Send a reset sequence consisting of 9 clocks with the data signal high
- * to clock any confused device back into an idle state. Also send a
- * <stop> at the end of the sequence for belts & suspenders.
- */
-static void send_reset(void)
-{
- I2C_SOFT_DECLARATIONS /* intentional without ';' */
- int j;
-
- I2C_SCL(1);
- I2C_SDA(1);
-#ifdef I2C_INIT
- I2C_INIT;
-#endif
- I2C_TRISTATE;
- for(j = 0; j < 9; j++) {
- I2C_SCL(0);
- I2C_DELAY;
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- I2C_DELAY;
- }
- send_stop();
- I2C_TRISTATE;
-}
+#ifndef I2C_INIT2
+#define I2C_INIT2 do {} while(0)
+#endif
+#ifndef I2C_INIT3
+#define I2C_INIT3 do {} while(0)
#endif
+#ifndef I2C_INIT4
+#define I2C_INIT4 do {} while(0)
+#endif
+
/*-----------------------------------------------------------------------
* START: High -> Low on SDA while SCL is High
*/
-static void send_start(void)
-{
- I2C_SOFT_DECLARATIONS /* intentional without ';' */
-
- I2C_DELAY;
- I2C_SDA(1);
- I2C_ACTIVE;
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- I2C_SDA(0);
- I2C_DELAY;
+#define I2C_SOFT_SEND_START(n) \
+static void send_start##n(void) \
+{ \
+ I2C_SOFT_DECLARATIONS##n \
+ I2C_DELAY##n; \
+ I2C_SDA##n(1); \
+ I2C_ACTIVE##n; \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ I2C_SDA##n(0); \
+ I2C_DELAY##n; \
}
+
/*-----------------------------------------------------------------------
* STOP: Low -> High on SDA while SCL is High
*/
-static void send_stop(void)
-{
- I2C_SOFT_DECLARATIONS /* intentional without ';' */
-
- I2C_SCL(0);
- I2C_DELAY;
- I2C_SDA(0);
- I2C_ACTIVE;
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- I2C_SDA(1);
- I2C_DELAY;
- I2C_TRISTATE;
+#define I2C_SOFT_SEND_STOP(n) \
+static void send_stop##n(void) \
+{ \
+ I2C_SOFT_DECLARATIONS##n \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_SDA##n(0); \
+ I2C_ACTIVE##n; \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ I2C_SDA##n(1); \
+ I2C_DELAY##n; \
+ I2C_TRISTATE##n; \
}
/*-----------------------------------------------------------------------
* ack should be I2C_ACK or I2C_NOACK
*/
-static void send_ack(int ack)
-{
- I2C_SOFT_DECLARATIONS /* intentional without ';' */
-
- I2C_SCL(0);
- I2C_DELAY;
- I2C_ACTIVE;
- I2C_SDA(ack);
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- I2C_DELAY;
- I2C_SCL(0);
- I2C_DELAY;
+#define I2C_SOFT_SEND_ACK(n) \
+static void send_ack##n(int ack) \
+{ \
+ I2C_SOFT_DECLARATIONS##n \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_ACTIVE##n; \
+ I2C_SDA##n(ack); \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ I2C_DELAY##n; \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
}
/*-----------------------------------------------------------------------
- * Send 8 bits and look for an acknowledgement.
+ * Send a reset sequence consisting of 9 clocks with the data signal high
+ * to clock any confused device back into an idle state. Also send a
+ * <stop> at the end of the sequence for belts & suspenders.
*/
-static int write_byte(uchar data)
-{
- I2C_SOFT_DECLARATIONS /* intentional without ';' */
- int j;
- int nack;
-
- I2C_ACTIVE;
- for(j = 0; j < 8; j++) {
- I2C_SCL(0);
- I2C_DELAY;
- I2C_SDA(data & 0x80);
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- I2C_DELAY;
-
- data <<= 1;
- }
-
- /*
- * Look for an <ACK>(negative logic) and return it.
- */
- I2C_SCL(0);
- I2C_DELAY;
- I2C_SDA(1);
- I2C_TRISTATE;
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- I2C_DELAY;
- nack = I2C_READ;
- I2C_SCL(0);
- I2C_DELAY;
- I2C_ACTIVE;
-
- return(nack); /* not a nack is an ack */
+#define I2C_SOFT_SEND_RESET(n) \
+static void send_reset##n(void) \
+{ \
+ I2C_SOFT_DECLARATIONS##n \
+ int j; \
+ I2C_SCL##n(1); \
+ I2C_SDA##n(1); \
+ I2C_INIT##n; \
+ I2C_TRISTATE##n; \
+ for(j = 0; j < 9; j++) { \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ I2C_DELAY##n; \
+ } \
+ send_stop##n(); \
+ I2C_TRISTATE##n; \
}
-#if defined(CONFIG_I2C_MULTI_BUS)
-/*
- * Functions for multiple I2C bus handling
- */
-unsigned int i2c_get_bus_num(void)
-{
- return i2c_bus_num;
-}
-
-int i2c_set_bus_num(unsigned int bus)
-{
-#if defined(CONFIG_I2C_MUX)
- if (bus < CONFIG_SYS_MAX_I2C_BUS) {
- i2c_bus_num = bus;
- } else {
- int ret;
-
- ret = i2x_mux_select_mux(bus);
- if (ret == 0)
- i2c_bus_num = bus;
- else
- return ret;
- }
-#else
- if (bus >= CONFIG_SYS_MAX_I2C_BUS)
- return -1;
- i2c_bus_num = bus;
-#endif
- return 0;
-}
-/* TODO: add 100/400k switching */
-unsigned int i2c_get_bus_speed(void)
-{
- return CONFIG_SYS_I2C_SPEED;
+/*-----------------------------------------------------------------------
+ * Send 8 bits and look for an acknowledgement.
+ */
+#define I2C_SOFT_WRITE_BYTE(n) \
+static int write_byte##n(uchar data) \
+{ \
+ I2C_SOFT_DECLARATIONS##n \
+ int j; \
+ int nack; \
+ I2C_ACTIVE##n; \
+ for(j = 0; j < 8; j++) { \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_SDA##n(data & 0x80); \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ I2C_DELAY##n; \
+ data <<= 1; \
+ } \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_SDA##n(1); \
+ I2C_TRISTATE##n; \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ I2C_DELAY##n; \
+ nack = I2C_READ##n; \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_ACTIVE##n; \
+ return(nack); \
}
-int i2c_set_bus_speed(unsigned int speed)
-{
- if (speed != CONFIG_SYS_I2C_SPEED)
- return -1;
-
- return 0;
-}
-#endif
/*-----------------------------------------------------------------------
* if ack == I2C_ACK, ACK the byte so can continue reading, else
* send I2C_NOACK to end the read.
*/
-static uchar read_byte(int ack)
-{
- I2C_SOFT_DECLARATIONS /* intentional without ';' */
- int data;
- int j;
-
- /*
- * Read 8 bits, MSB first.
- */
- I2C_TRISTATE;
- I2C_SDA(1);
- data = 0;
- for(j = 0; j < 8; j++) {
- I2C_SCL(0);
- I2C_DELAY;
- I2C_SCL(1);
- I2C_DELAY;
- data <<= 1;
- data |= I2C_READ;
- I2C_DELAY;
- }
- send_ack(ack);
-
- return(data);
-}
-
-/*=====================================================================*/
-/* Public Functions */
-/*=====================================================================*/
+#define I2C_SOFT_READ_BYTE(n) \
+static uchar read_byte##n(int ack) \
+{ \
+ I2C_SOFT_DECLARATIONS##n \
+ int data; \
+ int j; \
+ I2C_TRISTATE##n; \
+ I2C_SDA##n(1); \
+ data = 0; \
+ for(j = 0; j < 8; j++) { \
+ I2C_SCL##n(0); \
+ I2C_DELAY##n; \
+ I2C_SCL##n(1); \
+ I2C_DELAY##n; \
+ data <<= 1; \
+ data |= I2C_READ##n; \
+ I2C_DELAY##n; \
+ } \
+ send_ack##n(ack); \
+ return(data); \
+}
-/*-----------------------------------------------------------------------
+
+/*============================================================*/
+/* I2C Ops */
+/*============================================================*/
+
+/*--------------------------------------------------------------
* Initialization
*/
-void i2c_init (int speed, int slaveaddr)
-{
-#if defined(CONFIG_SYS_I2C_INIT_BOARD)
- /* call board specific i2c bus reset routine before accessing the */
- /* environment, which might be in a chip on that bus. For details */
- /* about this problem see doc/I2C_Edge_Conditions. */
- i2c_init_board();
+
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+#define I2C_SOFT_INIT_ADAPTER(n) \
+static void soft_i2c_init##n(int speed, int slaveaddr) \
+{ \
+ /* call board specific i2c bus reset routine before accessing the */ \
+ /* environment, which might be in a chip on that bus. For details */ \
+ /* about this problem see doc/I2C_Edge_Conditions. */ \
+ SOFT_I2C_INIT_BOARD; \
+}
#else
- /*
- * WARNING: Do NOT save speed in a static variable: if the
- * I2C routines are called before RAM is initialized (to read
- * the DIMM SPD, for instance), RAM won't be usable and your
- * system will crash.
- */
- send_reset ();
-#endif
+#define I2C_SOFT_INIT_ADAPTER(n) \
+static void soft_i2c_init##n(int speed, int slaveaddr) \
+{ \
+ /* WARNING: Do NOT save speed in a static variable: if the */ \
+ /* I2C routines are called before RAM is initialized (to read */ \
+ /* the DIMM SPD, for instance), RAM won't be usable and your */ \
+ /* system will crash. */ \
+ send_reset##n(); \
}
+#endif
+
/*-----------------------------------------------------------------------
* Probe to see if a chip is present. Also good for checking for the
* completion of EEPROM writes since the chip stops responding until
* the write completes (typically 10mSec).
*/
-int i2c_probe(uchar addr)
-{
- int rc;
-
- /*
- * perform 1 byte write transaction with just address byte
- * (fake write)
- */
- send_start();
- rc = write_byte ((addr << 1) | 0);
- send_stop();
-
- return (rc ? 1 : 0);
+#define I2C_SOFT_PROBE(n) \
+static int soft_i2c_probe##n(uchar addr) \
+{ \
+ int rc; \
+ /* perform 1 byte write transaction with just address byte */ \
+ /* (fake write) */ \
+ send_start##n(); \
+ rc = write_byte##n((addr << 1) | 0); \
+ send_stop##n(); \
+ return (rc ? 1 : 0); \
}
+
/*-----------------------------------------------------------------------
* Read bytes
*/
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
- int shift;
- PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
- chip, addr, alen, buffer, len);
+#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
+#define RRSS_STOP 0
+#else
+#define RRSS_STOP 1
+#endif
#ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
- /*
- * EEPROM chips that implement "address overflow" are ones
- * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
- * address and the extra bits end up in the "chip address"
- * bit slots. This makes a 24WC08 (1Kbyte) chip look like
- * four 256 byte chips.
- *
- * Note that we consider the length of the address field to
- * still be one byte because the extra address bits are
- * hidden in the chip address.
- */
- chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
-
- PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
- chip, addr);
-#endif
-
- /*
- * Do the addressing portion of a write cycle to set the
- * chip's address pointer. If the address length is zero,
- * don't do the normal write cycle to set the address pointer,
- * there is no address pointer in this chip.
- */
- send_start();
- if(alen > 0) {
- if(write_byte(chip << 1)) { /* write cycle */
- send_stop();
- PRINTD("i2c_read, no chip responded %02X\n", chip);
- return(1);
- }
- shift = (alen-1) * 8;
- while(alen-- > 0) {
- if(write_byte(addr >> shift)) {
- PRINTD("i2c_read, address not <ACK>ed\n");
- return(1);
- }
- shift -= 8;
- }
-
- /* Some I2C chips need a stop/start sequence here,
- * other chips don't work with a full stop and need
- * only a start. Default behaviour is to send the
- * stop/start sequence.
- */
-#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
- send_start();
+#define DO_EEAD_OVF chip |= ((addr >> (alen * 8)) & \
+ CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); \
+ PRINTD("%s: fix addr_overflow: chip %02X addr %02X\n", \
+ __FUNCTION__, chip, addr);
+
#else
- send_stop();
- send_start();
+#define DO_EEAD_OVF
#endif
- }
- /*
- * Send the chip address again, this time for a read cycle.
- * Then read the data. On the last byte, we do a NACK instead
- * of an ACK(len == 0) to terminate the read.
- */
- write_byte((chip << 1) | 1); /* read cycle */
- while(len-- > 0) {
- *buffer++ = read_byte(len == 0);
- }
- send_stop();
- return(0);
+
+#define I2C_SOFT_READ(n) \
+static int soft_i2c_read##n(uchar chip, uint addr, int alen, uchar *buffer, int len) \
+{ \
+ int shift; \
+ PRINTD("%s: chip %02X addr %02X alen %d buffer %p len %d\n", \
+ __FUNCTION__, chip, addr, alen, buffer, len); \
+ /* EEPROM chips that implement "address overflow" are ones */ \
+ /* like Catalyst 24WC04/08/16 which has 9/10/11 bits of */ \
+ /* address and the extra bits end up in the "chip address" */ \
+ /* bit slots. This makes a 24WC08 (1Kbyte) chip look like */ \
+ /* four 256 byte chips. */ \
+ /* */ \
+ /* Note that we consider the length of the address field to */ \
+ /* still be one byte because the extra address bits are */ \
+ /* hidden in the chip address. */ \
+ DO_EEAD_OVF \
+ /* Do the addressing portion of a write cycle to set the */ \
+ /* chip's address pointer. If the address length is zero, */ \
+ /* don't do the normal write cycle to set the address pointer, */ \
+ /* there is no address pointer in this chip. */ \
+ send_start##n(); \
+ if(alen > 0) { \
+ if(write_byte##n(chip << 1)) { /* write cycle */ \
+ send_stop##n(); \
+ PRINTD("%s, no chip responded %02X\n", __FUNCTION__, chip); \
+ return(1); \
+ } \
+ shift = (alen-1) * 8; \
+ while(alen-- > 0) { \
+ if(write_byte##n(addr >> shift)) { \
+ PRINTD("%s, address not <ACK>ed\n", __FUNCTION__); \
+ return(1); \
+ } \
+ shift -= 8; \
+ } \
+ if(RRSS_STOP) { \
+ send_stop##n(); /* reportedly some chips need a full stop */ \
+ } \
+ send_start##n(); \
+ } \
+ /* Send the chip address again, this time for a read cycle. */ \
+ /* Then read the data. On the last byte, we do a NACK instead */ \
+ /* of an ACK(len == 0) to terminate the read. */ \
+ write_byte##n((chip << 1) | 1); /* read cycle */ \
+ while(len-- > 0) { \
+ *buffer++ = read_byte##n(len == 0); \
+ } \
+ send_stop##n(); \
+ return(0); \
}
+
/*-----------------------------------------------------------------------
* Write bytes
*/
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
- int shift, failures = 0;
-
- PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
- chip, addr, alen, buffer, len);
-
- send_start();
- if(write_byte(chip << 1)) { /* write cycle */
- send_stop();
- PRINTD("i2c_write, no chip responded %02X\n", chip);
- return(1);
- }
- shift = (alen-1) * 8;
- while(alen-- > 0) {
- if(write_byte(addr >> shift)) {
- PRINTD("i2c_write, address not <ACK>ed\n");
- return(1);
- }
- shift -= 8;
- }
-
- while(len-- > 0) {
- if(write_byte(*buffer++)) {
- failures++;
- }
- }
- send_stop();
- return(failures);
+#define I2C_SOFT_WRITE(n) \
+static int soft_i2c_write##n(uchar chip, uint addr, int alen, uchar *buffer, int len) \
+{ \
+ int shift, failures = 0; \
+ PRINTD("%s: chip %02X addr %02X alen %d buffer %p len %d\n", \
+ __FUNCTION__, chip, addr, alen, buffer, len); \
+ send_start##n(); \
+ if(write_byte##n(chip << 1)) { /* write cycle */ \
+ send_stop##n(); \
+ PRINTD("%s, no chip responded %02X\n", __FUNCTION__, chip); \
+ return(1); \
+ } \
+ shift = (alen-1) * 8; \
+ while(alen-- > 0) { \
+ if(write_byte##n(addr >> shift)) { \
+ PRINTD("%s, address not <ACK>ed\n", __FUNCTION__); \
+ return(1); \
+ } \
+ shift -= 8; \
+ } \
+ while(len-- > 0) { \
+ if(write_byte##n(*buffer++)) { \
+ failures++; \
+ } \
+ } \
+ send_stop##n(); \
+ return(failures); \
}
+
+
+#define I2C_SOFT_GET_BUS_SPEED(n) \
+static unsigned int soft_i2c_get_bus_speed##n(void) \
+{ \
+ return CONFIG_SYS_SOFT_I2C##n##_SPEED; \
+}
+
+
+#define I2C_SOFT_SET_BUS_SPEED(n) \
+static unsigned int soft_i2c_set_bus_speed##n(unsigned int speed) \
+{ \
+ if (speed != CONFIG_SYS_SOFT_I2C##n##_SPEED) \
+ return -1; \
+ return(speed); \
+}
+
+
+/*============================================================*/
+/* Here comes the real stuff */
+/*============================================================*/
+I2C_SOFT_SEND_START()
+I2C_SOFT_SEND_STOP()
+I2C_SOFT_SEND_ACK()
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET()
+#endif
+I2C_SOFT_WRITE_BYTE()
+I2C_SOFT_READ_BYTE()
+I2C_SOFT_INIT_ADAPTER()
+I2C_SOFT_PROBE()
+I2C_SOFT_READ()
+I2C_SOFT_WRITE()
+I2C_SOFT_GET_BUS_SPEED()
+I2C_SOFT_SET_BUS_SPEED()
+
+#if defined(I2C_SOFT_DECLARATIONS2)
+I2C_SOFT_SEND_START(2)
+I2C_SOFT_SEND_STOP(2)
+I2C_SOFT_SEND_ACK(2)
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET(2)
+#endif
+I2C_SOFT_WRITE_BYTE(2)
+I2C_SOFT_READ_BYTE(2)
+I2C_SOFT_INIT_ADAPTER(2)
+I2C_SOFT_PROBE(2)
+I2C_SOFT_READ(2)
+I2C_SOFT_WRITE(2)
+I2C_SOFT_GET_BUS_SPEED(2)
+I2C_SOFT_SET_BUS_SPEED(2)
+#endif
+
+#if defined(I2C_SOFT_DECLARATIONS3)
+I2C_SOFT_SEND_START(3)
+I2C_SOFT_SEND_STOP(3)
+I2C_SOFT_SEND_ACK(3)
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET(3)
+#endif
+I2C_SOFT_WRITE_BYTE(3)
+I2C_SOFT_READ_BYTE(3)
+I2C_SOFT_INIT_ADAPTER(3)
+I2C_SOFT_PROBE(3)
+I2C_SOFT_READ(3)
+I2C_SOFT_WRITE(3)
+I2C_SOFT_GET_BUS_SPEED(3)
+I2C_SOFT_SET_BUS_SPEED(3)
+#endif
+
+#if defined(I2C_SOFT_DECLARATIONS4)
+I2C_SOFT_SEND_START(4)
+I2C_SOFT_SEND_STOP(4)
+I2C_SOFT_SEND_ACK(4)
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET(4)
+#endif
+I2C_SOFT_WRITE_BYTE(4)
+I2C_SOFT_READ_BYTE(4)
+I2C_SOFT_INIT_ADAPTER(4)
+I2C_SOFT_PROBE(4)
+I2C_SOFT_READ(4)
+I2C_SOFT_WRITE(4)
+I2C_SOFT_GET_BUS_SPEED(4)
+I2C_SOFT_SET_BUS_SPEED(4)
+#endif
+
+i2c_adap_t soft_i2c_adap[] = {
+ {
+ .init = soft_i2c_init,
+ .probe = soft_i2c_probe,
+ .read = soft_i2c_read,
+ .write = soft_i2c_write,
+ .set_bus_speed = soft_i2c_set_bus_speed,
+ .get_bus_speed = soft_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_SOFT_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C_SLAVE,
+ .init_done = 0,
+ .name = "soft-i2c"
+ },
+#if defined(I2C_SOFT_DECLARATIONS2)
+ {
+ .init = soft_i2c_init2,
+ .probe = soft_i2c_probe2,
+ .read = soft_i2c_read2,
+ .write = soft_i2c_write2,
+ .set_bus_speed = soft_i2c_set_bus_speed2,
+ .get_bus_speed = soft_i2c_get_bus_speed2,
+ .speed = CONFIG_SYS_SOFT_I2C2_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C2_SLAVE,
+ .init_done = 0,
+ .name = "soft-i2c#2"
+ },
+#endif
+#if defined(I2C_SOFT_DECLARATIONS3)
+ {
+ .init = soft_i2c_init3,
+ .probe = soft_i2c_probe3,
+ .read = soft_i2c_read3,
+ .write = soft_i2c_write3,
+ .set_bus_speed = soft_i2c_set_bus_speed3,
+ .get_bus_speed = soft_i2c_get_bus_speed3,
+ .speed = CONFIG_SYS_SOFT_I2C3_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C3_SLAVE,
+ .init_done = 0,
+ .name = "soft-i2c#3"
+ },
+#endif
+#if defined(I2C_SOFT_DECLARATIONS4)
+ {
+ .init = soft_i2c_init4,
+ .probe = soft_i2c_probe4,
+ .read = soft_i2c_read4,
+ .write = soft_i2c_write4,
+ .set_bus_speed = soft_i2c_set_bus_speed4,
+ .get_bus_speed = soft_i2c_get_bus_speed4,
+ .speed = CONFIG_SYS_SOFT_I2C4_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C4_SLAVE,
+ .init_done = 0,
+ .name = "soft-i2c#4"
+ },
+#endif
+};
2
2

17 Feb '09
Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
---
diff -purN u-boot-i2c.orig/drivers/i2c/omap1510_i2c.c u-boot-i2c/drivers/i2c/omap1510_i2c.c
--- u-boot-i2c.orig/drivers/i2c/omap1510_i2c.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/i2c/omap1510_i2c.c 2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,8 @@
/*
+ * Copyright (c) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
* Basic I2C functions
*
* Copyright (c) 2003 Texas Instruments
@@ -19,11 +23,51 @@
*/
#include <common.h>
+#include <i2c.h>
+
+i2c_adap_t omap1510_i2c_adap;
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void wait_for_bb (void)
+{
+ int timeout = 10;
+
+ while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
+ inw (I2C_IV);
+ udelay (1000);
+ }
+
+ if (timeout <= 0) {
+ printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
+ inw (I2C_STAT));
+ }
+}
+
+static u16 wait_for_pin (void)
+{
+ u16 status, iv;
+ int timeout = 10;
+
+ do {
+ udelay (1000);
+ status = inw (I2C_STAT);
+ iv = inw (I2C_IV);
+ } while (!iv &&
+ !(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_pin: I2C_STAT=%x\n",
+ inw (I2C_STAT));
+ }
-static void wait_for_bb (void);
-static u16 wait_for_pin (void);
+ return status;
+}
-void i2c_init (int speed, int slaveadd)
+static void omap1510_i2c_init (int speed, int slaveadd)
{
u16 scl;
@@ -46,6 +90,10 @@ void i2c_init (int speed, int slaveadd)
outw (slaveadd, I2C_OA);
outw (0, I2C_CNT);
udelay (1000);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ omap1510_i2c_adap.init_done = 1;
+ }
}
static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
@@ -158,7 +206,7 @@ static int i2c_write_byte (u8 devaddr, u
return i2c_error;
}
-int i2c_probe (uchar chip)
+static int omap1510_i2c_probe (uchar chip)
{
int res = 1;
@@ -188,24 +236,24 @@ int i2c_probe (uchar chip)
return res;
}
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+static int omap1510_i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
int i;
if (alen > 1) {
- printf ("I2C read: addr len %d not supported\n", alen);
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
return 1;
}
if (addr + len > 256) {
- printf ("I2C read: address out of range\n");
+ printf ("%s: address out of range\n", __FUNCTION__);
return 1;
}
for (i = 0; i < len; i++) {
if (i2c_read_byte (chip, addr + i, &buffer[i])) {
- printf ("I2C read: I/O error\n");
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ printf ("%s: I/O error\n", __FUNCTION__);
+ i2c_init (CONFIG_SYS_OMAP1510_I2C_SPEED, CONFIG_SYS_OMAP1510_I2C_SLAVE);
return 1;
}
}
@@ -213,24 +261,24 @@ int i2c_read (uchar chip, uint addr, int
return 0;
}
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+static int omap1510_i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
int i;
if (alen > 1) {
- printf ("I2C read: addr len %d not supported\n", alen);
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
return 1;
}
if (addr + len > 256) {
- printf ("I2C read: address out of range\n");
+ printf ("%s: address out of range\n", __FUNCTION__);
return 1;
}
for (i = 0; i < len; i++) {
if (i2c_write_byte (chip, addr + i, buffer[i])) {
- printf ("I2C read: I/O error\n");
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ printf ("%s: I/O error\n", __FUNCTION__);
+ i2c_init (CONFIG_SYS_OMAP1510_I2C_SPEED, CONFIG_SYS_OMAP1510_I2C_SLAVE);
return 1;
}
}
@@ -238,40 +286,25 @@ int i2c_write (uchar chip, uint addr, in
return 0;
}
-static void wait_for_bb (void)
+static unsigned int omap1510_i2c_set_bus_speed(unsigned int speed)
{
- int timeout = 10;
-
- while ((inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
- inw (I2C_IV);
- udelay (1000);
- }
-
- if (timeout <= 0) {
- printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
- inw (I2C_STAT));
- }
+ return(omap1510_i2c_adap.speed);
}
-static u16 wait_for_pin (void)
+static unsigned int omap1510_i2c_get_bus_speed(void)
{
- u16 status, iv;
- int timeout = 10;
-
- do {
- udelay (1000);
- status = inw (I2C_STAT);
- iv = inw (I2C_IV);
- } while (!iv &&
- !(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_pin: I2C_STAT=%x\n",
- inw (I2C_STAT));
- }
-
- return status;
+ return(omap1510_i2c_adap.speed);
}
+
+i2c_adap_t omap1510_i2c_adap = {
+ .init = omap1510_i2c_init,
+ .probe = omap1510_i2c_probe,
+ .read = omap1510_i2c_read,
+ .write = omap1510_i2c_write,
+ .set_bus_speed = omap1510_i2c_set_bus_speed,
+ .get_bus_speed = omap1510_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_OMAP1510_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_OMAP1510_I2C_SLAVE,
+ .init_done = 0,
+ .name = "omap1510_i2c"
+};
diff -purN u-boot-i2c.orig/drivers/i2c/omap24xx_i2c.c u-boot-i2c/drivers/i2c/omap24xx_i2c.c
--- u-boot-i2c.orig/drivers/i2c/omap24xx_i2c.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/i2c/omap24xx_i2c.c 2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,8 @@
/*
+ * Copyright (c) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
* Basic I2C functions
*
* Copyright (c) 2004 Texas Instruments
@@ -24,65 +28,134 @@
#include <asm/arch/i2c.h>
#include <asm/io.h>
+#include <i2c.h>
-static void wait_for_bb (void);
-static u16 wait_for_pin (void);
-static void flush_fifo(void);
+#define OMAP24XX_NAME(arg) "omap24xx_i2c@" MK_NAME(arg)
+#define MK_NAME(arg) #arg
+
+#ifndef CONFIG_SYS_OMAP24XX_I2C_BASE
+#define CONFIG_SYS_OMAP24XX_I2C_BASE I2C_BASE1
+#endif
-void i2c_init (int speed, int slaveadd)
+i2c_adap_t omap24xx_i2c_adap[];
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void flush_fifo(ulong base)
+{
+ u16 stat;
+
+ /* note: if you try and read data when its not there or ready
+ * you get a bus error
+ */
+ while(1){
+ stat = readw(base + I2C_STAT);
+ if(stat == I2C_STAT_RRDY){
+#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
+ readb(base + I2C_DATA);
+#else
+ readw(base + I2C_DATA);
+#endif
+ writew(I2C_STAT_RRDY, base + I2C_STAT);
+ udelay(1000);
+ }else
+ break;
+ }
+}
+
+static void wait_for_bb (ulong base)
+{
+ int timeout = 10;
+ u16 stat;
+
+ writew(0xFFFF, base + I2C_STAT); /* clear current interruts...*/
+ while ((stat = readw (base + I2C_STAT) & I2C_STAT_BB) && timeout--) {
+ writew (stat, base + I2C_STAT);
+ udelay (50000);
+ }
+
+ if (timeout <= 0) {
+ printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
+ readw (base + I2C_STAT));
+ }
+ writew(0xFFFF, base + I2C_STAT); /* clear delayed stuff*/
+}
+
+static u16 wait_for_pin (ulong base)
+{
+ u16 status;
+ int timeout = 10;
+
+ do {
+ udelay (1000);
+ status = readw (base + I2C_STAT);
+ } 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_pin: I2C_STAT=%x\n",
+ readw (base + I2C_STAT));
+ writew(0xFFFF, base + I2C_STAT);
+ }
+ return status;
+}
+
+static void _i2c_init (int speed, int slaveadd, ulong base)
{
u16 scl;
- writew(0x2, I2C_SYSC); /* for ES2 after soft reset */
+ writew(0x2, base + I2C_SYSC); /* for ES2 after soft reset */
udelay(1000);
- writew(0x0, I2C_SYSC); /* will probably self clear but */
+ writew(0x0, base + I2C_SYSC); /* will probably self clear but */
- if (readw (I2C_CON) & I2C_CON_EN) {
- writew (0, I2C_CON);
+ if (readw (base + I2C_CON) & I2C_CON_EN) {
+ writew (0, base + I2C_CON);
udelay (50000);
}
/* 12MHz I2C module clock */
- writew (0, I2C_PSC);
+ writew (0, base + I2C_PSC);
speed = speed/1000; /* 100 or 400 */
scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */
- writew (scl, I2C_SCLL);
- writew (scl, I2C_SCLH);
+ writew (scl, base + I2C_SCLL);
+ writew (scl, base + I2C_SCLH);
/* own address */
- writew (slaveadd, I2C_OA);
- writew (I2C_CON_EN, I2C_CON);
+ writew (slaveadd, base + I2C_OA);
+ writew (I2C_CON_EN, base + I2C_CON);
/* 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_IE);
+ I2C_IE_NACK_IE | I2C_IE_AL_IE, base + I2C_IE);
udelay (1000);
- flush_fifo();
- writew (0xFFFF, I2C_STAT);
- writew (0, I2C_CNT);
+ flush_fifo(base);
+ writew (0xFFFF, base + I2C_STAT);
+ writew (0, base + I2C_CNT);
}
-static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
+static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value, ulong base)
{
int i2c_error = 0;
u16 status;
/* wait until bus not busy */
- wait_for_bb ();
+ wait_for_bb (base);
/* one byte only */
- writew (1, I2C_CNT);
+ writew (1, base + I2C_CNT);
/* set slave address */
- writew (devaddr, I2C_SA);
+ writew (devaddr, base + I2C_SA);
/* no stop bit needed here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
+ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, base + I2C_CON);
- status = wait_for_pin ();
+ status = wait_for_pin (base);
if (status & I2C_STAT_XRDY) {
/* Important: have to use byte access */
- writeb (regoffset, I2C_DATA);
+ writeb (regoffset, base + I2C_DATA);
udelay (20000);
- if (readw (I2C_STAT) & I2C_STAT_NACK) {
+ if (readw (base + I2C_STAT) & I2C_STAT_NACK) {
i2c_error = 1;
}
} else {
@@ -91,28 +164,29 @@ static int i2c_read_byte (u8 devaddr, u8
if (!i2c_error) {
/* free bus, otherwise we can't use a combined transction */
- writew (0, I2C_CON);
- while (readw (I2C_STAT) || (readw (I2C_CON) & I2C_CON_MST)) {
+ writew (0, base + I2C_CON);
+ while (readw (base + I2C_STAT) ||
+ (readw (base + I2C_CON) & I2C_CON_MST)) {
udelay (10000);
/* Have to clear pending interrupt to clear I2C_STAT */
- writew (0xFFFF, I2C_STAT);
+ writew (0xFFFF, base + I2C_STAT);
}
- wait_for_bb ();
+ wait_for_bb (base);
/* set slave address */
- writew (devaddr, I2C_SA);
+ writew (devaddr, base + I2C_SA);
/* read one byte from slave */
- writew (1, I2C_CNT);
+ writew (1, base + I2C_CNT);
/* need stop bit here */
writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
- I2C_CON);
+ base + I2C_CON);
- status = wait_for_pin ();
+ status = wait_for_pin (base);
if (status & I2C_STAT_RRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
- *value = readb (I2C_DATA);
+ *value = readb (base + I2C_DATA);
#else
- *value = readw (I2C_DATA);
+ *value = readw (base + I2C_DATA);
#endif
udelay (20000);
} else {
@@ -120,60 +194,60 @@ static int i2c_read_byte (u8 devaddr, u8
}
if (!i2c_error) {
- writew (I2C_CON_EN, I2C_CON);
- while (readw (I2C_STAT)
- || (readw (I2C_CON) & I2C_CON_MST)) {
+ writew (I2C_CON_EN, base + I2C_CON);
+ while (readw (base + I2C_STAT)
+ || (readw (base + I2C_CON) & I2C_CON_MST)) {
udelay (10000);
- writew (0xFFFF, I2C_STAT);
+ writew (0xFFFF, base + I2C_STAT);
}
}
}
- flush_fifo();
- writew (0xFFFF, I2C_STAT);
- writew (0, I2C_CNT);
+ flush_fifo(base);
+ writew (0xFFFF, base + I2C_STAT);
+ writew (0, base + I2C_CNT);
return i2c_error;
}
-static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
+static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value, ulong base)
{
int i2c_error = 0;
u16 status, stat;
/* wait until bus not busy */
- wait_for_bb ();
+ wait_for_bb (base);
/* two bytes */
- writew (2, I2C_CNT);
+ writew (2, base + I2C_CNT);
/* set slave address */
- writew (devaddr, I2C_SA);
+ writew (devaddr, base + I2C_SA);
/* stop bit needed here */
writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
- I2C_CON_STP, I2C_CON);
+ I2C_CON_STP, base + I2C_CON);
/* wait until state change */
- status = wait_for_pin ();
+ status = wait_for_pin (base);
if (status & I2C_STAT_XRDY) {
#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
/* send out 1 byte */
- writeb (regoffset, I2C_DATA);
- writew (I2C_STAT_XRDY, I2C_STAT);
+ writeb (regoffset, base + I2C_DATA);
+ writew (I2C_STAT_XRDY, base + I2C_STAT);
- status = wait_for_pin ();
+ status = wait_for_pin (base);
if ((status & I2C_STAT_XRDY)) {
/* send out next 1 byte */
- writeb (value, I2C_DATA);
- writew (I2C_STAT_XRDY, I2C_STAT);
+ writeb (value, base + I2C_DATA);
+ writew (I2C_STAT_XRDY, base + I2C_STAT);
} else {
i2c_error = 1;
}
#else
/* send out two bytes */
- writew ((value << 8) + regoffset, I2C_DATA);
+ writew ((value << 8) + regoffset, base + I2C_DATA);
#endif
/* must have enough delay to allow BB bit to go low */
udelay (50000);
- if (readw (I2C_STAT) & I2C_STAT_NACK) {
+ if (readw (base + I2C_STAT) & I2C_STAT_NACK) {
i2c_error = 1;
}
} else {
@@ -183,96 +257,96 @@ static int i2c_write_byte (u8 devaddr, u
if (!i2c_error) {
int eout = 200;
- writew (I2C_CON_EN, I2C_CON);
- while ((stat = readw (I2C_STAT)) || (readw (I2C_CON) & I2C_CON_MST)) {
+ writew (I2C_CON_EN, base + I2C_CON);
+ while ((stat = readw (base + I2C_STAT)) ||
+ (readw (base + I2C_CON) & I2C_CON_MST)) {
udelay (1000);
/* have to read to clear intrrupt */
- writew (0xFFFF, I2C_STAT);
+ writew (0xFFFF, base + I2C_STAT);
if(--eout == 0) /* better leave with error than hang */
break;
}
}
- flush_fifo();
- writew (0xFFFF, I2C_STAT);
- writew (0, I2C_CNT);
+ flush_fifo(base);
+ writew (0xFFFF, base + I2C_STAT);
+ writew (0, base + I2C_CNT);
return i2c_error;
}
-static void flush_fifo(void)
-{ u16 stat;
-
- /* note: if you try and read data when its not there or ready
- * you get a bus error
- */
- while(1){
- stat = readw(I2C_STAT);
- if(stat == I2C_STAT_RRDY){
-#if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX)
- readb(I2C_DATA);
-#else
- readw(I2C_DATA);
-#endif
- writew(I2C_STAT_RRDY,I2C_STAT);
- udelay(1000);
- }else
- break;
- }
-}
-int i2c_probe (uchar chip)
+static int _i2c_probe (uchar chip, ulong base)
{
int res = 1; /* default = fail */
- if (chip == readw (I2C_OA)) {
+ if (chip == readw (base + I2C_OA)) {
return res;
}
/* wait until bus not busy */
- wait_for_bb ();
+ wait_for_bb (base);
/* try to read one byte */
- writew (1, I2C_CNT);
+ writew (1, base + I2C_CNT);
/* set slave address */
- writew (chip, I2C_SA);
+ writew (chip, base + I2C_SA);
/* stop bit needed here */
- writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
+ writew (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, base + I2C_CON);
/* enough delay for the NACK bit set */
udelay (50000);
- if (!(readw (I2C_STAT) & I2C_STAT_NACK)) {
+ if (!(readw (base + I2C_STAT) & I2C_STAT_NACK)) {
res = 0; /* success case */
- flush_fifo();
- writew(0xFFFF, I2C_STAT);
+ flush_fifo(base);
+ writew(0xFFFF, base + I2C_STAT);
} else {
- writew(0xFFFF, I2C_STAT); /* failue, clear sources*/
- writew (readw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
+ writew(0xFFFF, base + I2C_STAT); /* failure, clear sources*/
+ writew (readw (base + I2C_CON) | I2C_CON_STP, base + I2C_CON); /* finish up xfer */
udelay(20000);
- wait_for_bb ();
+ wait_for_bb (base);
}
- flush_fifo();
- writew (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
- writew(0xFFFF, I2C_STAT);
+ flush_fifo(base);
+ writew (0, base + I2C_CNT); /* don't allow any more data in...we don't want it.*/
+ writew(0xFFFF, base + I2C_STAT);
return res;
}
-int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+
+static void omap24xx_i2c_init (int speed, int slaveadd)
+{
+ _i2c_init(speed, slaveadd, CONFIG_SYS_OMAP24XX_I2C_BASE);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ omap24xx_i2c_adap[0].speed = speed;
+ omap24xx_i2c_adap[0].slaveaddr = slaveadd;
+ omap24xx_i2c_adap[0].init_done = 1;
+ }
+}
+
+static int omap24xx_i2c_probe (uchar chip)
+{
+ return(_i2c_probe(chip, CONFIG_SYS_OMAP24XX_I2C_BASE));
+}
+
+static int omap24xx_i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
int i;
if (alen > 1) {
- printf ("I2C read: addr len %d not supported\n", alen);
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
return 1;
}
if (addr + len > 256) {
- printf ("I2C read: address out of range\n");
+ printf ("%s: address out of range\n", __FUNCTION__);
return 1;
}
for (i = 0; i < len; i++) {
- if (i2c_read_byte (chip, addr + i, &buffer[i])) {
- printf ("I2C read: I/O error\n");
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ if (i2c_read_byte (chip, addr + i, &buffer[i], CONFIG_SYS_OMAP24XX_I2C_BASE)) {
+ printf ("%s: I/O error\n", __FUNCTION__);
+ _i2c_init (CONFIG_SYS_OMAP24XX_I2C_SPEED,
+ CONFIG_SYS_OMAP24XX_I2C_SLAVE,
+ CONFIG_SYS_OMAP24XX_I2C_BASE);
return 1;
}
}
@@ -280,24 +354,26 @@ int i2c_read (uchar chip, uint addr, int
return 0;
}
-int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+static int omap24xx_i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
int i;
if (alen > 1) {
- printf ("I2C read: addr len %d not supported\n", alen);
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
return 1;
}
if (addr + len > 256) {
- printf ("I2C read: address out of range\n");
+ printf ("%s: address out of range\n", __FUNCTION__);
return 1;
}
for (i = 0; i < len; i++) {
- if (i2c_write_byte (chip, addr + i, buffer[i])) {
- printf ("I2C read: I/O error\n");
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ if (i2c_write_byte (chip, addr + i, buffer[i], CONFIG_SYS_OMAP24XX_I2C_BASE)) {
+ printf ("%s: I/O error\n", __FUNCTION__);
+ _i2c_init (CONFIG_SYS_OMAP24XX_I2C_SPEED,
+ CONFIG_SYS_OMAP24XX_I2C_SLAVE,
+ CONFIG_SYS_OMAP24XX_I2C_BASE);
return 1;
}
}
@@ -305,41 +381,219 @@ int i2c_write (uchar chip, uint addr, in
return 0;
}
-static void wait_for_bb (void)
+static unsigned int omap24xx_i2c_set_bus_speed(unsigned int speed)
{
- int timeout = 10;
- u16 stat;
+ return(omap24xx_i2c_adap[0].speed);
+}
- writew(0xFFFF, I2C_STAT); /* clear current interruts...*/
- while ((stat = readw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
- writew (stat, I2C_STAT);
- udelay (50000);
+static unsigned int omap24xx_i2c_get_bus_speed(void)
+{
+ return(omap24xx_i2c_adap[0].speed);
+}
+
+#ifdef CONFIG_SYS_OMAP24XX_I2C2_BASE
+static void omap24xx_i2c2_init (int speed, int slaveadd)
+{
+ _i2c_init(speed, slaveadd, CONFIG_SYS_OMAP24XX_I2C2_BASE);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ omap24xx_i2c_adap[1].speed = speed;
+ omap24xx_i2c_adap[1].slaveaddr = slaveadd;
+ omap24xx_i2c_adap[1].init_done = 1;
+ }
+}
+
+static int omap24xx_i2c2_probe (uchar chip)
+{
+ return(_i2c_probe(chip, CONFIG_SYS_OMAP24XX_I2C2_BASE));
+}
+
+static int omap24xx_i2c2_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ int i;
+
+ if (alen > 1) {
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
+ return 1;
}
- if (timeout <= 0) {
- printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
- readw (I2C_STAT));
+ if (addr + len > 256) {
+ printf ("%s: address out of range\n", __FUNCTION__);
+ return 1;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (i2c_read_byte (chip, addr + i, &buffer[i], CONFIG_SYS_OMAP24XX_I2C2_BASE)) {
+ printf ("%s: I/O error\n", __FUNCTION__);
+ _i2c_init (CONFIG_SYS_OMAP24XX_I2C2_SPEED,
+ CONFIG_SYS_OMAP24XX_I2C2_SLAVE,
+ CONFIG_SYS_OMAP24XX_I2C2_BASE);
+ return 1;
+ }
}
- writew(0xFFFF, I2C_STAT); /* clear delayed stuff*/
+
+ return 0;
}
-static u16 wait_for_pin (void)
+static int omap24xx_i2c2_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
- u16 status;
- int timeout = 10;
+ int i;
- do {
- udelay (1000);
- status = readw (I2C_STAT);
- } 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 (alen > 1) {
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
+ return 1;
+ }
- if (timeout <= 0) {
- printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
- readw (I2C_STAT));
- writew(0xFFFF, I2C_STAT);
+ if (addr + len > 256) {
+ printf ("%s: address out of range\n", __FUNCTION__);
+ return 1;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (i2c_write_byte (chip, addr + i, buffer[i], CONFIG_SYS_OMAP24XX_I2C2_BASE)) {
+ printf ("%s: I/O error\n", __FUNCTION__);
+ _i2c_init (CONFIG_SYS_OMAP24XX_I2C2_SPEED,
+ CONFIG_SYS_OMAP24XX_I2C2_SLAVE,
+ CONFIG_SYS_OMAP24XX_I2C2_BASE);
+ return 1;
+ }
+ }
+
+ return 0;
}
- return status;
+
+static unsigned int omap24xx_i2c2_set_bus_speed(unsigned int speed)
+{
+ return(omap24xx_i2c_adap[1].speed);
+}
+
+static unsigned int omap24xx_i2c2_get_bus_speed(void)
+{
+ return(omap24xx_i2c_adap[1].speed);
+}
+#endif
+
+#ifdef CONFIG_SYS_OMAP24XX_I2C3_BASE
+static void omap24xx_i2c3_init (int speed, int slaveadd)
+{
+ _i2c_init(speed, slaveadd, CONFIG_SYS_OMAP24XX_I2C3_BASE);
+
+ if (gd->flags & GD_FLG_RELOC) {
+ omap24xx_i2c_adap[2].speed = speed;
+ omap24xx_i2c_adap[2].slaveaddr = slaveadd;
+ omap24xx_i2c_adap[2].init_done = 1;
+ }
+}
+
+static int omap24xx_i2c3_probe (uchar chip)
+{
+ return(_i2c_probe(chip, CONFIG_SYS_OMAP24XX_I2C3_BASE));
}
+
+static int omap24xx_i2c3_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ int i;
+
+ if (alen > 1) {
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
+ return 1;
+ }
+
+ if (addr + len > 256) {
+ printf ("%s: address out of range\n", __FUNCTION__);
+ return 1;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (i2c_read_byte (chip, addr + i, &buffer[i], CONFIG_SYS_OMAP24XX_I2C3_BASE)) {
+ printf ("%s: I/O error\n", __FUNCTION__);
+ _i2c_init (CONFIG_SYS_OMAP24XX_I2C3_SPEED,
+ CONFIG_SYS_OMAP24XX_I2C3_SLAVE,
+ CONFIG_SYS_OMAP24XX_I2C3_BASE);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int omap24xx_i2c3_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
+{
+ int i;
+
+ if (alen > 1) {
+ printf ("%s: addr len %d not supported\n", __FUNCTION__, alen);
+ return 1;
+ }
+
+ if (addr + len > 256) {
+ printf ("%s: address out of range\n", __FUNCTION__);
+ return 1;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (i2c_write_byte (chip, addr + i, buffer[i], CONFIG_SYS_OMAP24XX_I2C3_BASE)) {
+ printf ("%s: I/O error\n", __FUNCTION__);
+ _i2c_init (CONFIG_SYS_OMAP24XX_I2C3_SPEED,
+ CONFIG_SYS_OMAP24XX_I2C3_SLAVE,
+ CONFIG_SYS_OMAP24XX_I2C3_BASE);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int omap24xx_i2c3_set_bus_speed(unsigned int speed)
+{
+ return(omap24xx_i2c_adap[2].speed);
+}
+
+static unsigned int omap24xx_i2c3_get_bus_speed(void)
+{
+ return(omap24xx_i2c_adap[2].speed);
+}
+#endif
+
+i2c_adap_t omap24xx_i2c_adap[3] = {
+ {
+ .init = omap24xx_i2c_init,
+ .probe = omap24xx_i2c_probe,
+ .read = omap24xx_i2c_read,
+ .write = omap24xx_i2c_write,
+ .set_bus_speed = omap24xx_i2c_set_bus_speed,
+ .get_bus_speed = omap24xx_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_OMAP24XX_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_OMAP24XX_I2C_SLAVE,
+ .init_done = 0,
+ .name = OMAP24XX_NAME(CONFIG_SYS_OMAP24XX_I2C_BASE)
+ },
+#ifdef CONFIG_SYS_OMAP24XX_I2C2_BASE
+ {
+ .init = omap24xx_i2c2_init,
+ .probe = omap24xx_i2c2_probe,
+ .read = omap24xx_i2c2_read,
+ .write = omap24xx_i2c2_write,
+ .set_bus_speed = omap24xx_i2c2_set_bus_speed,
+ .get_bus_speed = omap24xx_i2c2_get_bus_speed,
+ .speed = CONFIG_SYS_OMAP24XX_I2C2_SPEED,
+ .slaveaddr = CONFIG_SYS_OMAP24XX_I2C2_SLAVE,
+ .init_done = 0,
+ .name = OMAP24XX_NAME(CONFIG_SYS_OMAP24XX_I2C2_BASE)
+ },
+#endif
+#ifdef CONFIG_SYS_OMAP24XX_I2C3_BASE
+ {
+ .init = omap24xx_i2c3_init,
+ .probe = omap24xx_i2c3_probe,
+ .read = omap24xx_i2c3_read,
+ .write = omap24xx_i2c3_write,
+ .set_bus_speed = omap24xx_i2c3_set_bus_speed,
+ .get_bus_speed = omap24xx_i2c3_get_bus_speed,
+ .speed = CONFIG_SYS_OMAP24XX_I2C3_SPEED,
+ .slaveaddr = CONFIG_SYS_OMAP24XX_I2C3_SLAVE,
+ .init_done = 0,
+ .name = OMAP24XX_NAME(CONFIG_SYS_OMAP24XX_I2C3_BASE)
+ }
+#endif
+};
diff -purN u-boot-i2c.orig/drivers/i2c/tsi108_i2c.c u-boot-i2c/drivers/i2c/tsi108_i2c.c
--- u-boot-i2c.orig/drivers/i2c/tsi108_i2c.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/i2c/tsi108_i2c.c 2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,8 @@
/*
+ * Copyright (c) 2009 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
* (C) Copyright 2004 Tundra Semiconductor Corp.
* Author: Alex Bounine
*
@@ -26,8 +30,7 @@
#include <common.h>
#include <tsi108.h>
-
-#if defined(CONFIG_CMD_I2C)
+#include <i2c.h>
#define I2C_DELAY 100000
#undef DEBUG_I2C
@@ -38,6 +41,8 @@
#define DPRINT(x)
#endif
+i2c_adap_t tsi108_i2c_adap;
+
/* All functions assume that Tsi108 I2C block is the only master on the bus */
/* I2C read helper function */
@@ -132,7 +137,7 @@ static int i2c_read_byte (
* Returns: 0 on success, not 0 on failure
*/
-int i2c_read (uchar chip_addr, uint byte_addr, int alen,
+static int tsi108_i2c_read (uchar chip_addr, uint byte_addr, int alen,
uchar * buffer, int len)
{
u32 op_status = TSI108_I2C_PARAM_ERR;
@@ -238,7 +243,7 @@ static int i2c_write_byte (uchar chip_ad
* Returns: 0 on success, not 0 on failure
*/
-int i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer,
+static int tsi108_i2c_write (uchar chip_addr, uint byte_addr, int alen, uchar * buffer,
int len)
{
u32 op_status = TSI108_I2C_PARAM_ERR;
@@ -266,7 +271,7 @@ int i2c_write (uchar chip_addr, uint byt
* Returns 0 if a chip responded, not 0 on failure.
*/
-int i2c_probe (uchar chip)
+static int tsi108_i2c_probe (uchar chip)
{
u32 tmp;
@@ -278,4 +283,31 @@ int i2c_probe (uchar chip)
return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
}
-#endif
+static unsigned int tsi108_i2c_set_bus_speed(unsigned int speed)
+{
+ return(tsi108_i2c_adap.speed);
+}
+
+static unsigned int tsi108_i2c_get_bus_speed(void)
+{
+ return(tsi108_i2c_adap.speed);
+}
+
+static void tsi108_i2c_init(int speed, int slaveaddr)
+{
+ /* Dummy */
+}
+
+i2c_adap_t tsi108_i2c_adap = {
+ .init = tsi108_i2c_init,
+ .probe = tsi108_i2c_probe,
+ .read = tsi108_i2c_read,
+ .write = tsi108_i2c_write,
+ .set_bus_speed = tsi108_i2c_set_bus_speed,
+ .get_bus_speed = tsi108_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_TSI108_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_TSI108_I2C_SLAVE,
+ .init_done = 0,
+ .name = "tsi108_i2c"
+};
+
diff -purN u-boot-i2c.orig/include/asm-arm/arch-omap24xx/i2c.h u-boot-i2c/include/asm-arm/arch-omap24xx/i2c.h
--- u-boot-i2c.orig/include/asm-arm/arch-omap24xx/i2c.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/asm-arm/arch-omap24xx/i2c.h 2009-02-12 10:46:00.000000000 -0800
@@ -23,24 +23,24 @@
#ifndef _OMAP24XX_I2C_H_
#define _OMAP24XX_I2C_H_
-#define I2C_BASE 0x48070000
+#define I2C_BASE1 0x48070000
#define I2C_BASE2 0x48072000 /* nothing hooked up on h4 */
-#define I2C_REV (I2C_BASE + 0x00)
-#define I2C_IE (I2C_BASE + 0x04)
-#define I2C_STAT (I2C_BASE + 0x08)
-#define I2C_IV (I2C_BASE + 0x0c)
-#define I2C_BUF (I2C_BASE + 0x14)
-#define I2C_CNT (I2C_BASE + 0x18)
-#define I2C_DATA (I2C_BASE + 0x1c)
-#define I2C_SYSC (I2C_BASE + 0x20)
-#define I2C_CON (I2C_BASE + 0x24)
-#define I2C_OA (I2C_BASE + 0x28)
-#define I2C_SA (I2C_BASE + 0x2c)
-#define I2C_PSC (I2C_BASE + 0x30)
-#define I2C_SCLL (I2C_BASE + 0x34)
-#define I2C_SCLH (I2C_BASE + 0x38)
-#define I2C_SYSTEST (I2C_BASE + 0x3c)
+#define I2C_REV (0x00)
+#define I2C_IE (0x04)
+#define I2C_STAT (0x08)
+#define I2C_IV (0x0c)
+#define I2C_BUF (0x14)
+#define I2C_CNT (0x18)
+#define I2C_DATA (0x1c)
+#define I2C_SYSC (0x20)
+#define I2C_CON (0x24)
+#define I2C_OA (0x28)
+#define I2C_SA (0x2c)
+#define I2C_PSC (0x30)
+#define I2C_SCLL (0x34)
+#define I2C_SCLH (0x38)
+#define I2C_SYSTEST (0x3c)
/* I2C masks */
diff -purN u-boot-i2c.orig/include/asm-arm/arch-omap3/i2c.h u-boot-i2c/include/asm-arm/arch-omap3/i2c.h
--- u-boot-i2c.orig/include/asm-arm/arch-omap3/i2c.h 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/include/asm-arm/arch-omap3/i2c.h 2009-02-12 10:46:00.000000000 -0800
@@ -20,26 +20,24 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
-#ifndef _I2C_H_
-#define _I2C_H_
+#ifndef _OMAP3_I2C_H_
+#define _OMAP3_I2C_H_
-#define I2C_DEFAULT_BASE I2C_BASE1
-
-#define I2C_REV (I2C_DEFAULT_BASE + 0x00)
-#define I2C_IE (I2C_DEFAULT_BASE + 0x04)
-#define I2C_STAT (I2C_DEFAULT_BASE + 0x08)
-#define I2C_IV (I2C_DEFAULT_BASE + 0x0c)
-#define I2C_BUF (I2C_DEFAULT_BASE + 0x14)
-#define I2C_CNT (I2C_DEFAULT_BASE + 0x18)
-#define I2C_DATA (I2C_DEFAULT_BASE + 0x1c)
-#define I2C_SYSC (I2C_DEFAULT_BASE + 0x20)
-#define I2C_CON (I2C_DEFAULT_BASE + 0x24)
-#define I2C_OA (I2C_DEFAULT_BASE + 0x28)
-#define I2C_SA (I2C_DEFAULT_BASE + 0x2c)
-#define I2C_PSC (I2C_DEFAULT_BASE + 0x30)
-#define I2C_SCLL (I2C_DEFAULT_BASE + 0x34)
-#define I2C_SCLH (I2C_DEFAULT_BASE + 0x38)
-#define I2C_SYSTEST (I2C_DEFAULT_BASE + 0x3c)
+#define I2C_REV (0x00)
+#define I2C_IE (0x04)
+#define I2C_STAT (0x08)
+#define I2C_IV (0x0c)
+#define I2C_BUF (0x14)
+#define I2C_CNT (0x18)
+#define I2C_DATA (0x1c)
+#define I2C_SYSC (0x20)
+#define I2C_CON (0x24)
+#define I2C_OA (0x28)
+#define I2C_SA (0x2c)
+#define I2C_PSC (0x30)
+#define I2C_SCLL (0x34)
+#define I2C_SCLH (0x38)
+#define I2C_SYSTEST (0x3c)
/* I2C masks */
@@ -125,4 +123,4 @@
#define I2C_PSC_MAX 0x0f
#define I2C_PSC_MIN 0x00
-#endif /* _I2C_H_ */
+#endif /* _OMAP3_I2C_H_ */
4
4

17 Feb '09
Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
---
diff -purN u-boot-i2c.orig/cpu/mpc8xx/video.c u-boot-i2c/cpu/mpc8xx/video.c
--- u-boot-i2c.orig/cpu/mpc8xx/video.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/cpu/mpc8xx/video.c 2009-02-12 10:46:00.000000000 -0800
@@ -809,7 +809,11 @@ static void video_encoder_init (void)
/* Initialize the I2C */
debug ("[VIDEO ENCODER] Initializing I2C bus...\n");
+#ifdef CONFIG_NEW_I2C
+ i2c_init_all();
+#else
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
#ifdef CONFIG_FADS
/* Reset ADV7176 chip */
diff -purN u-boot-i2c.orig/lib_arm/board.c u-boot-i2c/lib_arm/board.c
--- u-boot-i2c.orig/lib_arm/board.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/lib_arm/board.c 2009-02-12 10:46:00.000000000 -0800
@@ -81,7 +81,8 @@ extern void rtl8019_get_enetaddr (uchar
#endif
#if defined(CONFIG_HARD_I2C) || \
- defined(CONFIG_SOFT_I2C)
+ defined(CONFIG_SOFT_I2C) || \
+ defined(CONFIG_SYS_I2C_ADAPTERS)
#include <i2c.h>
#endif
@@ -211,11 +212,15 @@ static void display_flash_config (ulong
}
#endif /* CONFIG_SYS_NO_FLASH */
-#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_NEW_I2C
+ i2c_init_all();
+#else
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
puts ("ready\n");
return (0);
}
@@ -272,7 +277,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_SOFT_I2C) || defined(CONFIG_SYS_I2C_ADAPTERS)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks */
@@ -368,6 +373,10 @@ void start_armboot (void)
/* initialize environment */
env_relocate ();
+#if defined(CONFIG_NEW_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+ i2c_reloc_fixup();
+#endif
+
#ifdef CONFIG_VFD
/* must do this after the framebuffer is allocated */
drv_vfd_init();
diff -purN u-boot-i2c.orig/lib_blackfin/board.c u-boot-i2c/lib_blackfin/board.c
--- u-boot-i2c.orig/lib_blackfin/board.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/lib_blackfin/board.c 2009-02-12 10:46:00.000000000 -0800
@@ -31,6 +31,10 @@
int post_flag;
#endif
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+#include <i2c.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
const char version_string[] = U_BOOT_VERSION " ("U_BOOT_DATE" - "U_BOOT_TIME")";
@@ -338,6 +342,10 @@ void board_init_r(gd_t * id, ulong dest_
/* relocate environment function pointers etc. */
env_relocate();
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+ i2c_reloc_fixup();
+#endif
+
#ifdef CONFIG_CMD_NET
/* board MAC address */
s = getenv("ethaddr");
diff -purN u-boot-i2c.orig/lib_m68k/board.c u-boot-i2c/lib_m68k/board.c
--- u-boot-i2c.orig/lib_m68k/board.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/lib_m68k/board.c 2009-02-12 10:46:00.000000000 -0800
@@ -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
@@ -191,11 +192,15 @@ 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_NEW_I2C
+ i2c_init_all();
+#else
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
puts ("ready\n");
return (0);
}
@@ -227,7 +232,7 @@ 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)
@@ -577,6 +582,11 @@ void board_init_r (gd_t *id, ulong dest_
/* relocate environment function pointers etc. */
env_relocate ();
+#if defined(CONFIG_NEW_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+ /* Adjust I2C subsystem pointers after relocation */
+ i2c_reloc_fixup();
+#endif
+
/*
* Fill in missing fields of bd_info.
* We do this here, where we have "normal" access to the
diff -purN u-boot-i2c.orig/lib_mips/board.c u-boot-i2c/lib_mips/board.c
--- u-boot-i2c.orig/lib_mips/board.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/lib_mips/board.c 2009-02-12 10:46:00.000000000 -0800
@@ -33,6 +33,10 @@
#include <onenand_uboot.h>
#include <spi.h>
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+#include <i2c.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
#if ( ((CONFIG_ENV_ADDR+CONFIG_ENV_SIZE) < CONFIG_SYS_MONITOR_BASE) || \
@@ -401,6 +405,10 @@ void board_init_r (gd_t *id, ulong dest_
/* relocate environment function pointers etc. */
env_relocate();
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
+ i2c_reloc_fixup();
+#endif
+
/* board MAC address */
s = getenv ("ethaddr");
for (i = 0; i < 6; ++i) {
diff -purN u-boot-i2c.orig/lib_ppc/board.c u-boot-i2c/lib_ppc/board.c
--- u-boot-i2c.orig/lib_ppc/board.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/lib_ppc/board.c 2009-02-12 10:46:00.000000000 -0800
@@ -88,7 +88,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>
@@ -231,11 +232,15 @@ 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_NEW_I2C
+ i2c_init_all();
+#else
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
puts ("ready\n");
return (0);
}
@@ -330,7 +335,7 @@ 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)
@@ -847,6 +852,11 @@ void board_init_r (gd_t *id, ulong dest_
* the environment is in EEPROM.
*/
+#if defined(CONFIG_NEW_I2C) && defined(CONFIG_SYS_I2C_ADAPTERS)
+ /* Adjust I2C subsystem pointers after relocation */
+ i2c_reloc_fixup();
+#endif
+
#if defined(CONFIG_SYS_EXTBDINFO)
#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
#if defined(CONFIG_I2CFAST)
2
6

Re: [U-Boot] [PATCH 1/1] ARM DaVinci: Add common peripherals andmodules enable functions.
by Hugo Villeneuve 17 Feb '09
by Hugo Villeneuve 17 Feb '09
17 Feb '09
> From: u-boot-bounces(a)lists.denx.de on behalf of Hugo Villeneuve
> Sent: Fri 11/21/2008 2:35 PM
> To: u-boot(a)lists.denx.de
> Subject: [U-Boot] [PATCH 1/1] ARM DaVinci: Add common peripherals
> andmodules enable functions.
>
> Taken all the duplicated code for enabling common modules and apply
> software workarounds from the board specific code into common
> functions. Also added comments explaining the workarounds
> (from TI errata documents) and replaced some numerical bit numbers
> with more meaningful defines.
>
> Signed-off-by: Hugo Villeneuve <hugo.villeneuve(a)lyrtech.com>
> ---
> board/davinci/common/psc.c | 65 ++++++++++++++++++++++++++
> +++++++++ board/davinci/common/psc.h | 3 ++
> board/davinci/dvevm/dvevm.c | 35 +++++--------------
> board/davinci/schmoogie/schmoogie.c | 37 +++++--------------
> board/davinci/sffsdr/sffsdr.c | 31 +++--------------
> board/davinci/sonata/sonata.c | 35 +++++--------------
> 6 files changed, 101 insertions(+), 105 deletions(-)
I sent this patch two months ago but I didn´t receive feedback...
Hugo V.
> diff --git a/board/davinci/common/psc.c b/board/davinci/common/psc.c
> index d538d51..28e2a4b 100644
> --- a/board/davinci/common/psc.c
> +++ b/board/davinci/common/psc.c
> @@ -26,6 +26,14 @@
> #include <common.h>
> #include <asm/arch/hardware.h>
>
> +#define PINMUX0_EMACEN (1 << 31)
> +#define PINMUX0_AECS5 (1 << 11)
> +#define PINMUX0_AECS4 (1 << 10)
> +
> +#define PINMUX1_I2C (1 << 7)
> +#define PINMUX1_UART1 (1 << 1)
> +#define PINMUX1_UART0 (1 << 0)
> +
> /*
> * The DM6446 includes two separate power domains: "Always On" and
> "DSP". The
> * "Always On" power domain is always on when the chip is on. The
> "Always On" @@ -115,3 +123,60 @@ void dsp_on(void)
> REG(PSC_GBLCTL) &= ~0x1f;
> }
> #endif /* CONFIG_SYS_USE_DSPLINK */
> +
> +void davinci_enable_uart0(void)
> +{
> + lpsc_on(DAVINCI_LPSC_UART0);
> +
> + /* Bringup UART0 out of reset */
> + REG(UART0_PWREMU_MGMT) = 0x0000e003;
> +
> + /* Enable UART0 MUX lines */
> + REG(PINMUX1) |= PINMUX1_UART0;
> +}
> +
> +#ifdef CONFIG_DRIVER_TI_EMAC
> +void davinci_enable_emac(void)
> +{
> + lpsc_on(DAVINCI_LPSC_EMAC);
> + lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
> + lpsc_on(DAVINCI_LPSC_MDIO);
> +
> + /* Enable GIO3.3V cells used for EMAC */
> + REG(VDD3P3V_PWDN) = 0;
> +
> + /* Enable EMAC. */
> + REG(PINMUX0) |= PINMUX0_EMACEN;
> +}
> +#endif
> +
> +void davinci_enable_i2c(void)
> +{
> + lpsc_on(DAVINCI_LPSC_I2C);
> +
> + /* Enable I2C pin Mux */
> + REG(PINMUX1) |= PINMUX1_I2C;
> +}
> +
> +void davinci_errata_workarounds(void)
> +{
> + /*
> + * Workaround for TMS320DM6446 errata 1.3.22:
> + * PSC: PTSTAT Register Does Not Clear After Warm/Maximum
> Reset
> + * Revision(s) Affected: 1.3 and earlier
> + */
> + REG(PSC_SILVER_BULLET) = 0;
> +
> + /*
> + * Set the PR_OLD_COUNT bits in the Bus Burst Priority
> Register (PBBPR)
> + * as suggested in TMS320DM6446 errata 2.1.2:
> + *
> + * On DM6446 Silicon Revision 2.1 and earlier, under certain
> conditions
> + * low priority modules can occupy the bus and prevent high
> priority
> + * modules like the VPSS from getting the required DDR2
> throughput.
> + * A hex value of 0x20 should provide a good ARM (cache
> enabled)
> + * performance and still allow good utilization by the VPSS
> or other
> + * modules.
> + */
> + REG(VBPR) = 0x20;
> +}
> diff --git a/board/davinci/common/psc.h b/board/davinci/common/psc.h
> index 6ab2575..b18a185 100644
> --- a/board/davinci/common/psc.h
> +++ b/board/davinci/common/psc.h
> @@ -24,5 +24,8 @@
>
> void lpsc_on(unsigned int id);
> void dsp_on(void);
> +void davinci_enable_uart0(void);
> +void davinci_enable_emac(void);
> +void davinci_enable_i2c(void);
>
> #endif /* __PSC_H */
> diff --git a/board/davinci/dvevm/dvevm.c b/board/davinci/dvevm/dvevm.c
> index abf60b3..f740124 100644
> --- a/board/davinci/dvevm/dvevm.c
> +++ b/board/davinci/dvevm/dvevm.c
> @@ -27,7 +27,6 @@
> #include <common.h>
> #include <i2c.h>
> #include <asm/arch/hardware.h>
> -#include <asm/arch/emac_defs.h>
> #include "../common/psc.h"
> #include "../common/misc.h"
>
> @@ -41,16 +40,13 @@ int board_init(void)
> /* address of boot parameters */
> gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
>
> - /* Workaround for TMS320DM6446 errata 1.3.22 */
> - REG(PSC_SILVER_BULLET) = 0;
> + /* Configure AEMIF pins (although this should be configured
> at boot time
> + * with pull-up/pull-down resistors) */
> + REG(PINMUX0) = 0x00000c1f;
> +
> + davinci_errata_workarounds();
>
> /* Power on required peripherals */
> - lpsc_on(DAVINCI_LPSC_EMAC);
> - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
> - lpsc_on(DAVINCI_LPSC_MDIO);
> - lpsc_on(DAVINCI_LPSC_I2C);
> - lpsc_on(DAVINCI_LPSC_UART0);
> - lpsc_on(DAVINCI_LPSC_TIMER1);
> lpsc_on(DAVINCI_LPSC_GPIO);
>
> #if !defined(CONFIG_SYS_USE_DSPLINK)
> @@ -58,24 +54,11 @@ int board_init(void)
> dsp_on();
> #endif /* CONFIG_SYS_USE_DSPLINK */
>
> - /* Bringup UART0 out of reset */
> - REG(UART0_PWREMU_MGMT) = 0x0000e003;
> -
> - /* Enable GIO3.3V cells used for EMAC */
> - REG(VDD3P3V_PWDN) = 0;
> -
> - /* Enable UART0 MUX lines */
> - REG(PINMUX1) |= 1;
> -
> - /* Enable EMAC and AEMIF pins */
> - REG(PINMUX0) = 0x80000c1f;
> -
> - /* Enable I2C pin Mux */
> - REG(PINMUX1) |= (1 << 7);
> -
> - /* Set the Bus Priority Register to appropriate value */
> - REG(VBPR) = 0x20;
> + davinci_enable_uart0();
> + davinci_enable_emac();
> + davinci_enable_i2c();
>
> + lpsc_on(DAVINCI_LPSC_TIMER1);
> timer_init();
>
> return(0);
> diff --git a/board/davinci/schmoogie/schmoogie.c
> b/board/davinci/schmoogie/schmoogie.c index 3504a2e..433769a 100644
> --- a/board/davinci/schmoogie/schmoogie.c
> +++ b/board/davinci/schmoogie/schmoogie.c
> @@ -27,7 +27,6 @@
> #include <common.h>
> #include <i2c.h>
> #include <asm/arch/hardware.h>
> -#include <asm/arch/emac_defs.h>
> #include "../common/psc.h"
> #include "../common/misc.h"
>
> @@ -41,16 +40,13 @@ int board_init(void)
> /* address of boot parameters */
> gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
>
> - /* Workaround for TMS320DM6446 errata 1.3.22 */
> - REG(PSC_SILVER_BULLET) = 0;
> + /* Configure AEMIF pins (although this should be configured
> at boot time
> + * with pull-up/pull-down resistors) */
> + REG(PINMUX0) = 0x00000c1f;
> +
> + davinci_errata_workarounds();
>
> /* Power on required peripherals */
> - lpsc_on(DAVINCI_LPSC_EMAC);
> - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
> - lpsc_on(DAVINCI_LPSC_MDIO);
> - lpsc_on(DAVINCI_LPSC_I2C);
> - lpsc_on(DAVINCI_LPSC_UART0);
> - lpsc_on(DAVINCI_LPSC_TIMER1);
> lpsc_on(DAVINCI_LPSC_GPIO);
>
> #if !defined(CONFIG_SYS_USE_DSPLINK)
> @@ -58,24 +54,11 @@ int board_init(void)
> dsp_on();
> #endif /* CONFIG_SYS_USE_DSPLINK */
>
> - /* Bringup UART0 out of reset */
> - REG(UART0_PWREMU_MGMT) = 0x0000e003;
> -
> - /* Enable GIO3.3V cells used for EMAC */
> - REG(VDD3P3V_PWDN) = 0;
> -
> - /* Enable UART0 MUX lines */
> - REG(PINMUX1) |= 1;
> -
> - /* Enable EMAC and AEMIF pins */
> - REG(PINMUX0) = 0x80000c1f;
> -
> - /* Enable I2C pin Mux */
> - REG(PINMUX1) |= (1 << 7);
> -
> - /* Set the Bus Priority Register to appropriate value */
> - REG(VBPR) = 0x20;
> + davinci_enable_uart0();
> + davinci_enable_emac();
> + davinci_enable_i2c();
>
> + lpsc_on(DAVINCI_LPSC_TIMER1);
> timer_init();
>
> return(0);
> @@ -87,7 +70,7 @@ int misc_init_r(void)
> int i = 0;
>
> /* Set serial number from UID chip */
> - u_int8_t crc_tbl[256] = {
> + const u_int8_t crc_tbl[256] = {
> 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd,
> 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
> 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40,
> 0x1e, diff --git a/board/davinci/sffsdr/sffsdr.c
> b/board/davinci/sffsdr/sffsdr.c index 9296d7b..e76f86d 100644
> --- a/board/davinci/sffsdr/sffsdr.c
> +++ b/board/davinci/sffsdr/sffsdr.c
> @@ -30,7 +30,6 @@
> #include <common.h>
> #include <i2c.h>
> #include <asm/arch/hardware.h>
> -#include <asm/arch/emac_defs.h>
> #include "../common/psc.h"
> #include "../common/misc.h"
>
> @@ -51,16 +50,9 @@ int board_init(void)
> /* address of boot parameters */
> gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
>
> - /* Workaround for TMS320DM6446 errata 1.3.22 */
> - REG(PSC_SILVER_BULLET) = 0;
> + davinci_errata_workarounds();
>
> /* Power on required peripherals */
> - lpsc_on(DAVINCI_LPSC_EMAC);
> - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
> - lpsc_on(DAVINCI_LPSC_MDIO);
> - lpsc_on(DAVINCI_LPSC_I2C);
> - lpsc_on(DAVINCI_LPSC_UART0);
> - lpsc_on(DAVINCI_LPSC_TIMER1);
> lpsc_on(DAVINCI_LPSC_GPIO);
>
> #if !defined(CONFIG_SYS_USE_DSPLINK)
> @@ -68,24 +60,11 @@ int board_init(void)
> dsp_on();
> #endif /* CONFIG_SYS_USE_DSPLINK */
>
> - /* Bringup UART0 out of reset */
> - REG(UART0_PWREMU_MGMT) = 0x0000e003;
> -
> - /* Enable GIO3.3V cells used for EMAC */
> - REG(VDD3P3V_PWDN) = 0;
> -
> - /* Enable UART0 MUX lines */
> - REG(PINMUX1) |= 1;
> -
> - /* Enable EMAC and AEMIF pins */
> - REG(PINMUX0) = 0x80000c1f;
> -
> - /* Enable I2C pin Mux */
> - REG(PINMUX1) |= (1 << 7);
> -
> - /* Set the Bus Priority Register to appropriate value */
> - REG(VBPR) = 0x20;
> + davinci_enable_uart0();
> + davinci_enable_emac();
> + davinci_enable_i2c();
>
> + lpsc_on(DAVINCI_LPSC_TIMER1);
> timer_init();
>
> return(0);
> diff --git a/board/davinci/sonata/sonata.c
> b/board/davinci/sonata/sonata.c index 6de9356..d56b443 100644
> --- a/board/davinci/sonata/sonata.c
> +++ b/board/davinci/sonata/sonata.c
> @@ -26,7 +26,6 @@
>
> #include <common.h>
> #include <asm/arch/hardware.h>
> -#include <asm/arch/emac_defs.h>
> #include "../common/psc.h"
> #include "../common/misc.h"
>
> @@ -40,16 +39,13 @@ int board_init(void)
> /* address of boot parameters */
> gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
>
> - /* Workaround for TMS320DM6446 errata 1.3.22 */
> - REG(PSC_SILVER_BULLET) = 0;
> + /* Configure AEMIF pins (although this should be configured
> at boot time
> + * with pull-up/pull-down resistors) */
> + REG(PINMUX0) = 0x00000c1f;
> +
> + davinci_errata_workarounds();
>
> /* Power on required peripherals */
> - lpsc_on(DAVINCI_LPSC_EMAC);
> - lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
> - lpsc_on(DAVINCI_LPSC_MDIO);
> - lpsc_on(DAVINCI_LPSC_I2C);
> - lpsc_on(DAVINCI_LPSC_UART0);
> - lpsc_on(DAVINCI_LPSC_TIMER1);
> lpsc_on(DAVINCI_LPSC_GPIO);
>
> #if !defined(CONFIG_SYS_USE_DSPLINK)
> @@ -57,24 +53,11 @@ int board_init(void)
> dsp_on();
> #endif /* CONFIG_SYS_USE_DSPLINK */
>
> - /* Bringup UART0 out of reset */
> - REG(UART0_PWREMU_MGMT) = 0x0000e003;
> -
> - /* Enable GIO3.3V cells used for EMAC */
> - REG(VDD3P3V_PWDN) = 0;
> -
> - /* Enable UART0 MUX lines */
> - REG(PINMUX1) |= 1;
> -
> - /* Enable EMAC and AEMIF pins */
> - REG(PINMUX0) = 0x80000c1f;
> -
> - /* Enable I2C pin Mux */
> - REG(PINMUX1) |= (1 << 7);
> -
> - /* Set the Bus Priority Register to appropriate value */
> - REG(VBPR) = 0x20;
> + davinci_enable_uart0();
> + davinci_enable_emac();
> + davinci_enable_i2c();
>
> + lpsc_on(DAVINCI_LPSC_TIMER1);
> timer_init();
>
> return(0);
> --
> 1.5.4.5
>
> _______________________________________________
> U-Boot mailing list
> U-Boot(a)lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
>
---------------
Hugo Villeneuve
www.hugovil.com
---------------
3
3
Hi,
I want to display a starting logo on LCD when my custome board power up, so what shoud I do to achieve this purpose?
The U-Boot version is 1.1.1, the processor is AT91RM9200, and the display controller is SAMSUNG S1D13506. should I implement framebuffer driver for the display controller? Or Just simply add "SPLASH SCREEN" support according to instruction of the U-Boot document "README".
Best regards,
Lizhihao
2
1
Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
---
diff -purN u-boot-i2c.orig/board/keymile/common/common.c u-boot-i2c/board/keymile/common/common.c
--- u-boot-i2c.orig/board/keymile/common/common.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/keymile/common/common.c 2009-02-12 10:46:00.000000000 -0800
@@ -35,11 +35,9 @@
#include <libfdt.h>
#endif
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+#if defined(CONFIG_SYS_I2C_ADAPTERS)
#include <i2c.h>
-extern int i2c_soft_read_pin (void);
-
int ivm_calc_crc (unsigned char *buf, int len)
{
const unsigned short crc_tab[16] = {
@@ -295,32 +293,36 @@ int ivm_analyze_eeprom (unsigned char *b
int ivm_read_eeprom (void)
{
- I2C_MUX_DEVICE *dev = NULL;
uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
+ uint tmp = 0xffff;
+#if !defined(CONFIG_SYS_IVM_EEPROM_BUS_NUM) || !defined(CONFIG_SYS_IVM_EEPROM_ADR)
uchar *buf;
- unsigned dev_addr = CONFIG_SYS_IVM_EEPROM_ADR;
+#endif
/* First init the Bus, select the Bus */
-#if defined(CONFIG_SYS_I2C_IVM_BUS)
- dev = i2c_mux_ident_muxstring ((uchar *)CONFIG_SYS_I2C_IVM_BUS);
+#if defined(CONFIG_SYS_IVM_EEPROM_BUS_NUM)
+ tmp = CONFIG_SYS_IVM_EEPROM_BUS_NUM;
#else
- buf = (unsigned char *) getenv ("EEprom_ivm");
+ buf = (unsigned char *) getenv ("EEprom_ivm_bus");
if (buf != NULL)
- dev = i2c_mux_ident_muxstring (buf);
+ tmp = (uint)simple_strtoul((char *)buf, NULL, 16);
#endif
- if (dev == NULL) {
- printf ("Error couldnt add Bus for IVM\n");
- return -1;
+ if (i2c_set_bus_num(tmp)) {
+ printf ("Error couldnt set Bus (%x) for IVM\n", tmp);
+ return(-1);
}
- i2c_set_bus_num (dev->busid);
- buf = (unsigned char *) getenv ("EEprom_ivm_addr");
- if (buf != NULL)
- dev_addr = simple_strtoul ((char *)buf, NULL, 16);
+#if defined(CONFIG_SYS_IVM_EEPROM_ADR)
+ tmp = CONFIG_SYS_IVM_EEPROM_ADR;
+#else
+ buf = (unsigned char *) getenv ("EEprom_ivm_addr");
+ if (buf != NULL)
+ tmp = (uint)simple_strtoul((char *)buf, NULL, 16);
+#endif
- if (eeprom_read (dev_addr, 0, i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN) != 0) {
- printf ("Error reading EEprom\n");
- return -2;
+ if (eeprom_read (tmp, 0, i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN) != 0) {
+ printf("Error reading EEprom\n");
+ return(-2);
}
return ivm_analyze_eeprom (i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
diff -purN u-boot-i2c.orig/board/keymile/mgcoge/mgcoge.c u-boot-i2c/board/keymile/mgcoge/mgcoge.c
--- u-boot-i2c.orig/board/keymile/mgcoge/mgcoge.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/keymile/mgcoge/mgcoge.c 2009-02-12 10:46:00.000000000 -0800
@@ -32,10 +32,6 @@
#include <libfdt.h>
#endif
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
-#include <i2c.h>
-#endif
-
#include "../common/common.h"
/*
diff -purN u-boot-i2c.orig/board/keymile/mgsuvd/mgsuvd.c u-boot-i2c/board/keymile/mgsuvd/mgsuvd.c
--- u-boot-i2c.orig/board/keymile/mgsuvd/mgsuvd.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/keymile/mgsuvd/mgsuvd.c 2009-02-12 10:46:00.000000000 -0800
@@ -195,14 +195,3 @@ void ft_board_setup(void *blob, bd_t *bd
ft_blob_update (blob, bd);
}
#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
-
-int i2c_soft_read_pin (void)
-{
- int val;
-
- *(unsigned short *)(I2C_BASE_DIR) &= ~SDA_CONF;
- udelay(1);
- val = *(unsigned char *)(I2C_BASE_PORT);
-
- return ((val & SDA_BIT) == SDA_BIT);
-}
diff -purN u-boot-i2c.orig/board/lwmon/lwmon.c u-boot-i2c/board/lwmon/lwmon.c
--- u-boot-i2c.orig/board/lwmon/lwmon.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/lwmon/lwmon.c 2009-02-12 10:46:00.000000000 -0800
@@ -481,7 +481,7 @@ static void kbd_init (void)
uchar val, errcd;
int i;
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ i2c_init_all();
gd->kbd_status = 0;
diff -purN u-boot-i2c.orig/board/lwmon/pcmcia.c u-boot-i2c/board/lwmon/pcmcia.c
--- u-boot-i2c.orig/board/lwmon/pcmcia.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/lwmon/pcmcia.c 2009-02-12 10:46:00.000000000 -0800
@@ -108,7 +108,7 @@ int pcmcia_hardware_enable(int slot)
/* switch VCC on */
val |= MAX1604_OP_SUS | MAX1604_VCCBON;
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ i2c_init_all();
i2c_write (CONFIG_SYS_I2C_POWER_A_ADDR, 0, 0, &val, 1);
udelay(500000);
@@ -199,7 +199,7 @@ int pcmcia_voltage_set(int slot, int vcc
*/
debug ("PCMCIA power OFF\n");
val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
- i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ i2c_init_all();
i2c_write (CONFIG_SYS_I2C_POWER_A_ADDR, 0, 0, &val, 1);
val = 0;
diff -purN u-boot-i2c.orig/board/omap2420h4/omap2420h4.c u-boot-i2c/board/omap2420h4/omap2420h4.c
--- u-boot-i2c.orig/board/omap2420h4/omap2420h4.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/omap2420h4/omap2420h4.c 2009-02-12 10:46:00.000000000 -0800
@@ -201,7 +201,11 @@ int dram_init (void)
u8 vmode_on = 0x8C;
#define NOT_EARLY 0
+#if defined(CONFIG_NEW_I2C)
+ i2c_init_all();
+#else
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); /* need this a bit early */
+#endif
btype = get_board_type();
mtype = get_mem_type();
diff -purN u-boot-i2c.orig/board/omap3/common/power.c u-boot-i2c/board/omap3/common/power.c
--- u-boot-i2c.orig/board/omap3/common/power.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/omap3/common/power.c 2009-02-12 10:46:00.000000000 -0800
@@ -41,8 +41,8 @@ void power_init_r(void)
{
unsigned char byte;
-#ifdef CONFIG_DRIVER_OMAP34XX_I2C
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#ifdef CONFIG_OMAP24XX_I2C
+ i2c_init_all();
#endif
/*
diff -purN u-boot-i2c.orig/board/omap3/evm/evm.c u-boot-i2c/board/omap3/evm/evm.c
--- u-boot-i2c.orig/board/omap3/evm/evm.c 2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/board/omap3/evm/evm.c 2009-02-12 10:46:00.000000000 -0800
@@ -60,8 +60,8 @@ int board_init(void)
int misc_init_r(void)
{
-#ifdef CONFIG_DRIVER_OMAP34XX_I2C
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#ifdef CONFIG_OMAP24XX_I2C
+ i2c_init_all();
#endif
#if defined(CONFIG_CMD_NET)
2
2