Merge branch 'master' of git://git.denx.de/u-boot-i2c

The sandburst-specific i2c drivers have been deleted, conflict was just
over the SPDX conversion.

Conflicts:
	board/sandburst/common/ppc440gx_i2c.c
	board/sandburst/common/ppc440gx_i2c.h

Signed-off-by: Tom Rini <trini@ti.com>
This commit is contained in:
Tom Rini 2013-07-24 09:22:28 -04:00
commit c2120fbfbc
321 changed files with 3120 additions and 2616 deletions

173
README
View File

@ -1928,11 +1928,114 @@ CBFS (Coreboot Filesystem) support
on those systems that support this (optional)
feature, like the TQM8xxL modules.
- I2C Support: CONFIG_HARD_I2C | CONFIG_SOFT_I2C
- I2C Support: CONFIG_SYS_I2C
These enable 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.
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.
ported i2c driver to the new framework:
- drivers/i2c/soft_i2c.c:
- activate first bus with CONFIG_SYS_I2C_SOFT define
CONFIG_SYS_I2C_SOFT_SPEED and CONFIG_SYS_I2C_SOFT_SLAVE
for defining speed and slave address
- activate second bus with I2C_SOFT_DECLARATIONS2 define
CONFIG_SYS_I2C_SOFT_SPEED_2 and CONFIG_SYS_I2C_SOFT_SLAVE_2
for defining speed and slave address
- activate third bus with I2C_SOFT_DECLARATIONS3 define
CONFIG_SYS_I2C_SOFT_SPEED_3 and CONFIG_SYS_I2C_SOFT_SLAVE_3
for defining speed and slave address
- activate fourth bus with I2C_SOFT_DECLARATIONS4 define
CONFIG_SYS_I2C_SOFT_SPEED_4 and CONFIG_SYS_I2C_SOFT_SLAVE_4
for defining speed and slave address
- drivers/i2c/fsl_i2c.c:
- activate i2c driver with CONFIG_SYS_I2C_FSL
define CONFIG_SYS_FSL_I2C_OFFSET for setting the register
offset CONFIG_SYS_FSL_I2C_SPEED for the i2c speed and
CONFIG_SYS_FSL_I2C_SLAVE for the slave addr of the first
bus.
- If your board supports a second fsl i2c bus, define
CONFIG_SYS_FSL_I2C2_OFFSET for the register offset
CONFIG_SYS_FSL_I2C2_SPEED for the speed and
CONFIG_SYS_FSL_I2C2_SLAVE for the slave address of the
second bus.
- drivers/i2c/tegra_i2c.c:
- activate this driver with CONFIG_SYS_I2C_TEGRA
- This driver adds 4 i2c buses with a fix speed from
100000 and the slave addr 0!
- drivers/i2c/ppc4xx_i2c.c
- activate this driver with CONFIG_SYS_I2C_PPC4XX
- CONFIG_SYS_I2C_PPC4XX_CH0 activate hardware channel 0
- CONFIG_SYS_I2C_PPC4XX_CH1 activate hardware channel 1
additional defines:
CONFIG_SYS_NUM_I2C_BUSES
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. If you not use i2c muxes, omit this
define.
CONFIG_SYS_I2C_BUSES
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_BUSES = 9:
CONFIG_SYS_I2C_BUSES {{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 with a PCA9547 on address 0x70 port 1
bus 2 on adapter 0 with a PCA9547 on address 0x70 port 2
bus 3 on adapter 0 with a PCA9547 on address 0x70 port 3
bus 4 on adapter 0 with a PCA9547 on address 0x70 port 4
bus 5 on adapter 0 with a PCA9547 on address 0x70 port 5
bus 6 on adapter 1 without a mux
bus 7 on adapter 1 with a PCA9544 on address 0x72 port 1
bus 8 on adapter 1 with a PCA9544 on address 0x72 port 2
If you do not have i2c muxes on your board, omit this define.
- Legacy I2C Support: CONFIG_HARD_I2C
NOTE: It is intended to move drivers to CONFIG_SYS_I2C which
provides the following compelling advantages:
- more than one i2c adapter is usable
- approved multibus support
- better i2c mux support
** Please consider updating your I2C driver now. **
These enable legacy I2C serial bus commands. Defining
CONFIG_HARD_I2C will include the appropriate I2C driver
for the selected CPU.
This will allow you to use i2c commands at the u-boot
command line (as long as you set CONFIG_CMD_I2C in
@ -1942,12 +2045,8 @@ CBFS (Coreboot Filesystem) support
CONFIG_HARD_I2C selects a hardware I2C controller.
CONFIG_SOFT_I2C configures u-boot to use a software (aka
bit-banging) driver instead of CPM or similar hardware
support for I2C.
There are several other quantities that must also be
defined when you define CONFIG_HARD_I2C or CONFIG_SOFT_I2C.
defined when you define CONFIG_HARD_I2C.
In both cases you will need to define CONFIG_SYS_I2C_SPEED
to be the frequency (in Hz) at which you wish your i2c bus
@ -1969,7 +2068,7 @@ CBFS (Coreboot Filesystem) support
That's all that's required for CONFIG_HARD_I2C.
If you use the software i2c interface (CONFIG_SOFT_I2C)
If you use the software i2c interface (CONFIG_SYS_I2C_SOFT)
then the following macros need to be defined (examples are
from include/configs/lwmon.h):
@ -2120,58 +2219,6 @@ CBFS (Coreboot Filesystem) support
If not defined, then U-Boot uses predefined value for
specified DTT device.
CONFIG_FSL_I2C
Define this option if you want to use Freescale's I2C driver in
drivers/i2c/fsl_i2c.c.
CONFIG_I2C_MUX
Define this option if you have I2C devices reached over 1 .. n
I2C Muxes like the pca9544a. This option addes a new I2C
Command "i2c bus [muxtype:muxaddr:muxchannel]" which adds a
new I2C Bus to the existing I2C Busses. If you select the
new Bus with "i2c dev", u-bbot sends first the commandos for
the muxes to activate this new "bus".
CONFIG_I2C_MULTI_BUS must be also defined, to use this
feature!
Example:
Adding a new I2C Bus reached over 2 pca9544a muxes
The First mux with address 70 and channel 6
The Second mux with address 71 and channel 4
=> i2c bus pca9544a:70:6:pca9544a:71:4
Use the "i2c bus" command without parameter, to get a list
of I2C Busses with muxes:
=> i2c bus
Busses reached over muxes:
Bus ID: 2
reached over Mux(es):
pca9544a@70 ch: 4
Bus ID: 3
reached over Mux(es):
pca9544a@70 ch: 6
pca9544a@71 ch: 4
=>
If you now switch to the new I2C Bus 3 with "i2c dev 3"
u-boot first sends the command to the mux@70 to enable
channel 6, and then the command to the mux@71 to enable
the channel 4.
After that, you can use the "normal" i2c commands as
usual to communicate with your I2C devices behind
the 2 muxes.
This option is actually implemented for the bitbanging
algorithm in common/soft_i2c.c and for the Hardware I2C
Bus on the MPC8260. But it should be not so difficult
to add this option to other architectures.
CONFIG_SOFT_I2C_READ_REPEATED_START
defining this will force the i2c_read() function in
@ -3588,7 +3635,7 @@ to save the current settings.
I2C muxes, you can define here, how to reach this
EEPROM. For example:
#define CONFIG_I2C_ENV_EEPROM_BUS "pca9547:70:d\0"
#define CONFIG_I2C_ENV_EEPROM_BUS 1
EEPROM which holds the environment, is reached over
a pca9547 i2c mux with address 0x70, channel 3.

View File

@ -191,6 +191,11 @@ u32 get_fec_clk(void)
return freq;
}
static u32 get_i2c_clk(void)
{
return get_ipg_clk();
}
unsigned int mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
@ -206,6 +211,8 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
return get_sdhc_clk();
case MXC_FEC_CLK:
return get_fec_clk();
case MXC_I2C_CLK:
return get_i2c_clk();
default:
break;
}

View File

@ -128,7 +128,7 @@
* I2C related stuff
*/
#ifdef CONFIG_CMD_I2C
#ifndef CONFIG_SOFT_I2C
#ifndef CONFIG_SYS_I2C_SOFT
#define CONFIG_I2C_MVTWSI
#endif
#define CONFIG_SYS_I2C_SLAVE 0x0

View File

@ -16,6 +16,7 @@ enum mxc_clock {
MXC_UART_CLK,
MXC_ESDHC_CLK,
MXC_FEC_CLK,
MXC_I2C_CLK,
};
void enable_ocotp_clk(unsigned char enable);

View File

@ -177,6 +177,7 @@ struct anadig_reg {
#define CCM_CCGR4_WKUP_CTRL_MASK (0x3 << 20)
#define CCM_CCGR4_CCM_CTRL_MASK (0x3 << 22)
#define CCM_CCGR4_GPC_CTRL_MASK (0x3 << 24)
#define CCM_CCGR4_I2C0_CTRL_MASK (0x3 << 12)
#define CCM_CCGR6_OCOTP_CTRL_MASK (0x3 << 10)
#define CCM_CCGR6_DDRMC_CTRL_MASK (0x3 << 28)
#define CCM_CCGR7_SDHC1_CTRL_MASK (0x3 << 4)

View File

@ -90,6 +90,7 @@
#define CONFIG_IOMUX_SHARE_CONF_REG
#define FEC_QUIRK_ENET_MAC
#define I2C_QUIRK_REG
/* MSCM interrupt rounter */
#define MSCM_IRSPRC_CP0_EN 1

View File

@ -17,6 +17,8 @@
#define VF610_ENET_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_50ohm | \
PAD_CTL_OBE_IBE_ENABLE)
#define VF610_DDR_PAD_CTRL PAD_CTL_DSE_25ohm
#define VF610_I2C_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_50ohm | \
PAD_CTL_SPEED_HIGH | PAD_CTL_OBE_IBE_ENABLE)
enum {
VF610_PAD_PTA6__RMII0_CLKIN = IOMUX_PAD(0x0000, 0x0000, 2, __NA_, 0, VF610_ENET_PAD_CTRL),
@ -37,6 +39,8 @@ enum {
VF610_PAD_PTA27__ESDHC1_DAT1 = IOMUX_PAD(0x0044, 0x0044, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
VF610_PAD_PTA28__ESDHC1_DAT2 = IOMUX_PAD(0x0048, 0x0048, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
VF610_PAD_PTA29__ESDHC1_DAT3 = IOMUX_PAD(0x004c, 0x004c, 5, __NA_, 0, VF610_SDHC_PAD_CTRL),
VF610_PAD_PTB14__I2C0_SCL = IOMUX_PAD(0x0090, 0x0090, 2, 0x033c, 1, VF610_I2C_PAD_CTRL),
VF610_PAD_PTB15__I2C0_SDA = IOMUX_PAD(0x0094, 0x0094, 2, 0x0340, 1, VF610_I2C_PAD_CTRL),
VF610_PAD_DDR_A15__DDR_A_15 = IOMUX_PAD(0x0220, 0x0220, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
VF610_PAD_DDR_A14__DDR_A_14 = IOMUX_PAD(0x0224, 0x0224, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
VF610_PAD_DDR_A13__DDR_A_13 = IOMUX_PAD(0x0228, 0x0228, 0, __NA_, 0, VF610_DDR_PAD_CTRL),

View File

@ -53,7 +53,7 @@ extern void dataflash_print_info(void);
#endif
#if defined(CONFIG_HARD_I2C) || \
defined(CONFIG_SOFT_I2C)
defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
@ -149,11 +149,15 @@ static int display_dram_config(void)
return (0);
}
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
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);
}
@ -252,7 +256,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 */

View File

@ -37,6 +37,10 @@
int post_flag;
#endif
#if defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
__attribute__((always_inline))
@ -387,6 +391,9 @@ void board_init_r(gd_t * id, ulong dest_addr)
mmc_initialize(bd);
#endif
#if defined(CONFIG_SYS_I2C)
i2c_reloc_fixup();
#endif
/* relocate environment function pointers etc. */
env_relocate();

View File

@ -89,7 +89,7 @@ void cpu_init_f(void)
out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK);
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
out_8(&gpio->par_i2c, GPIO_PAR_I2C_SCL_SCL | GPIO_PAR_I2C_SDA_SDA);
#endif

View File

@ -118,7 +118,7 @@ int get_clocks(void)
gd->bus_clk = gd->arch.flb_clk;
}
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
gd->arch.i2c1_clk = gd->bus_clk;
#endif

View File

@ -99,7 +99,7 @@ void cpu_init_f(void)
out_be32(&fbcs->csmr7, CONFIG_SYS_CS7_MASK);
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
CONFIG_SYS_I2C_PINMUX_REG &= CONFIG_SYS_I2C_PINMUX_CLR;
CONFIG_SYS_I2C_PINMUX_REG |= CONFIG_SYS_I2C_PINMUX_SET;
#endif

View File

@ -31,7 +31,7 @@ int get_clocks(void)
gd->bus_clk = CONFIG_SYS_CLK;
gd->cpu_clk = (gd->bus_clk * 2);
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
gd->arch.i2c1_clk = gd->bus_clk;
#endif

View File

@ -212,7 +212,7 @@ void cpu_init_f(void)
/* FlexBus Chipselect */
init_fbcs();
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
CONFIG_SYS_I2C_PINMUX_REG =
CONFIG_SYS_I2C_PINMUX_REG & CONFIG_SYS_I2C_PINMUX_CLR;
CONFIG_SYS_I2C_PINMUX_REG |= CONFIG_SYS_I2C_PINMUX_SET;
@ -482,7 +482,7 @@ void cpu_init_f(void)
init_fbcs();
#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
CONFIG_SYS_I2C_PINMUX_REG &= CONFIG_SYS_I2C_PINMUX_CLR;
CONFIG_SYS_I2C_PINMUX_REG |= CONFIG_SYS_I2C_PINMUX_SET;
#endif

View File

@ -74,9 +74,9 @@ int get_clocks (void)
gd->bus_clk = gd->cpu_clk;
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
gd->arch.i2c1_clk = gd->bus_clk;
#ifdef CONFIG_SYS_I2C2_OFFSET
#ifdef CONFIG_SYS_I2C2_FSL_OFFSET
gd->arch.i2c2_clk = gd->bus_clk;
#endif
#endif

View File

@ -82,7 +82,7 @@ void cpu_init_f(void)
out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK);
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
out_8(&gpio->par_feci2c,
GPIO_PAR_FECI2C_SDA_SDA | GPIO_PAR_FECI2C_SCL_SCL);
#endif
@ -276,7 +276,7 @@ void cpu_init_f(void)
out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK);
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
out_8(&gpio->par_feci2c,
GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA);
#endif

View File

@ -254,7 +254,7 @@ int get_clocks(void)
gd->bus_clk = clock_pll(CONFIG_SYS_CLK / 1000, 0) * 1000;
gd->cpu_clk = (gd->bus_clk * 3);
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
gd->arch.i2c1_clk = gd->bus_clk;
#endif

View File

@ -196,7 +196,7 @@ void cpu_init_f(void)
GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA |
GPIO_PAR_FBCTL_RW_RW | GPIO_PAR_FBCTL_TS_TS);
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_FSL_I2C
out_be16(&gpio->par_feci2c,
GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA);
#endif

View File

@ -257,7 +257,7 @@ void setup_5445x_clocks(void)
#endif
}
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
gd->arch.i2c1_clk = gd->bus_clk;
#endif
}
@ -273,7 +273,7 @@ int get_clocks(void)
setup_5445x_clocks();
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_FSL_I2C
gd->arch.i2c1_clk = gd->bus_clk;
#endif

View File

@ -79,7 +79,7 @@ void cpu_init_f(void)
out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK);
#endif
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
out_be16(&gpio->par_feci2cirq,
GPIO_PAR_FECI2CIRQ_SCL | GPIO_PAR_FECI2CIRQ_SDA);
#endif

View File

@ -24,7 +24,7 @@ int get_clocks(void)
gd->bus_clk = CONFIG_SYS_CLK;
gd->cpu_clk = (gd->bus_clk * 2);
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
gd->arch.i2c1_clk = gd->bus_clk;
#endif

View File

@ -10,7 +10,7 @@
/* Architecture-specific global data */
struct arch_global_data {
#ifdef CONFIG_FSL_I2C
#ifdef CONFIG_SYS_I2C_FSL
unsigned long i2c1_clk;
unsigned long i2c2_clk;
#endif

View File

@ -40,7 +40,7 @@
#include <version.h>
#if defined(CONFIG_HARD_I2C) || \
defined(CONFIG_SOFT_I2C)
defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
@ -126,11 +126,15 @@ static int init_func_ram (void)
/***********************************************************************/
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
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);
}
@ -162,7 +166,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_SYS_I2C)
init_func_i2c,
#endif
#if defined(CONFIG_HARD_SPI)
@ -485,6 +489,11 @@ void board_init_r (gd_t *id, ulong dest_addr)
spi_init_r ();
#endif
#if defined(CONFIG_SYS_I2C)
/* Adjust I2C subsystem pointers after relocation */
i2c_reloc_fixup();
#endif
/* relocate environment function pointers etc. */
env_relocate ();

