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:
commit
c2120fbfbc
321 changed files with 3120 additions and 2616 deletions
173
README
173
README
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -272,7 +272,7 @@ int drv_video_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOFT_I2C
|
||||
#ifdef CONFIG_SYS_I2C_SOFT
|
||||
|
||||
void i2c_init_board(void)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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, ®8, sizeof(reg8)) == 0) ||
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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);
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <asm/io.h>
|
||||
#include <spd_sdram.h>
|
||||
#include <i2c.h>
|
||||
#include "ppc440gx_i2c.h"
|
||||
|
||||
/*
|
||||
* GPIO Settings
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
359
common/cmd_i2c.c
359
common/cmd_i2c.c
|
@ -1,4 +1,9 @@
|
|||
/*
|
||||
* (C) Copyright 2009
|
||||
* Sergey Kubushyn, himself, ksi@koi8.net
|
||||
*
|
||||
* Changes for unified multibus/multiadapter I2C support.
|
||||
*
|
||||
* (C) Copyright 2001
|
||||
* Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
|
||||
*
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
369
drivers/i2c/fti2c010.c
Normal 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(®s->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), ®s->dr);
|
||||
writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr);
|
||||
ret = fti2c010_wait(SR_DT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 2. Select device register */
|
||||
writel(0, ®s->dr);
|
||||
writel(CR_ENABLE | CR_TBEN, ®s->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), ®s->dr);
|
||||
writel(CR_ENABLE | CR_TBEN | CR_START, ®s->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], ®s->dr);
|
||||
writel(ctrl, ®s->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), ®s->dr);
|
||||
writel(CR_ENABLE | CR_TBEN | CR_START, ®s->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, ®s->cr);
|
||||
ret = fti2c010_wait(stat);
|
||||
if (ret)
|
||||
break;
|
||||
buf[pos] = (uchar)(readl(®s->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), ®s->dr);
|
||||
writel(CR_ENABLE | CR_TBEN | CR_START, ®s->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], ®s->dr);
|
||||
writel(ctrl, ®s->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], ®s->dr);
|
||||
writel(ctrl, ®s->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, ®s->cr);
|
||||
mdelay(100);
|
||||
if (readl(®s->cr) & CR_I2CRST) {
|
||||
printf("fti2c010: reset timeout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
curr->speed = spd;
|
||||
|
||||
writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr);
|
||||
writel(CDR_DIV(div), ®s->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
81
drivers/i2c/fti2c010.h
Normal 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
414
drivers/i2c/i2c_core.c
Normal 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")));
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ®, 1);
|
||||
rc = i2c_write_data(bus, chip, ®, 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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue