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