View File

@ -24,6 +24,10 @@
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
ulong monitor_flash_len;
/*
@ -157,7 +161,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 */
@ -331,6 +335,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();

View File

@ -730,23 +730,9 @@ unsigned int i2c_get_bus_num(void)
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;
}

View File

@ -793,7 +793,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 */

View File

@ -36,10 +36,6 @@
/*
* Set default values
*/
#ifndef CONFIG_SYS_I2C_SPEED
#define CONFIG_SYS_I2C_SPEED 50000
#endif
#define ONE_BILLION 1000000000
#define SDRAM0_CFG_DCE 0x80000000
@ -142,7 +138,7 @@ long int spd_sdram(int(read_spd)(uint addr))
* Make sure I2C controller is initialized
* before continuing.
*/
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
}
/* Make shure we are using SDRAM */

View File

@ -46,10 +46,6 @@
/*
* Set default values
*/
#ifndef CONFIG_SYS_I2C_SPEED
#define CONFIG_SYS_I2C_SPEED 50000
#endif
#define ONE_BILLION 1000000000
/*
@ -152,7 +148,7 @@ long int spd_sdram(void) {
* Make sure I2C controller is initialized
* before continuing.
*/
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
/*
* Read the SPD information using I2C interface. Check to see if the

View File

@ -442,8 +442,7 @@ phys_size_t initdram(int board_type)
*/
/* switch to correct I2C bus */
I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM);
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
/*------------------------------------------------------------------
* Clear out the serial presence detect buffers.

View File

@ -39,7 +39,7 @@ static int do_chip_config(cmd_tbl_t *cmdtp, int flag, int argc, char * const arg
* First switch to correct I2C bus. This is I2C bus 0
* for all currently available 4xx derivats.
*/
I2C_SET_BUS(0);
i2c_set_bus_num(0);
#ifdef CONFIG_CMD_EEPROM
ret = eeprom_read(CONFIG_4xx_CONFIG_I2C_EEPROM_ADDR,

View File

@ -1024,8 +1024,7 @@ phys_size_t initdram(int board_type)
* before continuing.
*/
/* switch to correct I2C bus */
I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM);
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
/*------------------------------------------------------------------
* Clear out the serial presence detect buffers.

View File

@ -18,24 +18,6 @@
#define IIC_TIMEOUT 1 /* 1 second */
#if defined(CONFIG_I2C_MULTI_BUS)
#define I2C_BUS_OFFS (i2c_bus_num * 0x100)
#else
#define I2C_BUS_OFFS (0x000)
#endif /* CONFIG_I2C_MULTI_BUS */
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
#define I2C_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000700 + I2C_BUS_OFFS)
#elif defined(CONFIG_440) || defined(CONFIG_405EX)
/* all remaining 440 variants */
#define I2C_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000400 + I2C_BUS_OFFS)
#else
/* all 405 variants */
#define I2C_BASE_ADDR (0xEF600500 + I2C_BUS_OFFS)
#endif
struct ppc4xx_i2c {
u8 mdbuf;
u8 res1;

View File

@ -82,8 +82,7 @@ extern void sc3_read_eeprom(void);
#if defined(CONFIG_CMD_DOC)
void doc_init(void);
#endif
#if defined(CONFIG_HARD_I2C) || \
defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
#include <spi.h>
@ -198,11 +197,15 @@ static int init_func_ram(void)
/***********************************************************************/
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
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;
}
@ -291,7 +294,7 @@ static 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_SYS_I2C)
init_func_i2c,
#endif
#if defined(CONFIG_HARD_SPI)

View File

@ -272,7 +272,7 @@ int drv_video_init(void)
}
#endif
#ifdef CONFIG_SOFT_I2C
#ifdef CONFIG_SYS_I2C_SOFT
void i2c_init_board(void)
{

View File

@ -307,7 +307,7 @@ int board_eth_init(bd_t *bis)
return rc;
}
#ifdef CONFIG_SOFT_I2C
#ifdef CONFIG_SYS_I2C_SOFT
void i2c_init_board(void)
{
u32 pin;

View File

@ -154,7 +154,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 0, 0, 0, 0, 0 }, /* PD17 */
/* PD16 */ { 0, 0, 0, 0, 0, 0 }, /* PD16 */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -132,7 +132,7 @@ int board_init(void)
/* Initialise peripherals */
at91_seriald_hw_init();
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
nand_hw_init();
macb_hw_init();

View File

@ -309,7 +309,7 @@ int board_early_init_r(void)
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT)
uchar buf[6];
char str[18];
char hostname[MODULE_NAME_MAXLEN];
@ -332,7 +332,7 @@ int misc_init_r(void)
" device at address %02X:%04X\n", CONFIG_SYS_I2C_EEPROM,
CONFIG_MAC_OFFSET);
}
#endif /* defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C) */
#endif /* defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT) */
if (!getenv("ethaddr"))
printf(LOG_PREFIX "MAC address not set, networking is not "
"operational\n");

View File

@ -145,7 +145,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 0, 0, 0, 0, 0 }, /* PD17 */
/* PD16 */ { 0, 0, 0, 0, 0, 0 }, /* PD16 */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -147,7 +147,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 0, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 0, 0, 0, 0, 0 }, /* PD17 */
/* PD16 */ { 0, 0, 0, 0, 0, 0 }, /* PD16 */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -35,7 +35,7 @@ uchar pll_fs6377_regs[16] = {
*/
int pll_init(void)
{
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
return i2c_write(CONFIG_SYS_I2C_PLL_ADDR, 0, 1,
(uchar *) pll_fs6377_regs, sizeof(pll_fs6377_regs));

View File

@ -229,7 +229,7 @@ int board_eth_init(bd_t *bis)
* However i2c_get_bus_num() cannot be called before
* relocation.
*/
#ifdef CONFIG_SOFT_I2C
#ifdef CONFIG_SYS_I2C_SOFT
void iic_init(void)
{
/* ports are now initialized in board_early_init_f() */
@ -237,7 +237,7 @@ void iic_init(void)
int iic_read(void)
{
switch ((gd->flags & GD_FLG_RELOC) ? i2c_get_bus_num() : 0) {
switch (I2C_ADAP_HWNR) {
case 0:
return at91_get_pio_value(I2C0_PORT, SDA0_PIN);
case 1:
@ -248,7 +248,7 @@ int iic_read(void)
void iic_sda(int bit)
{
switch ((gd->flags & GD_FLG_RELOC) ? i2c_get_bus_num() : 0) {
switch (I2C_ADAP_HWNR) {
case 0:
at91_set_pio_value(I2C0_PORT, SDA0_PIN, bit);
break;
@ -260,7 +260,7 @@ void iic_sda(int bit)
void iic_scl(int bit)
{
switch ((gd->flags & GD_FLG_RELOC) ? i2c_get_bus_num() : 0) {
switch (I2C_ADAP_HWNR) {
case 0:
at91_set_pio_value(I2C0_PORT, SCL0_PIN, bit);
break;

View File

@ -372,7 +372,6 @@ int last_stage_init(void)
return 0;
}
#if defined(CONFIG_I2C_MULTI_BUS)
/*
* read field strength from I2C ADC
*/
@ -487,7 +486,6 @@ U_BOOT_CMD(
"Initialize USB hub",
""
);
#endif /* CONFIG_I2C_MULTI_BUS */
#define CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS 3
int boot_eeprom_write (unsigned dev_addr,

View File

@ -169,11 +169,11 @@ static spd_eeprom_t default_spd_eeprom = {
int vme8349_read_spd(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
int old_bus = I2C_GET_BUS();
int old_bus = i2c_get_bus_num();
unsigned int l, sum;
int valid = 0;
I2C_SET_BUS(0);
i2c_set_bus_num(0);
if (i2c_read(chip, addr, alen, buffer, len) == 0)
if (memcmp(&buffer[64], &default_spd_eeprom.mid[0], 8) == 0) {
@ -198,7 +198,7 @@ int vme8349_read_spd(uchar chip, uint addr, int alen, uchar *buffer, int len)
buffer[63] = sum;
}
I2C_SET_BUS(old_bus);
i2c_set_bus_num(old_bus);
return 0;
}

View File

@ -57,7 +57,7 @@ int board_eth_init(bd_t *bis)
}
#endif
#ifdef CONFIG_SOFT_I2C
#ifdef CONFIG_SYS_I2C_SOFT
void i2c_init_board(void)
{
u32 pin;

View File

@ -82,9 +82,9 @@ CONFIG_CMD_DATE -- enable to use date feature in u-boot
CONFIG_MCFTMR -- define to use DMA timer
CONFIG_MCFPIT -- define to use PIT timer
CONFIG_FSL_I2C -- define to use FSL common I2C driver
CONFIG_SYS_I2C_FSL -- define to use FSL common I2C driver
CONFIG_HARD_I2C -- define for I2C hardware support
CONFIG_SOFT_I2C -- define for I2C bit-banged
CONFIG_SYS_I2C_SOFT -- define for I2C bit-banged
CONFIG_SYS_I2C_SPEED -- define for I2C speed
CONFIG_SYS_I2C_SLAVE -- define for I2C slave address
CONFIG_SYS_I2C_OFFSET -- define for I2C base address offset

View File

@ -90,9 +90,9 @@ MCFFEC_TOUT_LOOP -- set FEC timeout loop
CONFIG_MCFTMR -- define to use DMA timer
CONFIG_MCFPIT -- define to use PIT timer
CONFIG_FSL_I2C -- define to use FSL common I2C driver
CONFIG_SYS_I2C_FSL -- define to use FSL common I2C driver
CONFIG_HARD_I2C -- define for I2C hardware support
CONFIG_SOFT_I2C -- define for I2C bit-banged
CONFIG_SYS_I2C_SOFT -- define for I2C bit-banged
CONFIG_SYS_I2C_SPEED -- define for I2C speed
CONFIG_SYS_I2C_SLAVE -- define for I2C slave address
CONFIG_SYS_I2C_OFFSET -- define for I2C base address offset

View File

@ -89,9 +89,9 @@ MCFFEC_TOUT_LOOP -- set FEC timeout loop
CONFIG_MCFTMR -- define to use DMA timer
CONFIG_MCFPIT -- define to use PIT timer
CONFIG_FSL_I2C -- define to use FSL common I2C driver
CONFIG_SYS_I2C_FSL -- define to use FSL common I2C driver
CONFIG_HARD_I2C -- define for I2C hardware support
CONFIG_SOFT_I2C -- define for I2C bit-banged
CONFIG_SYS_I2C_SOFT -- define for I2C bit-banged
CONFIG_SYS_I2C_SPEED -- define for I2C speed
CONFIG_SYS_I2C_SLAVE -- define for I2C slave address
CONFIG_SYS_I2C_OFFSET -- define for I2C base address offset

View File

@ -112,9 +112,9 @@ _IO_BASE -- define for IO base address
CONFIG_MCFTMR -- define to use DMA timer
CONFIG_MCFPIT -- define to use PIT timer
CONFIG_FSL_I2C -- define to use FSL common I2C driver
CONFIG_SYS_FSL_I2C -- define to use FSL common I2C driver
CONFIG_HARD_I2C -- define for I2C hardware support
CONFIG_SOFT_I2C -- define for I2C bit-banged
CONFIG_SYS_I2C_SOFT -- define for I2C bit-banged
CONFIG_SYS_I2C_SPEED -- define for I2C speed
CONFIG_SYS_I2C_SLAVE -- define for I2C slave address
CONFIG_SYS_I2C_OFFSET -- define for I2C base address offset

View File

@ -97,9 +97,9 @@ CONFIG_DOS_PARTITION -- enable DOS read/write
CONFIG_SLTTMR -- define to use SLT timer
CONFIG_FSL_I2C -- define to use FSL common I2C driver
CONFIG_SYS_I2C_FSL -- define to use FSL common I2C driver
CONFIG_HARD_I2C -- define for I2C hardware support
CONFIG_SOFT_I2C -- define for I2C bit-banged
CONFIG_SYS_I2C_SOFT -- define for I2C bit-banged
CONFIG_SYS_I2C_SPEED -- define for I2C speed
CONFIG_SYS_I2C_SLAVE -- define for I2C slave address
CONFIG_SYS_I2C_OFFSET -- define for I2C base address offset

View File

@ -247,8 +247,7 @@ int misc_init_r(void)
{
int rc = 0;
#ifdef CONFIG_HARD_I2C
#if defined(CONFIG_SYS_I2C)
unsigned int orig_bus = i2c_get_bus_num();
u8 i2c_data;

View File

@ -71,7 +71,7 @@ void pci_init_board(void)
#endif
u8 reg8;
#ifdef CONFIG_HARD_I2C
#if defined(CONFIG_SYS_I2C)
i2c_set_bus_num(1);
/* Read the PCI_M66EN jumper setting */
if ((i2c_read(CONFIG_SYS_I2C_8574_ADDR2, 0, 0, &reg8, sizeof(reg8)) == 0) ||

View File

@ -232,7 +232,7 @@ int checkboard(void)
in_8(&cpld_data->pcba_rev) & 0x0F);
/* Initialize i2c early for rom_loc and flash bank information */
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
if (i2c_read(CONFIG_SYS_I2C_PCA9557_ADDR, 0, 1, &in, 1) < 0 ||
i2c_read(CONFIG_SYS_I2C_PCA9557_ADDR, 1, 1, &out, 1) < 0 ||

View File

@ -14,6 +14,7 @@
#include <fsl_esdhc.h>
#include <miiphy.h>
#include <netdev.h>
#include <i2c.h>
DECLARE_GLOBAL_DATA_PTR;
@ -267,6 +268,16 @@ static void setup_iomux_enet(void)
imx_iomux_v3_setup_multiple_pads(enet0_pads, ARRAY_SIZE(enet0_pads));
}
static void setup_iomux_i2c(void)
{
static const iomux_v3_cfg_t i2c0_pads[] = {
VF610_PAD_PTB14__I2C0_SCL,
VF610_PAD_PTB15__I2C0_SDA,
};
imx_iomux_v3_setup_multiple_pads(i2c0_pads, ARRAY_SIZE(i2c0_pads));
}
#ifdef CONFIG_FSL_ESDHC
struct fsl_esdhc_cfg esdhc_cfg[1] = {
{ESDHC1_BASE_ADDR},
@ -315,7 +326,7 @@ static void clock_init(void)
CCM_CCGR3_ANADIG_CTRL_MASK);
clrsetbits_le32(&ccm->ccgr4, CCM_REG_CTRL_MASK,
CCM_CCGR4_WKUP_CTRL_MASK | CCM_CCGR4_CCM_CTRL_MASK |
CCM_CCGR4_GPC_CTRL_MASK);
CCM_CCGR4_GPC_CTRL_MASK | CCM_CCGR4_I2C0_CTRL_MASK);
clrsetbits_le32(&ccm->ccgr6, CCM_REG_CTRL_MASK,
CCM_CCGR6_OCOTP_CTRL_MASK | CCM_CCGR6_DDRMC_CTRL_MASK);
clrsetbits_le32(&ccm->ccgr7, CCM_REG_CTRL_MASK,
@ -374,6 +385,7 @@ int board_early_init_f(void)
setup_iomux_uart();
setup_iomux_enet();
setup_iomux_i2c();
return 0;
}

View File

@ -35,7 +35,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PA27 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RXDV */
/* PA26 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RXER */
/* PA25 */ { 0, 0, 0, 0, 1, 0 }, /* 8247_P0 */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PA24 */ { 1, 0, 0, 0, 1, 1 }, /* I2C_SDA2 */
/* PA23 */ { 1, 0, 0, 1, 1, 1 }, /* I2C_SCL2 */
#else /* normal I/O port pins */

View File

@ -298,29 +298,14 @@ int ivm_analyze_eeprom(unsigned char *buf, int len)
int ivm_read_eeprom(void)
{
#if defined(CONFIG_I2C_MUX)
I2C_MUX_DEVICE *dev = NULL;
#endif
uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
uchar *buf;
unsigned long dev_addr = CONFIG_SYS_IVM_EEPROM_ADR;
int ret;
#if defined(CONFIG_I2C_MUX)
/* First init the Bus, select the Bus */
buf = (unsigned char *) getenv("EEprom_ivm");
if (buf != NULL)
dev = i2c_mux_ident_muxstring(buf);
if (dev == NULL) {
printf("Error couldnt add Bus for IVM\n");
return -1;
}
i2c_set_bus_num(dev->busid);
#endif
i2c_set_bus_num(CONFIG_KM_IVM_BUS);
/* add deblocking here */
i2c_make_abort();
ret = i2c_read(dev_addr, 0, 1, i2c_buffer,
ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, i2c_buffer,
CONFIG_SYS_IVM_EEPROM_MAX_LEN);
if (ret != 0) {
printf("Error reading EEprom\n");

View File

@ -92,19 +92,6 @@ const qe_iop_conf_t qe_iop_conf_tab[] = {
{0, 0, 0, 0, QE_IOP_TAB_END},
};
static int board_init_i2c_busses(void)
{
I2C_MUX_DEVICE *dev = NULL;
uchar *dtt_bus = (uchar *)"pca9547:70:a";
/* Set up the Bus for the DTTs */
dev = i2c_mux_ident_muxstring(dtt_bus);
if (dev == NULL)
printf("Error couldn't add Bus for DTT\n");
return 0;
}
#if defined(CONFIG_SUVD3)
const uint upma_table[] = {
0x1ffedc00, 0x0ffcdc80, 0x0ffcdc80, 0x0ffcdc04, /* Words 0 to 3 */
@ -203,8 +190,6 @@ int board_early_init_r(void)
int misc_init_r(void)
{
/* add board specific i2c busses */
board_init_i2c_busses();
return 0;
}

View File

@ -47,7 +47,7 @@ static const u32 kwmpp_config[] = {
MPP5_NF_IO7,
MPP6_SYSRST_OUTn,
MPP7_PEX_RST_OUTn,
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
MPP8_GPIO, /* SDA */
MPP9_GPIO, /* SCL */
#endif
@ -218,7 +218,7 @@ int misc_init_r(void)
int board_early_init_f(void)
{
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
u32 tmp;
/* set the 2 bitbang i2c pins as output gpios */
@ -244,7 +244,7 @@ int board_init(void)
kw_gpio_set_valid(KM_FLASH_GPIO_PIN, 1);
kw_gpio_direction_output(KM_FLASH_GPIO_PIN, 1);
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/*
* Reinit the GPIO for I2C Bitbang driver so that the now
* available gpio framework is consistent. The calls to
@ -424,7 +424,7 @@ int hush_init_var(void)
}
#endif
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
void set_sda(int state)
{
I2C_ACTIVE;

View File

@ -464,7 +464,7 @@ static void kbd_init (void)
uchar val, errcd;
int i;
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
gd->arch.kbd_status = 0;

View File

@ -104,7 +104,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_set_bus_num(0);
i2c_write (CONFIG_SYS_I2C_POWER_A_ADDR, 0, 0, &val, 1);
udelay(500000);
@ -193,7 +193,7 @@ int pcmcia_voltage_set(int slot, int vcc, int vpp)
*/
debug ("PCMCIA power OFF\n");
val = MAX1604_VCCBHIZ | MAX1604_VPPBHIZ;
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
i2c_write (CONFIG_SYS_I2C_POWER_A_ADDR, 0, 0, &val, 1);
val = 0;

View File

@ -98,7 +98,7 @@ static void kbd_init (void)
uchar val, errcd;
int i;
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
gd->arch.kbd_status = 0;

View File

@ -192,7 +192,7 @@ int board_early_init_f (void)
#endif
/* Read Serial Presence Detect Information */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
for (i = 0; i < 128; i++)
datain[i] = 127;
i2c_read(SPD_EEPROM_ADDRESS,0,1,datain,128);

View File

@ -135,7 +135,7 @@ int board_init(void)
power_det_init();
#ifdef CONFIG_TEGRA_I2C
#ifdef CONFIG_SYS_I2C_TEGRA
#ifndef CONFIG_SYS_I2C_INIT_BOARD
#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
#endif
@ -149,7 +149,7 @@ int board_init(void)
debug("Memory controller init failed: %d\n", err);
# endif
# endif /* CONFIG_TEGRA_PMU */
#endif /* CONFIG_TEGRA_I2C */
#endif /* CONFIG_SYS_I2C_TEGRA */
#ifdef CONFIG_USB_EHCI_TEGRA
pin_mux_usb();

View File

@ -153,7 +153,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* PD17 */
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* PD16 */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -153,7 +153,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* PD17 */
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* PD16 */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -187,7 +187,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD17 */ { CONF, SPEC, 1, DOUT, ACTV, 0 }, /* SPI_MOSI */
/* PD16 */ { CONF, SPEC, 1, DIN, ACTV, 0 }, /* SPI_MISO */
#endif
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { CONF, GPIO, 0, DOUT, OPEN, 1 }, /* I2C_SDA */
/* PD14 */ { CONF, GPIO, 0, DOUT, ACTV, 1 }, /* I2C_SCL */
#else

View File

@ -1,494 +0,0 @@
/*
* Copyright (C) 2005 Sandburst Corporation
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* Ported from arch/powerpc/cpu/ppc4xx/i2c.c by AS HARNOIS by
* Travis B. Sawyer
* Sandburst Corporation.
*/
#include <common.h>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-i2c.h>
#include <i2c.h>
#include <command.h>
#include "ppc440gx_i2c.h"
#include <asm/io.h>
#ifdef CONFIG_I2C_BUS1
#define IIC_OK 0
#define IIC_NOK 1
#define IIC_NOK_LA 2 /* Lost arbitration */
#define IIC_NOK_ICT 3 /* Incomplete transfer */
#define IIC_NOK_XFRA 4 /* Transfer aborted */
#define IIC_NOK_DATA 5 /* No data in buffer */
#define IIC_NOK_TOUT 6 /* Transfer timeout */
#define IIC_TIMEOUT 1 /* 1 second */
#if defined(CONFIG_SYS_I2C_NOPROBES)
static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
#endif
static struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_REGISTERS_BUS1_BASE_ADDRESS;
static void _i2c_bus1_reset (void)
{
int i, status;
/* Reset status register */
/* write 1 in SCMP and IRQA to clear these fields */
out_8 (IIC_STS1, 0x0A);
/* write 1 in IRQP IRQD LA ICT XFRA to clear these fields */
out_8 (IIC_EXTSTS1, 0x8F);
__asm__ volatile ("eieio");
/*
* Get current state, reset bus
* only if no transfers are pending.
*/
i = 10;
do {
/* Get status */
status = in_8 (IIC_STS1);
udelay (500); /* 500us */
i--;
} while ((status & IIC_STS_PT) && (i > 0));
/* Soft reset controller */
status = in_8 (IIC_XTCNTLSS1);
out_8 (IIC_XTCNTLSS1, (status | IIC_XTCNTLSS_SRST));
__asm__ volatile ("eieio");
/* make sure where in initial state, data hi, clock hi */
out_8 (IIC_DIRECTCNTL1, 0xC);
for (i = 0; i < 10; i++) {
if ((in_8 (IIC_DIRECTCNTL1) & 0x3) != 0x3) {
/* clock until we get to known state */
out_8 (IIC_DIRECTCNTL1, 0x8); /* clock lo */
udelay (100); /* 100us */
out_8 (IIC_DIRECTCNTL1, 0xC); /* clock hi */
udelay (100); /* 100us */
} else {
break;
}
}
/* send start condition */
out_8 (IIC_DIRECTCNTL1, 0x4);
udelay (1000); /* 1ms */
/* send stop condition */
out_8 (IIC_DIRECTCNTL1, 0xC);
udelay (1000); /* 1ms */
/* Unreset controller */
out_8 (IIC_XTCNTLSS1, (status & ~IIC_XTCNTLSS_SRST));
udelay (1000); /* 1ms */
}
void i2c1_init (int speed, int slaveadd)
{
sys_info_t sysInfo;
unsigned long freqOPB;
int val, divisor;
#ifdef 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();
#endif
/* Handle possible failed I2C state */
/* FIXME: put this into i2c_init_board()? */
_i2c_bus1_reset ();
/* clear lo master address */
out_8 (IIC_LMADR1, 0);
/* clear hi master address */
out_8 (IIC_HMADR1, 0);
/* clear lo slave address */
out_8 (IIC_LSADR1, 0);
/* clear hi slave address */
out_8 (IIC_HSADR1, 0);
/* Clock divide Register */
/* get OPB frequency */
get_sys_info (&sysInfo);
freqOPB = sysInfo.freqPLB / sysInfo.pllOpbDiv;
/* set divisor according to freqOPB */
divisor = (freqOPB - 1) / 10000000;
if (divisor == 0)
divisor = 1;
out_8 (IIC_CLKDIV1, divisor);
/* no interrupts */
out_8 (IIC_INTRMSK1, 0);
/* clear transfer count */
out_8 (IIC_XFRCNT1, 0);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out_8 (IIC_XTCNTLSS1, 0xF0);
/* Mode Control Register
Flush Slave/Master data buffer */
out_8 (IIC_MDCNTL1, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
__asm__ volatile ("eieio");
val = in_8(IIC_MDCNTL1);
__asm__ volatile ("eieio");
/* Ignore General Call, slave transfers are ignored,
disable interrupts, exit unknown bus state, enable hold
SCL
100kHz normaly or FastMode for 400kHz and above
*/
val |= IIC_MDCNTL_EUBS|IIC_MDCNTL_HSCL;
if( speed >= 400000 ){
val |= IIC_MDCNTL_FSM;
}
out_8 (IIC_MDCNTL1, val);
/* clear control reg */
out_8 (IIC_CNTL1, 0x00);
__asm__ volatile ("eieio");
}
/*
This code tries to use the features of the 405GP i2c
controller. It will transfer up to 4 bytes in one pass
on the loop. It only does out_8(lbz) to the buffer when it
is possible to do out16(lhz) transfers.
cmd_type is 0 for write 1 for read.
addr_len can take any value from 0-255, it is only limited
by the char, we could make it larger if needed. If it is
0 we skip the address write cycle.
Typical case is a Write of an addr followd by a Read. The
IBM FAQ does not cover this. On the last byte of the write
we don't set the creg CHT bit, and on the first bytes of the
read we set the RPST bit.
It does not support address only transfers, there must be
a data part. If you want to write the address yourself, put
it in the data pointer.
It does not support transfer to/from address 0.
It does not check XFRCNT.
*/
static
int i2c_transfer1(unsigned char cmd_type,
unsigned char chip,
unsigned char addr[],
unsigned char addr_len,
unsigned char data[],
unsigned short data_len )
{
unsigned char* ptr;
int reading;
int tran,cnt;
int result;
int status;
int i;
uchar creg;
if( data == 0 || data_len == 0 ){
/*Don't support data transfer of no length or to address 0*/
printf( "i2c_transfer: bad call\n" );
return IIC_NOK;
}
if( addr && addr_len ){
ptr = addr;
cnt = addr_len;
reading = 0;
}else{
ptr = data;
cnt = data_len;
reading = cmd_type;
}
/*Clear Stop Complete Bit*/
out_8(IIC_STS1,IIC_STS_SCMP);
/* Check init */
i=10;
do {
/* Get status */
status = in_8(IIC_STS1);
__asm__ volatile("eieio");
i--;
} while ((status & IIC_STS_PT) && (i>0));
if (status & IIC_STS_PT) {
result = IIC_NOK_TOUT;
return(result);
}
/*flush the Master/Slave Databuffers*/
out_8(IIC_MDCNTL1, ((in_8(IIC_MDCNTL1))|IIC_MDCNTL_FMDB|IIC_MDCNTL_FSDB));
/*need to wait 4 OPB clocks? code below should take that long*/
/* 7-bit adressing */
out_8(IIC_HMADR1,0);
out_8(IIC_LMADR1, chip);
__asm__ volatile("eieio");
tran = 0;
result = IIC_OK;
creg = 0;
while ( tran != cnt && (result == IIC_OK)) {
int bc,j;
/* Control register =
Normal transfer, 7-bits adressing, Transfer up to bc bytes, Normal start,
Transfer is a sequence of transfers
*/
creg |= IIC_CNTL_PT;
bc = (cnt - tran) > 4 ? 4 :
cnt - tran;
creg |= (bc-1)<<4;
/* if the real cmd type is write continue trans*/
if ( (!cmd_type && (ptr == addr)) || ((tran+bc) != cnt) )
creg |= IIC_CNTL_CHT;
if (reading)
creg |= IIC_CNTL_READ;
else {
for(j=0; j<bc; j++) {
/* Set buffer */
out_8(IIC_MDBUF1,ptr[tran+j]);
__asm__ volatile("eieio");
}
}
out_8(IIC_CNTL1, creg );
__asm__ volatile("eieio");
/* Transfer is in progress
we have to wait for upto 5 bytes of data
1 byte chip address+r/w bit then bc bytes
of data.
udelay(10) is 1 bit time at 100khz
Doubled for slop. 20 is too small.
*/
i=2*5*8;
do {
/* Get status */
status = in_8(IIC_STS1);
__asm__ volatile("eieio");
udelay (10);
i--;
} while ((status & IIC_STS_PT) && !(status & IIC_STS_ERR)
&& (i>0));
if (status & IIC_STS_ERR) {
result = IIC_NOK;
status = in_8 (IIC_EXTSTS1);
/* Lost arbitration? */
if (status & IIC_EXTSTS_LA)
result = IIC_NOK_LA;
/* Incomplete transfer? */
if (status & IIC_EXTSTS_ICT)
result = IIC_NOK_ICT;
/* Transfer aborted? */
if (status & IIC_EXTSTS_XFRA)
result = IIC_NOK_XFRA;
} else if ( status & IIC_STS_PT) {
result = IIC_NOK_TOUT;
}
/* Command is reading => get buffer */
if ((reading) && (result == IIC_OK)) {
/* Are there data in buffer */
if (status & IIC_STS_MDBS) {
/*
even if we have data we have to wait 4OPB clocks
for it to hit the front of the FIFO, after that
we can just read. We should check XFCNT here and
if the FIFO is full there is no need to wait.
*/
udelay (1);
for(j=0;j<bc;j++) {
ptr[tran+j] = in_8(IIC_MDBUF1);
__asm__ volatile("eieio");
}
} else
result = IIC_NOK_DATA;
}
creg = 0;
tran+=bc;
if( ptr == addr && tran == cnt ) {
ptr = data;
cnt = data_len;
tran = 0;
reading = cmd_type;
if( reading )
creg = IIC_CNTL_RPST;
}
}
return (result);
}
int i2c_probe1 (uchar chip)
{
uchar buf[1];
buf[0] = 0;
/*
* What is needed is to send the chip address and verify that the
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
return(i2c_transfer1 (1, chip << 1, 0,0, buf, 1) != 0);
}
int i2c_read1 (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
uchar xaddr[4];
int ret;
if ( alen > 4 ) {
printf ("I2C read: addr len %d not supported\n", alen);
return 1;
}
if ( alen > 0 ) {
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
}
#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.
*/
if( alen > 0 )
chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif
if( (ret = i2c_transfer1( 1, chip<<1, &xaddr[4-alen], alen, buffer, len )) != 0) {
printf( "I2c read: failed %d\n", ret);
return 1;
}
return 0;
}
int i2c_write1 (uchar chip, uint addr, int alen, uchar * buffer, int len)
{
uchar xaddr[4];
if ( alen > 4 ) {
printf ("I2C write: addr len %d not supported\n", alen);
return 1;
}
if ( alen > 0 ) {
xaddr[0] = (addr >> 24) & 0xFF;
xaddr[1] = (addr >> 16) & 0xFF;
xaddr[2] = (addr >> 8) & 0xFF;
xaddr[3] = addr & 0xFF;
}
#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.
*/
if( alen > 0 )
chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif
return (i2c_transfer1( 0, chip<<1, &xaddr[4-alen], alen, buffer, len ) != 0);
}
/*-----------------------------------------------------------------------
* Read a register
*/
uchar i2c_reg_read1(uchar i2c_addr, uchar reg)
{
uchar buf;
i2c_read1(i2c_addr, reg, 1, &buf, (uchar)1);
return(buf);
}
/*-----------------------------------------------------------------------
* Write a register
*/
void i2c_reg_write1(uchar i2c_addr, uchar reg, uchar val)
{
i2c_write1(i2c_addr, reg, 1, &val, 1);
}
int do_i2c1_probe(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int j;
#if defined(CONFIG_SYS_I2C_NOPROBES)
int k, skip;
#endif
puts ("Valid chip addresses:");
for(j = 0; j < 128; j++) {
#if defined(CONFIG_SYS_I2C_NOPROBES)
skip = 0;
for (k = 0; k < sizeof(i2c_no_probes); k++){
if (j == i2c_no_probes[k]){
skip = 1;
break;
}
}
if (skip)
continue;
#endif
if(i2c_probe1(j) == 0) {
printf(" %02X", j);
}
}
putc ('\n');
#if defined(CONFIG_SYS_I2C_NOPROBES)
puts ("Excluded chip addresses:");
for( k = 0; k < sizeof(i2c_no_probes); k++ )
printf(" %02X", i2c_no_probes[k] );
putc ('\n');
#endif
return 0;
}
U_BOOT_CMD(
iprobe1, 1, 1, do_i2c1_probe,
"probe to discover valid I2C chip addresses",
""
);
#endif /* CONFIG_I2C_BUS1 */

View File

@ -1,44 +0,0 @@
/*
* Copyright (C) 2005 Sandburst Corporation
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* Ported from i2c driver for ppc4xx by AS HARNOIS by
* Travis B. Sawyer
* Sandburst Corporation
*/
#include <common.h>
#include <asm/ppc4xx.h>
#include <asm/ppc4xx-i2c.h>
#include <i2c.h>
#ifdef CONFIG_HARD_I2C
#define I2C_BUS1_BASE_ADDR (CONFIG_SYS_PERIPHERAL_BASE + 0x00000500)
#define I2C_REGISTERS_BUS1_BASE_ADDRESS I2C_BUS1_BASE_ADDR
#define IIC_MDBUF1 (&i2c->mdbuf)
#define IIC_SDBUF1 (&i2c->sdbuf)
#define IIC_LMADR1 (&i2c->lmadr)
#define IIC_HMADR1 (&i2c->hmadr)
#define IIC_CNTL1 (&i2c->cntl)
#define IIC_MDCNTL1 (&i2c->mdcntl)
#define IIC_STS1 (&i2c->sts)
#define IIC_EXTSTS1 (&i2c->extsts)
#define IIC_LSADR1 (&i2c->lsadr)
#define IIC_HSADR1 (&i2c->hsadr)
#define IIC_CLKDIV1 (&i2c->clkdiv)
#define IIC_INTRMSK1 (&i2c->intrmsk)
#define IIC_XFRCNT1 (&i2c->xfrcnt)
#define IIC_XTCNTLSS1 (&i2c->xtcntlss)
#define IIC_DIRECTCNTL1 (&i2c->directcntl)
void i2c1_init (int speed, int slaveadd);
int i2c_probe1 (uchar chip);
int i2c_read1 (uchar chip, uint addr, int alen, uchar * buffer, int len);
int i2c_write1 (uchar chip, uint addr, int alen, uchar * buffer, int len);
uchar i2c_reg_read1(uchar i2c_addr, uchar reg);
void i2c_reg_write1(uchar i2c_addr, uchar reg, uchar val);
#endif /* CONFIG_HARD_I2C */

View File

@ -10,7 +10,6 @@
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "ppc440gx_i2c.h"
#include "sb_common.h"
DECLARE_GLOBAL_DATA_PTR;
@ -68,7 +67,7 @@ unsigned short sbcommon_get_serial_number(void)
/* Get the board serial number from eeprom */
/* Initialize I2C */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
/* Read 256 bytes in EEPROM */
i2c_read (0x50, 0, 1, buff, 0x100);
@ -94,85 +93,87 @@ void sbcommon_fans(void)
* Attempt to turn on 2 of the fans...
* Need to go through the bridge
*/
i2c_set_bus_num(1);
puts ("FANS: ");
/* select fan4 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x08); /* val = bus 4 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x08); /* val = bus 4 */
/* Turn on FAN 4 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 4 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
/* select fan3 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x04); /* val = bus 3 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x04); /* val = bus 3 */
/* Turn on FAN 3 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 3 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
/* select fan2 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x02); /* val = bus 4 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x02); /* val = bus 4 */
/* Turn on FAN 2 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 2 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
/* select fan1 through the bridge */
i2c_reg_write1(0x73, /* addr */
0x00, /* reg */
0x01); /* val = bus 0 */
i2c_reg_write(0x73, /* addr */
0x00, /* reg */
0x01); /* val = bus 0 */
/* Turn on FAN 1 */
i2c_reg_write1(0x2e,
1,
0x80);
i2c_reg_write(0x2e,
1,
0x80);
i2c_reg_write1(0x2e,
0,
0x19);
i2c_reg_write(0x2e,
0,
0x19);
/* Deselect bus 1 on the bridge */
i2c_reg_write1(0x73,
0x00,
0x00);
i2c_reg_write(0x73,
0x00,
0x00);
puts ("on\n");
i2c_set_bus_num(0);
return;
@ -303,7 +304,7 @@ void board_get_enetaddr(int macaddr_idx, uchar *enet)
if (0 == macaddr_idx) {
/* Initialize I2C */
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
i2c_set_bus_num(0);
/* Read 256 bytes in EEPROM */
i2c_read (0x50, 0, 1, buff, 0x100);

View File

@ -12,7 +12,6 @@
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "ppc440gx_i2c.h"
/*
* GPIO Settings

View File

@ -24,8 +24,7 @@ CFLAGS += -DBUILDUSER='"$(BUILDUSER)"'
LIB = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o ../common/flash.o ../common/ppc440gx_i2c.o \
../common/sb_common.o
COBJS = $(BOARD).o ../common/flash.o ../common/sb_common.o
SOBJS = init.o

View File

@ -16,7 +16,6 @@
#include <spd_sdram.h>
#include <i2c.h>
#include "../common/sb_common.h"
#include "../common/ppc440gx_i2c.h"
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) || \
defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3)
#include <net.h>
@ -322,11 +321,6 @@ int checkboard (void)
************************************************************************/
int misc_init_f (void)
{
/* Turn on i2c bus 1 */
puts ("I2C1: ");
i2c1_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
puts ("ready\n");
/* Turn on fans 3 & 4 */
sbcommon_fans();

View File

@ -23,8 +23,7 @@ CFLAGS += -DBUILDUSER='"$(BUILDUSER)"'
LIB = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o ../common/flash.o ../common/ppc440gx_i2c.o \
../common/sb_common.o
COBJS = $(BOARD).o ../common/flash.o ../common/sb_common.o
SOBJS = init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)

View File

@ -14,7 +14,6 @@
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "../common/ppc440gx_i2c.h"
#include "../common/sb_common.h"
#if defined(CONFIG_HAS_ETH0) || defined(CONFIG_HAS_ETH1) || \
defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3)
@ -289,11 +288,6 @@ int checkboard (void)
************************************************************************/
int misc_init_f (void)
{
/* Turn on i2c bus 1 */
puts ("I2C1: ");
i2c1_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
puts ("ready\n");
/* Turn on fans */
sbcommon_fans();

View File

@ -144,7 +144,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -164,7 +164,7 @@ const iop_conf_t iop_conf_tab[4][32] = {
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
#if defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_SYS_I2C_SOFT)
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
#else

View File

@ -34,4 +34,4 @@ typedef struct{
static HWIB_INFO hwinf = {0, 0, 1, 0, 1, 0, 0, 0, 0, 8272, 0 ,0,
0, 0, 0, 0, 0, 0};
#endif
#endif /* __CONFIG_H */

View File

@ -245,7 +245,7 @@ void __dram_init_banksize(void)
void dram_init_banksize(void)
__attribute__((weak, alias("__dram_init_banksize")));
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
static int init_func_i2c(void)
{
puts("I2C: ");
@ -903,7 +903,7 @@ static init_fnc_t init_sequence_f[] = {
misc_init_f,
#endif
INIT_FUNC_WATCHDOG_RESET
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
init_func_i2c,
#endif
#if defined(CONFIG_HARD_SPI)

View File

@ -34,8 +34,13 @@ static 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 */
@ -81,7 +86,11 @@ static 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;
}

View File

@ -57,8 +57,13 @@ int dtt_i2c(void)
/* 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();
@ -70,7 +75,11 @@ int dtt_i2c(void)
printf("DTT%d: %i C\n", i + 1, dtt_get_temp(sensors[i]));
/* switch back to original I2C bus */
#ifdef CONFIG_SYS_I2C
i2c_set_bus_num(old_bus);
#else
I2C_SET_BUS(old_bus);
#endif
#endif
return 0;

View File

@ -389,8 +389,7 @@ void eeprom_init (void)
#if defined(CONFIG_SPI) && !defined(CONFIG_ENV_EEPROM_IS_ON_I2C)
spi_init_f ();
#endif
#if defined(CONFIG_HARD_I2C) || \
defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT)
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
}

View File

@ -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.
*
@ -69,6 +74,8 @@
#include <asm/byteorder.h>
#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
/* Display values from last command.
* Memory modify remembered values are different from display memory.
*/
@ -87,7 +94,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 defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS)
static struct
{
uchar bus;
@ -103,17 +110,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 */
#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 /* defined(CONFIG_SYS_I2C) */
#endif
#define DISP_LINE_LEN 16
@ -128,7 +125,6 @@ DECLARE_GLOBAL_DATA_PTR;
__weak
void i2c_init_board(void)
{
return;
}
/* TODO: Implement architecture-specific get/set functions */
@ -145,6 +141,11 @@ void i2c_init_board(void)
*
* Returns I2C bus speed in Hz.
*/
#if !defined(CONFIG_SYS_I2C)
/*
* TODO: Implement architecture-specific get/set functions
* Should go away, if we switched completely to new multibus support
*/
__weak
unsigned int i2c_get_bus_speed(void)
{
@ -172,6 +173,7 @@ int i2c_set_bus_speed(unsigned int speed)
return 0;
}
#endif
/**
* get_alen() - Small parser helper function to get address length
@ -684,7 +686,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
int found = 0;
#if defined(CONFIG_SYS_I2C_NOPROBES)
int k, skip;
uchar bus = GET_BUS_NUM;
unsigned int bus = GET_BUS_NUM;
#endif /* NOPROBES */
if (argc == 2)
@ -697,7 +699,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
#if defined(CONFIG_SYS_I2C_NOPROBES)
skip = 0;
for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
for (k = 0; k < ARRAY_SIZE(i2c_no_probes); k++) {
if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) {
skip = 1;
break;
@ -715,7 +717,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
#if defined(CONFIG_SYS_I2C_NOPROBES)
puts ("Excluded chip addresses:");
for (k=0; k < NUM_ELEMENTS_NOPROBE; k++) {
for (k = 0; k < ARRAY_SIZE(i2c_no_probes); k++) {
if (COMPARE_BUS(bus,k))
printf(" %02X", NO_PROBE_ADDR(k));
}
@ -1357,9 +1359,8 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
}
#endif /* CONFIG_I2C_EDID */
#if defined(CONFIG_I2C_MUX)
/**
* do_i2c_add_bus() - Handle the "i2c bus" command-line command
* do_i2c_show_bus() - Handle the "i2c bus" command-line command
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
@ -1367,35 +1368,55 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
*
* Returns zero always.
*/
static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
#if defined(CONFIG_SYS_I2C)
int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int ret=0;
int i;
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
int j;
#endif
if (argc == 1) {
/* show all busses */
I2C_MUX *mux;
I2C_MUX_DEVICE *device = i2c_mux_devices;
printf ("Busses reached over muxes:\n");
while (device != NULL) {
printf ("Bus ID: %x\n", device->busid);
printf (" reached over Mux(es):\n");
mux = device->mux;
while (mux != NULL) {
printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel);
mux = mux->next;
for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) {
printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
if (i2c_bus[i].next_hop[j].chip == 0)
break;
printf("->%s@0x%2x:%d",
i2c_bus[i].next_hop[j].mux.name,
i2c_bus[i].next_hop[j].chip,
i2c_bus[i].next_hop[j].channel);
}
device = device->next;
#endif
printf("\n");
}
} else {
(void)i2c_mux_ident_muxstring ((uchar *)argv[1]);
ret = 0;
/* show specific bus */
i = simple_strtoul(argv[1], NULL, 10);
if (i >= CONFIG_SYS_NUM_I2C_BUSES) {
printf("Invalid bus %d\n", i);
return -1;
}
printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name);
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) {
if (i2c_bus[i].next_hop[j].chip == 0)
break;
printf("->%s@0x%2x:%d",
i2c_bus[i].next_hop[j].mux.name,
i2c_bus[i].next_hop[j].chip,
i2c_bus[i].next_hop[j].channel);
}
#endif
printf("\n");
}
return ret;
}
#endif /* CONFIG_I2C_MUX */
#if defined(CONFIG_I2C_MULTI_BUS)
return 0;
}
#endif
/**
* do_i2c_bus_num() - Handle the "i2c dev" command-line command
* @cmdtp: Command data struct pointer
@ -1406,23 +1427,29 @@ static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar
* Returns zero on success, CMD_RET_USAGE in case of misuse and negative
* on error.
*/
static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS)
int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int bus_idx, ret=0;
int ret = 0;
unsigned int bus_no;
if (argc == 1)
/* querying current setting */
printf("Current bus is %d\n", i2c_get_bus_num());
else {
bus_idx = simple_strtoul(argv[1], NULL, 10);
printf("Setting bus to %d\n", bus_idx);
ret = i2c_set_bus_num(bus_idx);
bus_no = simple_strtoul(argv[1], NULL, 10);
if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) {
printf("Invalid bus %d\n", bus_no);
return -1;
}
printf("Setting bus to %d\n", bus_no);
ret = i2c_set_bus_num(bus_no);
if (ret)
printf("Failure changing bus number (%d)\n", ret);
}
return ret;
}
#endif /* CONFIG_I2C_MULTI_BUS */
#endif /* defined(CONFIG_SYS_I2C) */
/**
* do_i2c_bus_speed() - Handle the "i2c speed" command-line command
@ -1492,16 +1519,21 @@ 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, "", ""),
#endif /* CONFIG_I2C_MUX */
#if defined(CONFIG_SYS_I2C)
U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""),
#endif
U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
#if defined(CONFIG_I2C_MULTI_BUS)
#if defined(CONFIG_SYS_I2C) || \
defined(CONFIG_I2C_MULTI_BUS)
U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
#endif /* CONFIG_I2C_MULTI_BUS */
#if defined(CONFIG_I2C_EDID)
@ -1560,11 +1592,12 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
/***************************************************/
#ifdef CONFIG_SYS_LONGHELP
static char i2c_help_text[] =
#if defined(CONFIG_I2C_MUX)
"bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c "
#endif /* CONFIG_I2C_MUX */
#if defined(CONFIG_SYS_I2C)
"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
#endif
"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
#if defined(CONFIG_I2C_MULTI_BUS)
#if defined(CONFIG_SYS_I2C) || \
defined(CONFIG_I2C_MULTI_BUS)
"i2c dev [dev] - show or set current I2C bus\n"
#endif /* CONFIG_I2C_MULTI_BUS */
#if defined(CONFIG_I2C_EDID)
@ -1590,225 +1623,3 @@ U_BOOT_CMD(
"I2C sub-system",
i2c_help_text
);
#if defined(CONFIG_I2C_MUX)
static 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 immediately sends 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;
}
i2c_init_board();
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) {
/* do deblocking on each level of mux, before mux config */
i2c_init_board();
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;
}
/* do deblocking on each level of mux and after mux config */
i2c_init_board();
return 0;
}
#endif /* CONFIG_I2C_MUX */

View File

@ -33,24 +33,8 @@ 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 (gd->flags & GD_FLG_RELOC) {
if (env_eeprom_bus == -1) {
I2C_MUX_DEVICE *dev = NULL;
dev = i2c_mux_ident_muxstring(
(uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
if (dev != NULL)
env_eeprom_bus = dev->busid;
else
printf("error adding env eeprom bus.\n");
}
if (old_bus != env_eeprom_bus) {
i2c_set_bus_num(env_eeprom_bus);
old_bus = env_eeprom_bus;
}
} else {
rcode = i2c_mux_ident_muxstring_f(
(uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
}
if (old_bus != CONFIG_I2C_ENV_EEPROM_BUS)
i2c_set_bus_num(CONFIG_I2C_ENV_EEPROM_BUS);
#endif
rcode = eeprom_read(dev_addr, offset, buffer, cnt);
@ -59,6 +43,7 @@ static int eeprom_bus_read(unsigned dev_addr, unsigned offset,
if (old_bus != env_eeprom_bus)
i2c_set_bus_num(old_bus);
#endif
return rcode;
}
@ -69,9 +54,12 @@ static int eeprom_bus_write(unsigned dev_addr, unsigned offset,
#if defined(CONFIG_I2C_ENV_EEPROM_BUS)
int old_bus = i2c_get_bus_num();
rcode = i2c_mux_ident_muxstring_f((uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
if (old_bus != CONFIG_I2C_ENV_EEPROM_BUS)
i2c_set_bus_num(CONFIG_I2C_ENV_EEPROM_BUS);
#endif
rcode = eeprom_write(dev_addr, offset, buffer, cnt);
#if defined(CONFIG_I2C_ENV_EEPROM_BUS)
i2c_set_bus_num(old_bus);
#endif

View File

@ -1,4 +1,8 @@
/*
* Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net>
*
* Changes for multibus/multiadapter I2C support.
*
* (C) Copyright 2000
* Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
*
@ -14,7 +18,8 @@
#ifdef CONFIG_LOGBUFFER
#include <logbuff.h>
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
#include <i2c.h>
#endif
@ -194,9 +199,13 @@ int stdio_init (void)
#ifdef CONFIG_ARM_DCC
drv_arm_dcc_init ();
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
#ifdef CONFIG_SYS_I2C
i2c_init_all();
#else
#if defined(CONFIG_HARD_I2C)
i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif
#endif
#ifdef CONFIG_LCD
drv_lcd_init ();
#endif

View File

@ -12,7 +12,6 @@ LIB := $(obj)libi2c.o
COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
COBJS-$(CONFIG_DW_I2C) += designware_i2c.o
COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
@ -21,15 +20,18 @@ 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_PCA9564_I2C) += pca9564_i2c.o
COBJS-$(CONFIG_PPC4XX_I2C) += ppc4xx_i2c.o
COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
COBJS-$(CONFIG_TEGRA_I2C) += tegra_i2c.o
COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
COBJS-$(CONFIG_SYS_I2C) += i2c_core.o
COBJS-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
COBJS-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o
COBJS-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o
COBJS-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
COBJS-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
COBJS-$(CONFIG_ZYNQ_I2C) += zynq_i2c.o
COBJS := $(COBJS-y)

View File

@ -1,6 +1,9 @@
/*
* Copyright 2006,2009 Freescale Semiconductor, Inc.
*
* 2012, Heiko Schocher, DENX Software Engineering, hs@denx.de.
* Changes for multibus/multiadapter I2C support.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Version 2 as published by the Free Software Foundation.
@ -17,12 +20,8 @@
*/
#include <common.h>
#ifdef CONFIG_HARD_I2C
#include <command.h>
#include <i2c.h> /* Functional interface */
#include <asm/io.h>
#include <asm/fsl_i2c.h> /* HW definitions */
@ -47,25 +46,10 @@
DECLARE_GLOBAL_DATA_PTR;
/* Initialize the bus pointer to whatever one the SPD EEPROM is on.
* Default is bus 0. This is necessary because the DDR initialization
* runs from ROM, and we can't switch buses because we can't modify
* the global variables.
*/
#ifndef CONFIG_SYS_SPD_BUS_NUM
#define CONFIG_SYS_SPD_BUS_NUM 0
#endif
static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = CONFIG_SYS_SPD_BUS_NUM;
#if defined(CONFIG_I2C_MUX)
static unsigned int i2c_bus_num_mux __attribute__ ((section ("data"))) = 0;
#endif
static unsigned int i2c_bus_speed[2] = {CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED};
static const struct fsl_i2c *i2c_dev[2] = {
(struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET),
#ifdef CONFIG_SYS_I2C2_OFFSET
(struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C2_OFFSET)
(struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C_OFFSET),
#ifdef CONFIG_SYS_FSL_I2C2_OFFSET
(struct fsl_i2c *)(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_I2C2_OFFSET)
#endif
};
@ -222,12 +206,9 @@ static unsigned int get_i2c_clock(int bus)
return gd->arch.i2c1_clk; /* I2C1 clock */
}
void
i2c_init(int speed, int slaveadd)
static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
{
const struct fsl_i2c *dev;
unsigned int temp;
int bus_num, i;
#ifdef CONFIG_SYS_I2C_INIT_BOARD
/* Call board specific i2c bus reset routine before accessing the
@ -236,23 +217,14 @@ i2c_init(int speed, int slaveadd)
*/
i2c_init_board();
#endif
#ifdef CONFIG_SYS_I2C2_OFFSET
bus_num = 2;
#else
bus_num = 1;
#endif
for (i = 0; i < bus_num; i++) {
dev = i2c_dev[i];
dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
writeb(0, &dev->cr); /* stop I2C controller */
udelay(5); /* let it shutdown in peace */
temp = set_i2c_bus_speed(dev, get_i2c_clock(i), speed);
if (gd->flags & GD_FLG_RELOC)
i2c_bus_speed[i] = temp;
writeb(slaveadd << 1, &dev->adr);/* write slave address */
writeb(0x0, &dev->sr); /* clear status register */
writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */
}
writeb(0, &dev->cr); /* stop I2C controller */
udelay(5); /* let it shutdown in peace */
set_i2c_bus_speed(dev, get_i2c_clock(adap->hwadapnr), speed);
writeb(slaveadd << 1, &dev->adr);/* write slave address */
writeb(0x0, &dev->sr); /* clear status register */
writeb(I2C_CR_MEN, &dev->cr); /* start I2C controller */
#ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT
/* Call board specific i2c bus reset routine AFTER the bus has been
@ -265,12 +237,13 @@ i2c_init(int speed, int slaveadd)
}
static int
i2c_wait4bus(void)
i2c_wait4bus(struct i2c_adapter *adap)
{
struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
unsigned long long timeval = get_ticks();
const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {
while (readb(&dev->sr) & I2C_SR_MBB) {
if ((get_ticks() - timeval) > timeout)
return -1;
}
@ -279,20 +252,21 @@ i2c_wait4bus(void)
}
static __inline__ int
i2c_wait(int write)
i2c_wait(struct i2c_adapter *adap, int write)
{
u32 csr;
unsigned long long timeval = get_ticks();
const unsigned long long timeout = usec2ticks(CONFIG_I2C_TIMEOUT);
struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
do {
csr = readb(&i2c_dev[i2c_bus_num]->sr);
csr = readb(&dev->sr);
if (!(csr & I2C_SR_MIF))
continue;
/* Read again to allow register to stabilise */
csr = readb(&i2c_dev[i2c_bus_num]->sr);
csr = readb(&dev->sr);
writeb(0x0, &i2c_dev[i2c_bus_num]->sr);
writeb(0x0, &dev->sr);
if (csr & I2C_SR_MAL) {
debug("i2c_wait: MAL\n");
@ -317,29 +291,32 @@ i2c_wait(int write)
}
static __inline__ int
i2c_write_addr (u8 dev, u8 dir, int rsta)
i2c_write_addr(struct i2c_adapter *adap, u8 dev, u8 dir, int rsta)
{
struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
| (rsta ? I2C_CR_RSTA : 0),
&i2c_dev[i2c_bus_num]->cr);
&device->cr);
writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);
writeb((dev << 1) | dir, &device->dr);
if (i2c_wait(I2C_WRITE_BIT) < 0)
if (i2c_wait(adap, I2C_WRITE_BIT) < 0)
return 0;
return 1;
}
static __inline__ int
__i2c_write(u8 *data, int length)
__i2c_write(struct i2c_adapter *adap, u8 *data, int length)
{
struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
int i;
for (i = 0; i < length; i++) {
writeb(data[i], &i2c_dev[i2c_bus_num]->dr);
writeb(data[i], &dev->dr);
if (i2c_wait(I2C_WRITE_BIT) < 0)
if (i2c_wait(adap, I2C_WRITE_BIT) < 0)
break;
}
@ -347,57 +324,60 @@ __i2c_write(u8 *data, int length)
}
static __inline__ int
__i2c_read(u8 *data, int length)
__i2c_read(struct i2c_adapter *adap, u8 *data, int length)
{
struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
int i;
writeb(I2C_CR_MEN | I2C_CR_MSTA | ((length == 1) ? I2C_CR_TXAK : 0),
&i2c_dev[i2c_bus_num]->cr);
&dev->cr);
/* dummy read */
readb(&i2c_dev[i2c_bus_num]->dr);
readb(&dev->dr);
for (i = 0; i < length; i++) {
if (i2c_wait(I2C_READ_BIT) < 0)
if (i2c_wait(adap, I2C_READ_BIT) < 0)
break;
/* Generate ack on last next to last byte */
if (i == length - 2)
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_TXAK,
&i2c_dev[i2c_bus_num]->cr);
&dev->cr);
/* Do not generate stop on last byte */
if (i == length - 1)
writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX,
&i2c_dev[i2c_bus_num]->cr);
&dev->cr);
data[i] = readb(&i2c_dev[i2c_bus_num]->dr);
data[i] = readb(&dev->dr);
}
return i;
}
int
i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
static int
fsl_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data,
int length)
{
struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
int i = -1; /* signal error */
u8 *a = (u8*)&addr;
if (i2c_wait4bus() < 0)
if (i2c_wait4bus(adap) < 0)
return -1;
if ((!length || alen > 0)
&& i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
&& __i2c_write(&a[4 - alen], alen) == alen)
&& i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0
&& __i2c_write(adap, &a[4 - alen], alen) == alen)
i = 0; /* No error so far */
if (length &&
i2c_write_addr(dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
i = __i2c_read(data, length);
i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
i = __i2c_read(adap, data, length);
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
writeb(I2C_CR_MEN, &device->cr);
if (i2c_wait4bus()) /* Wait until STOP */
if (i2c_wait4bus(adap)) /* Wait until STOP */
debug("i2c_read: wait4bus timed out\n");
if (i == length)
@ -406,20 +386,22 @@ i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
return -1;
}
int
i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
static int
fsl_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, int alen,
u8 *data, int length)
{
struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
int i = -1; /* signal error */
u8 *a = (u8*)&addr;
if (i2c_wait4bus() >= 0
&& i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0
&& __i2c_write(&a[4 - alen], alen) == alen) {
i = __i2c_write(data, length);
if (i2c_wait4bus(adap) >= 0 &&
i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0 &&
__i2c_write(adap, &a[4 - alen], alen) == alen) {
i = __i2c_write(adap, data, length);
}
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);
if (i2c_wait4bus()) /* Wait until STOP */
writeb(I2C_CR_MEN, &device->cr);
if (i2c_wait4bus(adap)) /* Wait until STOP */
debug("i2c_write: wait4bus timed out\n");
if (i == length)
@ -428,72 +410,42 @@ i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
return -1;
}
int
i2c_probe(uchar chip)
static int
fsl_i2c_probe(struct i2c_adapter *adap, uchar chip)
{
struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
/* For unknow reason the controller will ACK when
* probing for a slave with the same address, so skip
* it.
*/
if (chip == (readb(&i2c_dev[i2c_bus_num]->adr) >> 1))
if (chip == (readb(&dev->adr) >> 1))
return -1;
return i2c_read(chip, 0, 0, NULL, 0);
return fsl_i2c_read(adap, chip, 0, 0, NULL, 0);
}
int i2c_set_bus_num(unsigned int bus)
static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,
unsigned int speed)
{
#if defined(CONFIG_I2C_MUX)
if (bus < CONFIG_SYS_MAX_I2C_BUS) {
i2c_bus_num = bus;
} else {
int ret;
struct fsl_i2c *dev = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
ret = i2x_mux_select_mux(bus);
if (ret)
return ret;
i2c_bus_num = 0;
}
i2c_bus_num_mux = bus;
#else
#ifdef CONFIG_SYS_I2C2_OFFSET
if (bus > 1) {
#else
if (bus > 0) {
#endif
return -1;
}
i2c_bus_num = bus;
#endif
return 0;
}
int i2c_set_bus_speed(unsigned int speed)
{
unsigned int i2c_clk = (i2c_bus_num == 1)
? gd->arch.i2c2_clk : gd->arch.i2c1_clk;
writeb(0, &i2c_dev[i2c_bus_num]->cr); /* stop controller */
i2c_bus_speed[i2c_bus_num] =
set_i2c_bus_speed(i2c_dev[i2c_bus_num], i2c_clk, speed);
writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr); /* start controller */
writeb(0, &dev->cr); /* stop controller */
set_i2c_bus_speed(dev, get_i2c_clock(adap->hwadapnr), speed);
writeb(I2C_CR_MEN, &dev->cr); /* start controller */
return 0;
}
unsigned int i2c_get_bus_num(void)
{
#if defined(CONFIG_I2C_MUX)
return i2c_bus_num_mux;
#else
return i2c_bus_num;
/*
* Register fsl i2c adapters
*/
U_BOOT_I2C_ADAP_COMPLETE(fsl_0, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
fsl_i2c_write, fsl_i2c_set_bus_speed,
CONFIG_SYS_FSL_I2C_SPEED, CONFIG_SYS_FSL_I2C_SLAVE,
0)
#ifdef CONFIG_SYS_FSL_I2C2_OFFSET
U_BOOT_I2C_ADAP_COMPLETE(fsl_1, fsl_i2c_init, fsl_i2c_probe, fsl_i2c_read,
fsl_i2c_write, fsl_i2c_set_bus_speed,
CONFIG_SYS_FSL_I2C2_SPEED, CONFIG_SYS_FSL_I2C2_SLAVE,
1)
#endif
}
unsigned int i2c_get_bus_speed(void)
{
return i2c_bus_speed[i2c_bus_num];
}
#endif /* CONFIG_HARD_I2C */

369
drivers/i2c/fti2c010.c Normal file
View File

@ -0,0 +1,369 @@
/*
* Faraday I2C Controller
*
* (C) Copyright 2010 Faraday Technology
* Dante Su <dantesu@faraday-tech.com>
*
* This file is released under the terms of GPL v2 and any later version.
* See the file COPYING in the root directory of the source tree for details.
*/
#include <common.h>
#include <asm/io.h>
#include <i2c.h>
#include "fti2c010.h"
#ifndef CONFIG_HARD_I2C
#error "fti2c010: CONFIG_HARD_I2C is not defined"
#endif
#ifndef CONFIG_SYS_I2C_SPEED
#define CONFIG_SYS_I2C_SPEED 50000
#endif
#ifndef CONFIG_FTI2C010_FREQ
#define CONFIG_FTI2C010_FREQ clk_get_rate("I2C")
#endif
/* command timeout */
#define CFG_CMD_TIMEOUT 10 /* ms */
/* 7-bit chip address + 1-bit read/write */
#define I2C_RD(chip) ((((chip) << 1) & 0xff) | 1)
#define I2C_WR(chip) (((chip) << 1) & 0xff)
struct fti2c010_chip {
void __iomem *regs;
uint bus;
uint speed;
};
static struct fti2c010_chip chip_list[] = {
{
.bus = 0,
.regs = (void __iomem *)CONFIG_FTI2C010_BASE,
},
#ifdef CONFIG_I2C_MULTI_BUS
# ifdef CONFIG_FTI2C010_BASE1
{
.bus = 1,
.regs = (void __iomem *)CONFIG_FTI2C010_BASE1,
},
# endif
# ifdef CONFIG_FTI2C010_BASE2
{
.bus = 2,
.regs = (void __iomem *)CONFIG_FTI2C010_BASE2,
},
# endif
# ifdef CONFIG_FTI2C010_BASE3
{
.bus = 3,
.regs = (void __iomem *)CONFIG_FTI2C010_BASE3,
},
# endif
#endif /* #ifdef CONFIG_I2C_MULTI_BUS */
};
static struct fti2c010_chip *curr = chip_list;
static int fti2c010_wait(uint32_t mask)
{
int ret = -1;
uint32_t stat, ts;
struct fti2c010_regs *regs = curr->regs;
for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
stat = readl(&regs->sr);
if ((stat & mask) == mask) {
ret = 0;
break;
}
}
return ret;
}
/*
* u-boot I2C API
*/
/*
* Initialization, must be called once on start up, may be called
* repeatedly to change the speed and slave addresses.
*/
void i2c_init(int speed, int slaveaddr)
{
if (speed || !curr->speed)
i2c_set_bus_speed(speed);
/* if slave mode disabled */
if (!slaveaddr)
return;
/*
* TODO:
* Implement slave mode, but is it really necessary?
*/
}
/*
* Probe the given I2C chip address. Returns 0 if a chip responded,
* not 0 on failure.
*/
int i2c_probe(uchar chip)
{
int ret;
struct fti2c010_regs *regs = curr->regs;
i2c_init(0, 0);
/* 1. Select slave device (7bits Address + 1bit R/W) */
writel(I2C_WR(chip), &regs->dr);
writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
return ret;
/* 2. Select device register */
writel(0, &regs->dr);
writel(CR_ENABLE | CR_TBEN, &regs->cr);
ret = fti2c010_wait(SR_DT);
return ret;
}
/*
* 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(uchar chip, uint addr, int alen, uchar *buf, int len)
{
int ret, pos;
uchar paddr[4];
struct fti2c010_regs *regs = curr->regs;
i2c_init(0, 0);
paddr[0] = (addr >> 0) & 0xFF;
paddr[1] = (addr >> 8) & 0xFF;
paddr[2] = (addr >> 16) & 0xFF;
paddr[3] = (addr >> 24) & 0xFF;
/*
* Phase A. Set register address
*/
/* A.1 Select slave device (7bits Address + 1bit R/W) */
writel(I2C_WR(chip), &regs->dr);
writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
return ret;
/* A.2 Select device register */
for (pos = 0; pos < alen; ++pos) {
uint32_t ctrl = CR_ENABLE | CR_TBEN;
writel(paddr[pos], &regs->dr);
writel(ctrl, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
return ret;
}
/*
* Phase B. Get register data
*/
/* B.1 Select slave device (7bits Address + 1bit R/W) */
writel(I2C_RD(chip), &regs->dr);
writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
return ret;
/* B.2 Get register data */
for (pos = 0; pos < len; ++pos) {
uint32_t ctrl = CR_ENABLE | CR_TBEN;
uint32_t stat = SR_DR;
if (pos == len - 1) {
ctrl |= CR_NAK | CR_STOP;
stat |= SR_ACK;
}
writel(ctrl, &regs->cr);
ret = fti2c010_wait(stat);
if (ret)
break;
buf[pos] = (uchar)(readl(&regs->dr) & 0xFF);
}
return ret;
}
/*
* 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_write(uchar chip, uint addr, int alen, uchar *buf, int len)
{
int ret, pos;
uchar paddr[4];
struct fti2c010_regs *regs = curr->regs;
i2c_init(0, 0);
paddr[0] = (addr >> 0) & 0xFF;
paddr[1] = (addr >> 8) & 0xFF;
paddr[2] = (addr >> 16) & 0xFF;
paddr[3] = (addr >> 24) & 0xFF;
/*
* Phase A. Set register address
*
* A.1 Select slave device (7bits Address + 1bit R/W)
*/
writel(I2C_WR(chip), &regs->dr);
writel(CR_ENABLE | CR_TBEN | CR_START, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
return ret;
/* A.2 Select device register */
for (pos = 0; pos < alen; ++pos) {
uint32_t ctrl = CR_ENABLE | CR_TBEN;
writel(paddr[pos], &regs->dr);
writel(ctrl, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
return ret;
}
/*
* Phase B. Set register data
*/
for (pos = 0; pos < len; ++pos) {
uint32_t ctrl = CR_ENABLE | CR_TBEN;
if (pos == len - 1)
ctrl |= CR_STOP;
writel(buf[pos], &regs->dr);
writel(ctrl, &regs->cr);
ret = fti2c010_wait(SR_DT);
if (ret)
break;
}
return ret;
}
/*
* Functions for setting the current I2C bus and its speed
*/
#ifdef CONFIG_I2C_MULTI_BUS
/*
* 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(uint bus)
{
if (bus >= ARRAY_SIZE(chip_list))
return -1;
curr = chip_list + bus;
i2c_init(0, 0);
return 0;
}
/*
* i2c_get_bus_num:
*
* Returns index of currently active I2C bus. Zero-based.
*/
uint i2c_get_bus_num(void)
{
return curr->bus;
}
#endif /* #ifdef CONFIG_I2C_MULTI_BUS */
/*
* 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
*/
int i2c_set_bus_speed(uint speed)
{
struct fti2c010_regs *regs = curr->regs;
uint clk = CONFIG_FTI2C010_FREQ;
uint gsr = 0, tsr = 32;
uint spd, div;
if (!speed)
speed = CONFIG_SYS_I2C_SPEED;
for (div = 0; div < 0x3ffff; ++div) {
/* SCLout = PCLK/(2*(COUNT + 2) + GSR) */
spd = clk / (2 * (div + 2) + gsr);
if (spd <= speed)
break;
}
if (curr->speed == spd)
return 0;
writel(CR_I2CRST, &regs->cr);
mdelay(100);
if (readl(&regs->cr) & CR_I2CRST) {
printf("fti2c010: reset timeout\n");
return -1;
}
curr->speed = spd;
writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), &regs->tgsr);
writel(CDR_DIV(div), &regs->cdr);
return 0;
}
/*
* i2c_get_bus_speed:
*
* Returns speed of currently active I2C bus in Hz
*/
uint i2c_get_bus_speed(void)
{
return curr->speed;
}

81
drivers/i2c/fti2c010.h Normal file
View File

@ -0,0 +1,81 @@
/*
* Faraday I2C Controller
*
* (C) Copyright 2010 Faraday Technology
* Dante Su <dantesu@faraday-tech.com>
*
* This file is released under the terms of GPL v2 and any later version.
* See the file COPYING in the root directory of the source tree for details.
*/
#ifndef __FTI2C010_H
#define __FTI2C010_H
/*
* FTI2C010 registers
*/
struct fti2c010_regs {
uint32_t cr; /* 0x00: control register */
uint32_t sr; /* 0x04: status register */
uint32_t cdr; /* 0x08: clock division register */
uint32_t dr; /* 0x0c: data register */
uint32_t sar; /* 0x10: slave address register */
uint32_t tgsr;/* 0x14: time & glitch suppression register */
uint32_t bmr; /* 0x18: bus monitor register */
uint32_t rsvd[5];
uint32_t revr;/* 0x30: revision register */
};
/*
* control register
*/
#define CR_ALIRQ 0x2000 /* arbitration lost interrupt (master) */
#define CR_SAMIRQ 0x1000 /* slave address match interrupt (slave) */
#define CR_STOPIRQ 0x800 /* stop condition interrupt (slave) */
#define CR_NAKRIRQ 0x400 /* NACK response interrupt (master) */
#define CR_DRIRQ 0x200 /* rx interrupt (both) */
#define CR_DTIRQ 0x100 /* tx interrupt (both) */
#define CR_TBEN 0x80 /* tx enable (both) */
#define CR_NAK 0x40 /* NACK (both) */
#define CR_STOP 0x20 /* stop (master) */
#define CR_START 0x10 /* start (master) */
#define CR_GCEN 0x8 /* general call support (slave) */
#define CR_SCLEN 0x4 /* enable clock out (master) */
#define CR_I2CEN 0x2 /* enable I2C (both) */
#define CR_I2CRST 0x1 /* reset I2C (both) */
#define CR_ENABLE \
(CR_ALIRQ | CR_NAKRIRQ | CR_DRIRQ | CR_DTIRQ | CR_SCLEN | CR_I2CEN)
/*
* status register
*/
#define SR_CLRAL 0x400 /* clear arbitration lost */
#define SR_CLRGC 0x200 /* clear general call */
#define SR_CLRSAM 0x100 /* clear slave address match */
#define SR_CLRSTOP 0x80 /* clear stop */
#define SR_CLRNAKR 0x40 /* clear NACK respond */
#define SR_DR 0x20 /* rx ready */
#define SR_DT 0x10 /* tx done */
#define SR_BB 0x8 /* bus busy */
#define SR_BUSY 0x4 /* chip busy */
#define SR_ACK 0x2 /* ACK/NACK received */
#define SR_RW 0x1 /* set when master-rx or slave-tx mode */
/*
* clock division register
*/
#define CDR_DIV(n) ((n) & 0x3ffff)
/*
* time & glitch suppression register
*/
#define TGSR_GSR(n) (((n) & 0x7) << 10)
#define TGSR_TSR(n) ((n) & 0x3ff)
/*
* bus monitor register
*/
#define BMR_SCL 0x2 /* SCL is pull-up */
#define BMR_SDA 0x1 /* SDA is pull-up */
#endif /* __FTI2C010_H */

414
drivers/i2c/i2c_core.c Normal file
View File

@ -0,0 +1,414 @@
/*
* Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net>
*
* (C) Copyright 2012
* Heiko Schocher, DENX Software Engineering, hs@denx.de.
*
* Multibus/multiadapter I2C core functions (wrappers)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <common.h>
#include <i2c.h>
struct i2c_adapter *i2c_get_adapter(int index)
{
struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter,
i2c);
int max = ll_entry_count(struct i2c_adapter, i2c);
int i;
if (index >= max) {
printf("Error, wrong i2c adapter %d max %d possible\n",
index, max);
return i2c_adap_p;
}
if (index == 0)
return i2c_adap_p;
for (i = 0; i < index; i++)
i2c_adap_p++;
return i2c_adap_p;
}
#if !defined(CONFIG_SYS_I2C_DIRECT_BUS)
struct i2c_bus_hose i2c_bus[CONFIG_SYS_NUM_I2C_BUSES] =
CONFIG_SYS_I2C_BUSES;
#endif
DECLARE_GLOBAL_DATA_PTR;
void i2c_reloc_fixup(void)
{
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter,
i2c);
struct i2c_adapter *tmp = i2c_adap_p;
int max = ll_entry_count(struct i2c_adapter, i2c);
int i;
unsigned long addr;
if (gd->reloc_off == 0)
return;
for (i = 0; i < max; i++) {
/* adapter itself */
addr = (unsigned long)i2c_adap_p;
addr += gd->reloc_off;
i2c_adap_p = (struct i2c_adapter *)addr;
/* i2c_init() */
addr = (unsigned long)i2c_adap_p->init;
addr += gd->reloc_off;
i2c_adap_p->init = (void (*)(int, int))addr;
/* i2c_probe() */
addr = (unsigned long)i2c_adap_p->probe;
addr += gd->reloc_off;
i2c_adap_p->probe = (int (*)(uint8_t))addr;
/* i2c_read() */
addr = (unsigned long)i2c_adap_p->read;
addr += gd->reloc_off;
i2c_adap_p->read = (int (*)(uint8_t, uint, int, uint8_t *,
int))addr;
/* i2c_write() */
addr = (unsigned long)i2c_adap_p->write;
addr += gd->reloc_off;
i2c_adap_p->write = (int (*)(uint8_t, uint, int, uint8_t *,
int))addr;
/* i2c_set_bus_speed() */
addr = (unsigned long)i2c_adap_p->set_bus_speed;
addr += gd->reloc_off;
i2c_adap_p->set_bus_speed = (uint (*)(uint))addr;
/* name */
addr = (unsigned long)i2c_adap_p->name;
addr += gd->reloc_off;
i2c_adap_p->name = (char *)addr;
tmp++;
i2c_adap_p = tmp;
}
#endif
}
#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(struct i2c_adapter *adap, int mux_id, int chip,
int channel)
{
uint8_t buf;
int ret;
/* channel < 0 - turn off the mux */
if (channel < 0) {
buf = 0;
ret = adap->write(adap, chip, 0, 0, &buf, 1);
if (ret)
printf("%s: Could not turn off the mux.\n", __func__);
return ret;
}
switch (mux_id) {
case I2C_MUX_PCA9540_ID:
case I2C_MUX_PCA9542_ID:
if (channel > 1)
return -1;
buf = (uint8_t)((channel & 0x01) | (1 << 2));
break;
case I2C_MUX_PCA9544_ID:
if (channel > 3)
return -1;
buf = (uint8_t)((channel & 0x03) | (1 << 2));
break;
case I2C_MUX_PCA9547_ID:
if (channel > 7)
return -1;
buf = (uint8_t)((channel & 0x07) | (1 << 3));
break;
default:
printf("%s: wrong mux id: %d\n", __func__, mux_id);
return -1;
}
ret = adap->write(adap, chip, 0, 0, &buf, 1);
if (ret)
printf("%s: could not set mux: id: %d chip: %x channel: %d\n",
__func__, mux_id, chip, channel);
return ret;
}
static int i2c_mux_set_all(void)
{
struct i2c_bus_hose *i2c_bus_tmp = &i2c_bus[I2C_BUS];
int i;
/* Connect requested bus if behind muxes */
if (i2c_bus_tmp->next_hop[0].chip != 0) {
/* Set all muxes along the path to that bus */
for (i = 0; i < CONFIG_SYS_I2C_MAX_HOPS; i++) {
int ret;
if (i2c_bus_tmp->next_hop[i].chip == 0)
break;
ret = i2c_mux_set(I2C_ADAP,
i2c_bus_tmp->next_hop[i].mux.id,
i2c_bus_tmp->next_hop[i].chip,
i2c_bus_tmp->next_hop[i].channel);
if (ret != 0)
return ret;
}
}
return 0;
}
static int i2c_mux_disconnet_all(void)
{
struct i2c_bus_hose *i2c_bus_tmp = &i2c_bus[I2C_BUS];
int i;
uint8_t buf;
if (I2C_ADAP->init_done == 0)
return 0;
/* Disconnect current bus (turn off muxes if any) */
if ((i2c_bus_tmp->next_hop[0].chip != 0) &&
(I2C_ADAP->init_done != 0)) {
i = CONFIG_SYS_I2C_MAX_HOPS;
do {
uint8_t chip;
int ret;
chip = i2c_bus_tmp->next_hop[--i].chip;
if (chip == 0)
continue;
ret = I2C_ADAP->write(I2C_ADAP, chip, 0, 0, &buf, 1);
if (ret != 0) {
printf("i2c: mux diconnect error\n");
return ret;
}
} while (i > 0);
}
return 0;
}
#endif
/*
* 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_BUSES)
return;
I2C_ADAP->init(I2C_ADAP, speed, slaveaddr);
if (gd->flags & GD_FLG_RELOC) {
I2C_ADAP->init_done = 1;
I2C_ADAP->speed = speed;
I2C_ADAP->slaveaddr = slaveaddr;
}
}
/* implement possible board specific board init */
static void __def_i2c_init_board(void)
{
}
void i2c_init_board(void)
__attribute__((weak, alias("__def_i2c_init_board")));
/*
* i2c_init_all():
*
* not longer needed, will deleted. Actual init the SPD_BUS
* for compatibility.
* i2c_adap[] must be initialized beforehead with function pointers and
* data, including speed and slaveaddr.
*/
void i2c_init_all(void)
{
i2c_init_board();
i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM);
return;
}
/*
* i2c_get_bus_num():
* ------------------
*
* Returns index of currently active I2C bus. Zero-based.
*/
unsigned int i2c_get_bus_num(void)
{
return gd->cur_i2c_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.
* 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)
{
int max = ll_entry_count(struct i2c_adapter, i2c);
if (I2C_ADAPTER(bus) >= max) {
printf("Error, wrong i2c adapter %d max %d possible\n",
I2C_ADAPTER(bus), max);
return -2;
}
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
if (bus >= CONFIG_SYS_NUM_I2C_BUSES)
return -1;
#endif
if ((bus == I2C_BUS) && (I2C_ADAP->init_done > 0))
return 0;
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
i2c_mux_disconnet_all();
#endif
gd->cur_i2c_bus = bus;
if (I2C_ADAP->init_done == 0)
i2c_init_bus(bus, I2C_ADAP->speed, I2C_ADAP->slaveaddr);
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
i2c_mux_set_all();
#endif
return 0;
}
/*
* Probe the given I2C chip address. Returns 0 if a chip responded,
* not 0 on failure.
*/
int i2c_probe(uint8_t chip)
{
return I2C_ADAP->probe(I2C_ADAP, 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(uint8_t chip, unsigned int addr, int alen,
uint8_t *buffer, int len)
{
return I2C_ADAP->read(I2C_ADAP, chip, addr, alen, buffer, len);
}
int i2c_write(uint8_t chip, unsigned int addr, int alen,
uint8_t *buffer, int len)
{
return I2C_ADAP->write(I2C_ADAP, chip, addr, alen, buffer, len);
}
unsigned int i2c_set_bus_speed(unsigned int speed)
{
unsigned int ret;
if (I2C_ADAP->set_bus_speed == NULL)
return 0;
ret = I2C_ADAP->set_bus_speed(I2C_ADAP, speed);
if (gd->flags & GD_FLG_RELOC)
I2C_ADAP->speed = ret;
return ret;
}
unsigned int i2c_get_bus_speed(void)
{
struct i2c_adapter *cur = I2C_ADAP;
return cur->speed;
}
uint8_t i2c_reg_read(uint8_t addr, uint8_t reg)
{
uint8_t buf;
#ifdef CONFIG_8xx
/* MPC8xx needs this. Maybe one day we can get rid of it. */
/* maybe it is now the time for it ... */
i2c_set_bus_num(i2c_get_bus_num());
#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_get_bus_num(), addr, reg, buf);
#endif
return buf;
}
void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val)
{
#ifdef CONFIG_8xx
/* MPC8xx needs this. Maybe one day we can get rid of it. */
/* maybe it is now the time for it ... */
i2c_set_bus_num(i2c_get_bus_num());
#endif
#ifdef DEBUG
printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n",
__func__, i2c_get_bus_num(), addr, reg, val);
#endif
i2c_write(addr, reg, 1, &val, 1);
}
void __i2c_init(int speed, int slaveaddr)
{
i2c_init_bus(i2c_get_bus_num(), speed, slaveaddr);
}
void i2c_init(int speed, int slaveaddr)
__attribute__((weak, alias("__i2c_init")));

View File

@ -22,6 +22,15 @@
#include <i2c.h>
#include <watchdog.h>
#ifdef I2C_QUIRK_REG
struct mxc_i2c_regs {
uint8_t iadr;
uint8_t ifdr;
uint8_t i2cr;
uint8_t i2sr;
uint8_t i2dr;
};
#else
struct mxc_i2c_regs {
uint32_t iadr;
uint32_t ifdr;
@ -29,8 +38,8 @@ struct mxc_i2c_regs {
uint32_t i2sr;
uint32_t i2dr;
};
#endif
#define I2CR_IEN (1 << 7)
#define I2CR_IIEN (1 << 6)
#define I2CR_MSTA (1 << 5)
#define I2CR_MTX (1 << 4)
@ -43,10 +52,39 @@ struct mxc_i2c_regs {
#define I2SR_IIF (1 << 1)
#define I2SR_RX_NO_AK (1 << 0)
#ifdef I2C_QUIRK_REG
#define I2CR_IEN (0 << 7)
#define I2CR_IDIS (1 << 7)
#define I2SR_IIF_CLEAR (1 << 1)
#else
#define I2CR_IEN (1 << 7)
#define I2CR_IDIS (0 << 7)
#define I2SR_IIF_CLEAR (0 << 1)
#endif
#if defined(CONFIG_HARD_I2C) && !defined(CONFIG_SYS_I2C_BASE)
#error "define CONFIG_SYS_I2C_BASE to use the mxc_i2c driver"
#endif
#ifdef I2C_QUIRK_REG
static u16 i2c_clk_div[60][2] = {
{ 20, 0x00 }, { 22, 0x01 }, { 24, 0x02 }, { 26, 0x03 },
{ 28, 0x04 }, { 30, 0x05 }, { 32, 0x09 }, { 34, 0x06 },
{ 36, 0x0A }, { 40, 0x07 }, { 44, 0x0C }, { 48, 0x0D },
{ 52, 0x43 }, { 56, 0x0E }, { 60, 0x45 }, { 64, 0x12 },
{ 68, 0x0F }, { 72, 0x13 }, { 80, 0x14 }, { 88, 0x15 },
{ 96, 0x19 }, { 104, 0x16 }, { 112, 0x1A }, { 128, 0x17 },
{ 136, 0x4F }, { 144, 0x1C }, { 160, 0x1D }, { 176, 0x55 },
{ 192, 0x1E }, { 208, 0x56 }, { 224, 0x22 }, { 228, 0x24 },
{ 240, 0x1F }, { 256, 0x23 }, { 288, 0x5C }, { 320, 0x25 },
{ 384, 0x26 }, { 448, 0x2A }, { 480, 0x27 }, { 512, 0x2B },
{ 576, 0x2C }, { 640, 0x2D }, { 768, 0x31 }, { 896, 0x32 },
{ 960, 0x2F }, { 1024, 0x33 }, { 1152, 0x34 }, { 1280, 0x35 },
{ 1536, 0x36 }, { 1792, 0x3A }, { 1920, 0x37 }, { 2048, 0x3B },
{ 2304, 0x3C }, { 2560, 0x3D }, { 3072, 0x3E }, { 3584, 0x7A },
{ 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E },
};
#else
static u16 i2c_clk_div[50][2] = {
{ 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 },
{ 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 },
@ -62,6 +100,7 @@ static u16 i2c_clk_div[50][2] = {
{ 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D },
{ 3072, 0x1E }, { 3840, 0x1F }
};
#endif
/*
* Calculate and set proper clock divider
@ -109,7 +148,7 @@ static int bus_i2c_set_bus_speed(void *base, int speed)
writeb(idx, &i2c_regs->ifdr);
/* Reset module */
writeb(0, &i2c_regs->i2cr);
writeb(I2CR_IDIS, &i2c_regs->i2cr);
writeb(0, &i2c_regs->i2sr);
return 0;
}
@ -141,7 +180,11 @@ static int wait_for_sr_state(struct mxc_i2c_regs *i2c_regs, unsigned state)
for (;;) {
sr = readb(&i2c_regs->i2sr);
if (sr & I2SR_IAL) {
#ifdef I2C_QUIRK_REG
writeb(sr | I2SR_IAL, &i2c_regs->i2sr);
#else
writeb(sr & ~I2SR_IAL, &i2c_regs->i2sr);
#endif
printf("%s: Arbitration lost sr=%x cr=%x state=%x\n",
__func__, sr, readb(&i2c_regs->i2cr), state);
return -ERESTART;
@ -162,7 +205,7 @@ static int tx_byte(struct mxc_i2c_regs *i2c_regs, u8 byte)
{
int ret;
writeb(0, &i2c_regs->i2sr);
writeb(I2SR_IIF_CLEAR, &i2c_regs->i2sr);
writeb(byte, &i2c_regs->i2dr);
ret = wait_for_sr_state(i2c_regs, ST_IIF);
if (ret < 0)
@ -198,14 +241,18 @@ static int i2c_init_transfer_(struct mxc_i2c_regs *i2c_regs,
int ret;
/* Enable I2C controller */
#ifdef I2C_QUIRK_REG
if (readb(&i2c_regs->i2cr) & I2CR_IDIS) {
#else
if (!(readb(&i2c_regs->i2cr) & I2CR_IEN)) {
#endif
writeb(I2CR_IEN, &i2c_regs->i2cr);
/* Wait for controller to be stable */
udelay(50);
}
if (readb(&i2c_regs->iadr) == (chip << 1))
writeb((chip << 1) ^ 2, &i2c_regs->iadr);
writeb(0, &i2c_regs->i2sr);
writeb(I2SR_IIF_CLEAR, &i2c_regs->i2sr);
ret = wait_for_sr_state(i2c_regs, ST_BUS_IDLE);
if (ret < 0)
return ret;
@ -253,7 +300,8 @@ static int i2c_init_transfer(struct mxc_i2c_regs *i2c_regs,
printf("%s: failed for chip 0x%x retry=%d\n", __func__, chip,
retry);
if (ret != -ERESTART)
writeb(0, &i2c_regs->i2cr); /* Disable controller */
/* Disable controller */
writeb(I2CR_IDIS, &i2c_regs->i2cr);
udelay(100);
if (i2c_idle_bus(i2c_regs) < 0)
break;
@ -293,7 +341,7 @@ int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf,
if (len == 1)
temp |= I2CR_TX_NO_AK;
writeb(temp, &i2c_regs->i2cr);
writeb(0, &i2c_regs->i2sr);
writeb(I2SR_IIF_CLEAR, &i2c_regs->i2sr);
readb(&i2c_regs->i2dr); /* dummy read to clear ICF */
/* read data */
@ -315,7 +363,7 @@ int bus_i2c_read(void *base, uchar chip, uint addr, int alen, uchar *buf,
temp |= I2CR_TX_NO_AK;
writeb(temp, &i2c_regs->i2cr);
}
writeb(0, &i2c_regs->i2sr);
writeb(I2SR_IIF_CLEAR, &i2c_regs->i2sr);
buf[i] = readb(&i2c_regs->i2dr);
}
i2c_imx_stop(i2c_regs);

View File

@ -16,27 +16,29 @@
#include <i2c.h>
#include <asm/io.h>
#ifdef CONFIG_HARD_I2C
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_I2C_MULTI_BUS)
/*
* Initialize the bus pointer to whatever one the SPD EEPROM is on.
* Default is bus 0. This is necessary because the DDR initialization
* runs from ROM, and we can't switch buses because we can't modify
* the global variables.
*/
#ifndef CONFIG_SYS_SPD_BUS_NUM
#define CONFIG_SYS_SPD_BUS_NUM 0
#endif
static unsigned int i2c_bus_num __attribute__ ((section (".data"))) =
CONFIG_SYS_SPD_BUS_NUM;
#endif /* CONFIG_I2C_MULTI_BUS */
static void _i2c_bus_reset(void)
static inline struct ppc4xx_i2c *ppc4xx_get_i2c(int hwadapnr)
{
struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
unsigned long base;
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
base = CONFIG_SYS_PERIPHERAL_BASE + 0x00000700 + (hwadapnr * 0x100);
#elif defined(CONFIG_440) || defined(CONFIG_405EX)
/* all remaining 440 variants */
base = CONFIG_SYS_PERIPHERAL_BASE + 0x00000400 + (hwadapnr * 0x100);
#else
/* all 405 variants */
base = 0xEF600500 + (hwadapnr * 0x100);
#endif
return (struct ppc4xx_i2c *)base;
}
static void _i2c_bus_reset(struct i2c_adapter *adap)
{
struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr);
int i;
u8 dc;
@ -75,11 +77,10 @@ static void _i2c_bus_reset(void)
out_8(&i2c->xtcntlss, 0);
}
void i2c_init(int speed, int slaveaddr)
static void ppc4xx_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
{
struct ppc4xx_i2c *i2c;
struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr);
int val, divisor;
int bus;
#ifdef CONFIG_SYS_I2C_INIT_BOARD
/*
@ -90,67 +91,57 @@ void i2c_init(int speed, int slaveaddr)
i2c_init_board();
#endif
for (bus = 0; bus < CONFIG_SYS_MAX_I2C_BUS; bus++) {
I2C_SET_BUS(bus);
/* Handle possible failed I2C state */
/* FIXME: put this into i2c_init_board()? */
_i2c_bus_reset(adap);
/* Set i2c pointer after calling I2C_SET_BUS() */
i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
/* clear lo master address */
out_8(&i2c->lmadr, 0);
/* Handle possible failed I2C state */
/* FIXME: put this into i2c_init_board()? */
_i2c_bus_reset();
/* clear hi master address */
out_8(&i2c->hmadr, 0);
/* clear lo master address */
out_8(&i2c->lmadr, 0);
/* clear lo slave address */
out_8(&i2c->lsadr, 0);
/* clear hi master address */
out_8(&i2c->hmadr, 0);
/* clear hi slave address */
out_8(&i2c->hsadr, 0);
/* clear lo slave address */
out_8(&i2c->lsadr, 0);
/* Clock divide Register */
/* set divisor according to freq_opb */
divisor = (get_OPB_freq() - 1) / 10000000;
if (divisor == 0)
divisor = 1;
out_8(&i2c->clkdiv, divisor);
/* clear hi slave address */
out_8(&i2c->hsadr, 0);
/* no interrupts */
out_8(&i2c->intrmsk, 0);
/* Clock divide Register */
/* set divisor according to freq_opb */
divisor = (get_OPB_freq() - 1) / 10000000;
if (divisor == 0)
divisor = 1;
out_8(&i2c->clkdiv, divisor);
/* clear transfer count */
out_8(&i2c->xfrcnt, 0);
/* no interrupts */
out_8(&i2c->intrmsk, 0);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out_8(&i2c->xtcntlss, 0xF0);
/* clear transfer count */
out_8(&i2c->xfrcnt, 0);
/* Mode Control Register
Flush Slave/Master data buffer */
out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
/* clear extended control & stat */
/* write 1 in SRC SRS SWC SWS to clear these fields */
out_8(&i2c->xtcntlss, 0xF0);
val = in_8(&i2c->mdcntl);
/* Mode Control Register
Flush Slave/Master data buffer */
out_8(&i2c->mdcntl, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB);
/* Ignore General Call, slave transfers are ignored,
* disable interrupts, exit unknown bus state, enable hold
* SCL 100kHz normaly or FastMode for 400kHz and above
*/
val = in_8(&i2c->mdcntl);
val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL;
if (speed >= 400000)
val |= IIC_MDCNTL_FSM;
out_8(&i2c->mdcntl, val);
/* Ignore General Call, slave transfers are ignored,
* disable interrupts, exit unknown bus state, enable hold
* SCL 100kHz normaly or FastMode for 400kHz and above
*/
val |= IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL;
if (speed >= 400000)
val |= IIC_MDCNTL_FSM;
out_8(&i2c->mdcntl, val);
/* clear control reg */
out_8(&i2c->cntl, 0x00);
}
/* set to SPD bus as default bus upon powerup */
I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM);
/* clear control reg */
out_8(&i2c->cntl, 0x00);
}
/*
@ -178,14 +169,15 @@ void i2c_init(int speed, int slaveaddr)
*
* It does not check XFRCNT.
*/
static int i2c_transfer(unsigned char cmd_type,
static int _i2c_transfer(struct i2c_adapter *adap,
unsigned char cmd_type,
unsigned char chip,
unsigned char addr[],
unsigned char addr_len,
unsigned char data[],
unsigned short data_len)
{
struct ppc4xx_i2c *i2c = (struct ppc4xx_i2c *)I2C_BASE_ADDR;
struct ppc4xx_i2c *i2c = ppc4xx_get_i2c(adap->hwadapnr);
u8 *ptr;
int reading;
int tran, cnt;
@ -329,7 +321,7 @@ static int i2c_transfer(unsigned char cmd_type,
return result;
}
int i2c_probe(uchar chip)
static int ppc4xx_i2c_probe(struct i2c_adapter *adap, uchar chip)
{
uchar buf[1];
@ -340,11 +332,11 @@ int i2c_probe(uchar chip)
* address was <ACK>ed (i.e. there was a chip at that address which
* drove the data line low).
*/
return (i2c_transfer(1, chip << 1, 0, 0, buf, 1) != 0);
return (_i2c_transfer(adap, 1, chip << 1, 0, 0, buf, 1) != 0);
}
static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer,
int len, int read)
static int ppc4xx_i2c_transfer(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len, int read)
{
uchar xaddr[4];
int ret;
@ -378,43 +370,50 @@ static int ppc4xx_i2c_transfer(uchar chip, uint addr, int alen, uchar *buffer,
chip |= ((addr >> (alen * 8)) &
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
#endif
if ((ret = i2c_transfer(read, chip << 1, &xaddr[4 - alen], alen,
buffer, len)) != 0) {
ret = _i2c_transfer(adap, read, chip << 1, &xaddr[4 - alen], alen,
buffer, len);
if (ret) {
printf("I2C %s: failed %d\n", read ? "read" : "write", ret);
return 1;
}
return 0;
}
int i2c_read(uchar chip, uint addr, int alen, uchar * buffer, int len)
static int ppc4xx_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 1);
return ppc4xx_i2c_transfer(adap, chip, addr, alen, buffer, len, 1);
}
int i2c_write(uchar chip, uint addr, int alen, uchar * buffer, int len)
static int ppc4xx_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
return ppc4xx_i2c_transfer(chip, addr, alen, buffer, len, 0);
return ppc4xx_i2c_transfer(adap, chip, addr, alen, buffer, len, 0);
}
#if defined(CONFIG_I2C_MULTI_BUS)
/*
* Functions for multiple I2C bus handling
*/
unsigned int i2c_get_bus_num(void)
static unsigned int ppc4xx_i2c_set_bus_speed(struct i2c_adapter *adap,
unsigned int speed)
{
return i2c_bus_num;
}
int i2c_set_bus_num(unsigned int bus)
{
if (bus >= CONFIG_SYS_MAX_I2C_BUS)
if (speed != adap->speed)
return -1;
i2c_bus_num = bus;
return 0;
return speed;
}
#endif /* CONFIG_I2C_MULTI_BUS */
#endif /* CONFIG_HARD_I2C */
/*
* Register ppc4xx i2c adapters
*/
#ifdef CONFIG_SYS_I2C_PPC4XX_CH0
U_BOOT_I2C_ADAP_COMPLETE(ppc4xx_0, ppc4xx_i2c_init, ppc4xx_i2c_probe,
ppc4xx_i2c_read, ppc4xx_i2c_write,
ppc4xx_i2c_set_bus_speed,
CONFIG_SYS_I2C_PPC4XX_SPEED_0,
CONFIG_SYS_I2C_PPC4XX_SLAVE_0, 0)
#endif
#ifdef CONFIG_SYS_I2C_PPC4XX_CH1
U_BOOT_I2C_ADAP_COMPLETE(ppc4xx_1, ppc4xx_i2c_init, ppc4xx_i2c_probe,
ppc4xx_i2c_read, ppc4xx_i2c_write,
ppc4xx_i2c_set_bus_speed,
CONFIG_SYS_I2C_PPC4XX_SPEED_1,
CONFIG_SYS_I2C_PPC4XX_SLAVE_1, 1)
#endif

View File

@ -1,4 +1,8 @@
/*
* (C) Copyright 2009
* Heiko Schocher, DENX Software Engineering, hs@denx.de.
* Changes for multibus/multiadapter I2C support.
*
* (C) Copyright 2001, 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
@ -87,14 +91,30 @@
/* #define DEBUG_I2C */
#ifdef DEBUG_I2C
DECLARE_GLOBAL_DATA_PTR;
#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
#endif
#if !defined(CONFIG_SYS_SOFT_I2C_SPEED)
#define CONFIG_SYS_SOFT_I2C_SPEED CONFIG_SYS_I2C_SPEED
#endif
#if !defined(CONFIG_SYS_SOFT_I2C_SLAVE)
#define CONFIG_SYS_SOFT_I2C_SLAVE CONFIG_SYS_I2C_SLAVE
#endif
/*-----------------------------------------------------------------------
* Definitions
*/
#define RETRIES 0
#define I2C_ACK 0 /* PD_SDA level to ack a byte */
@ -109,10 +129,6 @@ 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
*/
@ -251,39 +267,6 @@ static int write_byte(uchar data)
return(nack); /* not a nack is an ack */
}
#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);
i2c_init_board();
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;
}
#endif
/*-----------------------------------------------------------------------
* if ack == I2C_ACK, ACK the byte so can continue reading, else
* send I2C_NOACK to end the read.
@ -314,14 +297,10 @@ static uchar read_byte(int ack)
return(data);
}
/*=====================================================================*/
/* Public Functions */
/*=====================================================================*/
/*-----------------------------------------------------------------------
* Initialization
*/
void i2c_init (int speed, int slaveaddr)
static void soft_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
{
#if defined(CONFIG_SYS_I2C_INIT_BOARD)
/* call board specific i2c bus reset routine before accessing the */
@ -344,7 +323,7 @@ void i2c_init (int speed, int slaveaddr)
* completion of EEPROM writes since the chip stops responding until
* the write completes (typically 10mSec).
*/
int i2c_probe(uchar addr)
static int soft_i2c_probe(struct i2c_adapter *adap, uint8_t addr)
{
int rc;
@ -362,7 +341,8 @@ int i2c_probe(uchar addr)
/*-----------------------------------------------------------------------
* Read bytes
*/
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
static int soft_i2c_read(struct i2c_adapter *adap, 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",
@ -436,7 +416,8 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
/*-----------------------------------------------------------------------
* Write bytes
*/
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
static int soft_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
int shift, failures = 0;
@ -466,3 +447,32 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
send_stop();
return(failures);
}
/*
* Register soft i2c adapters
*/
U_BOOT_I2C_ADAP_COMPLETE(soft0, soft_i2c_init, soft_i2c_probe,
soft_i2c_read, soft_i2c_write, NULL,
CONFIG_SYS_I2C_SOFT_SPEED, CONFIG_SYS_I2C_SOFT_SLAVE,
0)
#if defined(I2C_SOFT_DECLARATIONS2)
U_BOOT_I2C_ADAP_COMPLETE(soft1, soft_i2c_init, soft_i2c_probe,
soft_i2c_read, soft_i2c_write, NULL,
CONFIG_SYS_I2C_SOFT_SPEED_2,
CONFIG_SYS_I2C_SOFT_SLAVE_2,
1)
#endif
#if defined(I2C_SOFT_DECLARATIONS3)
U_BOOT_I2C_ADAP_COMPLETE(soft2, soft_i2c_init, soft_i2c_probe,
soft_i2c_read, soft_i2c_write, NULL,
CONFIG_SYS_I2C_SOFT_SPEED_3,
CONFIG_SYS_I2C_SOFT_SLAVE_3,
2)
#endif
#if defined(I2C_SOFT_DECLARATIONS4)
U_BOOT_I2C_ADAP_COMPLETE(soft3, soft_i2c_init, soft_i2c_probe,
soft_i2c_read, soft_i2c_write, NULL,
CONFIG_SYS_I2C_SOFT_SPEED_4,
CONFIG_SYS_I2C_SOFT_SLAVE_4,
3)
#endif

View File

@ -19,8 +19,6 @@
DECLARE_GLOBAL_DATA_PTR;
static unsigned int i2c_bus_num;
/* Information about i2c controller */
struct i2c_bus {
int id;
@ -268,7 +266,8 @@ exit:
return error;
}
static int tegra_i2c_write_data(u32 addr, u8 *data, u32 len)
static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data,
u32 len)
{
int error;
struct i2c_trans_info trans_info;
@ -279,14 +278,15 @@ static int tegra_i2c_write_data(u32 addr, u8 *data, u32 len)
trans_info.num_bytes = len;
trans_info.is_10bit_address = 0;
error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info);
error = send_recv_packets(bus, &trans_info);
if (error)
debug("tegra_i2c_write_data: Error (%d) !!!\n", error);
return error;
}
static int tegra_i2c_read_data(u32 addr, u8 *data, u32 len)
static int tegra_i2c_read_data(struct i2c_bus *bus, u32 addr, u8 *data,
u32 len)
{
int error;
struct i2c_trans_info trans_info;
@ -297,7 +297,7 @@ static int tegra_i2c_read_data(u32 addr, u8 *data, u32 len)
trans_info.num_bytes = len;
trans_info.is_10bit_address = 0;
error = send_recv_packets(&i2c_controllers[i2c_bus_num], &trans_info);
error = send_recv_packets(bus, &trans_info);
if (error)
debug("tegra_i2c_read_data: Error (%d) !!!\n", error);
@ -308,18 +308,35 @@ static int tegra_i2c_read_data(u32 addr, u8 *data, u32 len)
#error "Please enable device tree support to use this driver"
#endif
unsigned int i2c_get_bus_speed(void)
/**
* Check that a bus number is valid and return a pointer to it
*
* @param bus_num Bus number to check / return
* @return pointer to bus, if valid, else NULL
*/
static struct i2c_bus *tegra_i2c_get_bus(struct i2c_adapter *adap)
{
return i2c_controllers[i2c_bus_num].speed;
struct i2c_bus *bus;
bus = &i2c_controllers[adap->hwadapnr];
if (!bus->inited) {
debug("%s: Bus %u not available\n", __func__, adap->hwadapnr);
return NULL;
}
return bus;
}
int i2c_set_bus_speed(unsigned int speed)
static unsigned int tegra_i2c_set_bus_speed(struct i2c_adapter *adap,
unsigned int speed)
{
struct i2c_bus *i2c_bus;
struct i2c_bus *bus;
i2c_bus = &i2c_controllers[i2c_bus_num];
i2c_bus->speed = speed;
i2c_init_controller(i2c_bus);
bus = tegra_i2c_get_bus(adap);
if (!bus)
return 0;
bus->speed = speed;
i2c_init_controller(bus);
return 0;
}
@ -434,7 +451,7 @@ void i2c_init_board(void)
return;
}
void i2c_init(int speed, int slaveaddr)
static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
{
/* This will override the speed selected in the fdt for that port */
debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
@ -442,7 +459,7 @@ void i2c_init(int speed, int slaveaddr)
}
/* i2c write version without the register address */
int i2c_write_data(uchar chip, uchar *buffer, int len)
int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
{
int rc;
@ -454,7 +471,7 @@ int i2c_write_data(uchar chip, uchar *buffer, int len)
debug("\n");
/* Shift 7-bit address over for lower-level i2c functions */
rc = tegra_i2c_write_data(chip << 1, buffer, len);
rc = tegra_i2c_write_data(bus, chip << 1, buffer, len);
if (rc)
debug("i2c_write_data(): rc=%d\n", rc);
@ -462,13 +479,13 @@ int i2c_write_data(uchar chip, uchar *buffer, int len)
}
/* i2c read version without the register address */
int i2c_read_data(uchar chip, uchar *buffer, int len)
int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer, int len)
{
int rc;
debug("inside i2c_read_data():\n");
/* Shift 7-bit address over for lower-level i2c functions */
rc = tegra_i2c_read_data(chip << 1, buffer, len);
rc = tegra_i2c_read_data(bus, chip << 1, buffer, len);
if (rc) {
debug("i2c_read_data(): rc=%d\n", rc);
return rc;
@ -484,14 +501,18 @@ int i2c_read_data(uchar chip, uchar *buffer, int len)
}
/* Probe to see if a chip is present. */
int i2c_probe(uchar chip)
static int tegra_i2c_probe(struct i2c_adapter *adap, uchar chip)
{
struct i2c_bus *bus;
int rc;
uchar reg;
debug("i2c_probe: addr=0x%x\n", chip);
bus = tegra_i2c_get_bus(adap);
if (!bus)
return 1;
reg = 0;
rc = i2c_write_data(chip, &reg, 1);
rc = i2c_write_data(bus, chip, &reg, 1);
if (rc) {
debug("Error probing 0x%x.\n", chip);
return 1;
@ -506,13 +527,18 @@ static int i2c_addr_ok(const uint addr, const int alen)
}
/* Read bytes */
int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
struct i2c_bus *bus;
uint offset;
int i;
debug("i2c_read: chip=0x%x, addr=0x%x, len=0x%x\n",
chip, addr, len);
bus = tegra_i2c_get_bus(adap);
if (!bus)
return 1;
if (!i2c_addr_ok(addr, alen)) {
debug("i2c_read: Bad address %x.%d.\n", addr, alen);
return 1;
@ -524,13 +550,13 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
data[alen - i - 1] =
(addr + offset) >> (8 * i);
}
if (i2c_write_data(chip, data, alen)) {
if (i2c_write_data(bus, chip, data, alen)) {
debug("i2c_read: error sending (0x%x)\n",
addr);
return 1;
}
}
if (i2c_read_data(chip, buffer + offset, 1)) {
if (i2c_read_data(bus, chip, buffer + offset, 1)) {
debug("i2c_read: error reading (0x%x)\n", addr);
return 1;
}
@ -540,13 +566,18 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
}
/* Write bytes */
int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
static int tegra_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
int alen, uchar *buffer, int len)
{
struct i2c_bus *bus;
uint offset;
int i;
debug("i2c_write: chip=0x%x, addr=0x%x, len=0x%x\n",
chip, addr, len);
bus = tegra_i2c_get_bus(adap);
if (!bus)
return 1;
if (!i2c_addr_ok(addr, alen)) {
debug("i2c_write: Bad address %x.%d.\n", addr, alen);
return 1;
@ -556,7 +587,7 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
for (i = 0; i < alen; i++)
data[alen - i - 1] = (addr + offset) >> (8 * i);
data[alen] = buffer[offset];
if (i2c_write_data(chip, data, alen + 1)) {
if (i2c_write_data(bus, chip, data, alen + 1)) {
debug("i2c_write: error sending (0x%x)\n", addr);
return 1;
}
@ -565,30 +596,11 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
return 0;
}
#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 (bus >= TEGRA_I2C_NUM_CONTROLLERS || !i2c_controllers[bus].inited)
return -1;
i2c_bus_num = bus;
return 0;
}
#endif
int tegra_i2c_get_dvc_bus_num(void)
{
int i;
for (i = 0; i < CONFIG_SYS_MAX_I2C_BUS; i++) {
for (i = 0; i < TEGRA_I2C_NUM_CONTROLLERS; i++) {
struct i2c_bus *bus = &i2c_controllers[i];
if (bus->inited && bus->is_dvc)
@ -597,3 +609,19 @@ int tegra_i2c_get_dvc_bus_num(void)
return -1;
}
/*
* Register soft i2c adapters
*/
U_BOOT_I2C_ADAP_COMPLETE(tegra0, tegra_i2c_init, tegra_i2c_probe,
tegra_i2c_read, tegra_i2c_write,
tegra_i2c_set_bus_speed, 100000, 0, 0)
U_BOOT_I2C_ADAP_COMPLETE(tegra1, tegra_i2c_init, tegra_i2c_probe,
tegra_i2c_read, tegra_i2c_write,
tegra_i2c_set_bus_speed, 100000, 0, 1)
U_BOOT_I2C_ADAP_COMPLETE(tegra2, tegra_i2c_init, tegra_i2c_probe,
tegra_i2c_read, tegra_i2c_write,
tegra_i2c_set_bus_speed, 100000, 0, 2)
U_BOOT_I2C_ADAP_COMPLETE(tegra3, tegra_i2c_init, tegra_i2c_probe,
tegra_i2c_read, tegra_i2c_write,
tegra_i2c_set_bus_speed, 100000, 0, 3)

View File

@ -68,6 +68,9 @@ typedef struct global_data {
char env_buf[32]; /* buffer for getenv() before reloc. */
#ifdef CONFIG_TRACE
void *trace_buff; /* The trace buffer */
#endif
#if defined(CONFIG_SYS_I2C)
int cur_i2c_bus; /* current used i2c bus */
#endif
struct arch_global_data arch; /* architecture-specific data */
} gd_t;

View File

@ -70,8 +70,8 @@
* PCI stuff
*-----------------------------------------------------------------------
*/
#define CONFIG_HARD_I2C 1 /* To enable I2C support */
#undef CONFIG_SOFT_I2C /* I2C bit-banged */
#define CONFIG_HARD_I2C 1 /* To enable I2C support */
#undef CONFIG_SYS_I2C_SOFT /* I2C bit-banged */
#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */
#define CONFIG_SYS_I2C_SLAVE 0x7F

View File

@ -290,10 +290,11 @@
/*
* I2C EEPROM (CAT24WC16) for environment
*/
#define CONFIG_HARD_I2C /* I2c with hardware support */
#define CONFIG_PPC4XX_I2C /* use PPC4xx driver */
#define CONFIG_SYS_I2C_SPEED 100000 /* I2C speed and slave address */
#define CONFIG_SYS_I2C_SLAVE 0x7F
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_PPC4XX
#define CONFIG_SYS_I2C_PPC4XX_CH0
#define CONFIG_SYS_I2C_PPC4XX_SPEED_0 100000
#define CONFIG_SYS_I2C_PPC4XX_SLAVE_0 0x7F
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */

View File

@ -231,10 +231,11 @@
/*-----------------------------------------------------------------------
* I2C EEPROM (CAT24WC16) for environment
*/
#define CONFIG_HARD_I2C /* I2c with hardware support */
#define CONFIG_PPC4XX_I2C /* use PPC4xx driver */
#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address */
#define CONFIG_SYS_I2C_SLAVE 0x7F
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_PPC4XX
#define CONFIG_SYS_I2C_PPC4XX_CH0
#define CONFIG_SYS_I2C_PPC4XX_SPEED_0 400000
#define CONFIG_SYS_I2C_PPC4XX_SLAVE_0 0x7F
#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT28WC08 */
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */

View File

@ -443,14 +443,14 @@ unsigned long get_board_ddr_clk(void);
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
/* I2C */
#define CONFIG_FSL_I2C /* Use FSL common I2C driver */
#define CONFIG_HARD_I2C /* I2C with hardware support */
#define CONFIG_I2C_MULTI_BUS
#define CONFIG_I2C_CMD_TREE
#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed in Hz */
#define CONFIG_SYS_I2C_SLAVE 0x7F
#define CONFIG_SYS_I2C_OFFSET 0x118000
#define CONFIG_SYS_I2C2_OFFSET 0x119000
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_FSL /* Use FSL common I2C driver */
#define CONFIG_SYS_FSL_I2C_SPEED 400000 /* I2C speed in Hz */
#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
#define CONFIG_SYS_FSL_I2C2_SPEED 400000 /* I2C speed in Hz */
#define CONFIG_SYS_FSL_I2C2_SLAVE 0x7F
#define CONFIG_SYS_FSL_I2C_OFFSET 0x118000
#define CONFIG_SYS_FSL_I2C2_OFFSET 0x119000
/*
* RTC configuration

View File

@ -259,13 +259,11 @@ extern unsigned long get_sdram_size(void);
#define CONFIG_FIT
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
#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_I2C_MULTI_BUS
#define CONFIG_I2C_CMD_TREE
#define CONFIG_SYS_I2C_SPEED 400000 /* I2C speed and slave address*/
#define CONFIG_SYS_I2C_OFFSET 0x3000
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_FSL
#define CONFIG_SYS_FSL_I2C_SPEED 400000
#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
#define CONFIG_SYS_FSL_I2C_OFFSET 0x3000
/* I2C EEPROM */
#define CONFIG_CMD_EEPROM

View File

@ -435,15 +435,14 @@ combinations. this should be removed later
#define CONFIG_FIT
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
#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_I2C_MULTI_BUS
#define CONFIG_I2C_CMD_TREE
#define CONFIG_SYS_I2C_SPEED 400800 /* I2C speed and slave address*/
#define CONFIG_SYS_I2C_SLAVE 0x7F
#define CONFIG_SYS_I2C_OFFSET 0x3000
#define CONFIG_SYS_I2C2_OFFSET 0x3100
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_FSL
#define CONFIG_SYS_FSL_I2C_SPEED 400800 /* I2C speed and slave address*/
#define CONFIG_SYS_FSL_I2C_SLAVE 0x7F
#define CONFIG_SYS_FSL_I2C2_SPEED 400800 /* I2C speed and slave address*/
#define CONFIG_SYS_FSL_I2C2_SLAVE 0x7F
#define CONFIG_SYS_FSL_I2C_OFFSET 0x3000
#define CONFIG_SYS_FSL_I2C2_OFFSET 0x3100
/* I2C EEPROM */
#define CONFIG_ID_EEPROM

Some files were not shown because too many files have changed in this diff Show More