Hi,
i want to use i2c1 at u-boot level. i'm using u-boot code from AM335x EVM, in u-boot code "board/ti/am335x/evm.c" i saw the include file <i2c.h>, and how it use to enable i2c0,
can i really use <i2c.h> header file to enable i2c1 as well? any changes needed?
Thanks
Keldy
Hi Keldy,
In u-boot i2c0 is enabled by default, you can go through "read_eeprom()" API for usage.
Yes, you have to add i2c.h
i2c1 sould be register in the simillar lines as that of i2c0.
* Do proper pinmuxing
* enable i2c1 clocks
* i2c_int()
Note: In software I2C instances are starting from 1 instead of 0 (HW)
Regards
AnilKumar
Please mark this Forum post as answered via the Verify Answer button below if it helps answer your question. Thanks!
Also you need to setup pin-mux for i2c1 pins.
so you need to setup
1. i2c1 clocks
2. i2c1 pin-mux
3. proper i2c1 base address to be used by omap-i2c driver
4. verify that the omap-i2c driver supports multi-bus and use it accordingly
Gururaja
Does this help with your question? If not, please send back more information. If it answers your question, please click the Verify Answer button.
Hi All,
I build a i2c1 function inside u-boot code, ("board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c"), in this case, i plan to communicate with i2c port expander (tca6416) with chip address 0x20, communication speed 400k.
___________________________________________________________________
void i2c1(void){ u32 val; val = __raw_readl(CONF_SPI0_D1); //pin_mux i2c1_sda val = (val & 0xFFFFFFF1 | 0x2); __raw_writel(val, CONF_SPI0_D1);
val = __raw_readl(CONF_SPI0_CS0); //pin_mux i2c1_scl val = (val & 0xFFFFFFF1 | 0x2); __raw_writel(val, CONF_SPI0_CS0);
i2c_init(400000, 0x20); //i2c speed 400k, i2c port expander (tca6416) chip address 0x20 printf("sending value = 0xFF\n"); //write value i2c_write(0x20, 0x06, 1, 0xFF, 1); uchar read_val; //read value printf("reading value :"); i2c_read(0x20, 0x06, 1, &read_val, 1); printf("%d\n", read_val); }
am i correct? is the i2c_init(), i2c_write(), i2c_read() functions applicable for i2c1 ?
Thanks & Regards
I dont think thats enough. By default u-boot i2c driver will be working for i2c-0 instance. so you need to switch it to i2c-1 instance.
Also look at board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/mux.c on how i2c0 pin-mux is done.
Have you set i2c1 clocks (controller clocks & not i2c device clocks). for this look at board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/pll.c
in "board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/mux.c"
i have changed: PULLUDEN to PULLUDDIS (because i use external pull-up)
static struct module_pin_mux i2c1_pin_mux[] = { {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | PULLUDDIS | SLEWCTRL)}, /* I2C_DATA */ {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | PULLUDDIS | SLEWCTRL)}, /* I2C_SCLK */ {-1},};
and i have add new function:
void enable_i2c1_pin_mux(void){ configure_module_pin_mux(i2c1_pin_mux);}
in "board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c"
void i2c1(void){
enable_i2c1_pin_mux(); //set pin mux /* enable clock i2c1 */ __raw_writel(0x2, CM_PER_I2C1_CLKCTRL); while (__raw_readl(CM_PER_I2C1_CLKCTRL) != 0x2); i2c_init(400000, 0x20); //i2c speed 400k, chip address 0x20 printf("sending value = 0xFF\n"); //write value i2c_write(0x20, 0x06, 1, 0xFF, 1); uchar read_val; //read value printf("reading value :"); i2c_read(0x20, 0x06, 1, &read_val, 1); printf("%d\n", read_val); }
how i switch u-boot i2c driver to i2c-1 instance?
Replace this line i2c_init(400000, 0x20); //i2c speed 400k, chip address 0x20
with i2c_init(400000, 2); //i2c speed 400k, chip id 2 /* instance 1 */
my u-boot hang while execute the i2c1() function, the i2c_write() cause the u-boot hang.
void i2c1 (void)
{
enable_i2c1_pin_mux(); /* enable clock i2c1 */ __raw_writel(0x2, CM_PER_I2C1_CLKCTRL); while (__raw_readl(CM_PER_I2C1_CLKCTRL) != 0x2); i2c_init(400000, 2); //i2c speed 400k, chip address 0x20 printf("sending value = 0xFF\n"); //write value i2c_write(0x20, 0x06, 1, 0xFF, 1); //-----------------------------------------------------------------------------this line cause the u-boot hang uchar read_val; //read value printf("reading value :"); i2c_read(0x20, 0x06, 1, &read_val, 1); printf("%d\n", read_val); }
Any wrong with my code, what i have miss to configure?
Looking at the board/ti/am335x/evm.c , only pinmuxing and i2c_init is done did you add both these in board_init() function itself? are you sure the i2c speed for i2c1 is 400000?
Thx,
--Prabhakar Lad
Remove "enable clock i2c1" code from your9 part. Because all the I2C clocks are enabled in u-boot in "pll_init()"
You have to call your API (i2c1) after pll_init() call.
in "/board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c
under function: s_init(void) :
void s_init(void){ /* Can be removed as A8 comes up with L2 enabled */ l2_cache_enable();
/* WDT1 is already running when the bootloader gets control * Disable it to avoid "random" resets */ __raw_writel(0xAAAA, WDT_WSPR); while(__raw_readl(WDT_WWPS) != 0x0); __raw_writel(0x5555, WDT_WSPR); while(__raw_readl(WDT_WWPS) != 0x0);
#ifdef CONFIG_SPL_BUILD /* Setup the PLLs and the clocks for the peripherals */ pll_init(); i2c1(); ---------------------------------------------------------------- my API i2c1();
The u-boot no hang anymore, but seen like the u-boot didn't execute i2c1(), because it didn't printf the message inside the i2c1(void) function.
do i need to call the function s_init() inside board_init() function ?
Thanks & Regard
Can you add next to config_am335x_ddr();? I think console is not initialized at your step.
#ifdef CONFIG_SPL_BUILD /* Setup the PLLs and the clocks for the peripherals */ pll_init(); /* UART softreset */ u32 regVal; u32 uart_base = DEFAULT_UART_BASE;
enable_uart0_pin_mux(); /* IA Motor Control Board has default console on UART3*/ /* XXX: This is before we've probed / set board_id */ if (board_id == IA_BOARD) { uart_base = UART3_BASE; }
regVal = __raw_readl(uart_base + UART_SYSCFG_OFFSET); regVal |= UART_RESET; __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET) ); while ((__raw_readl(uart_base + UART_SYSSTS_OFFSET) & UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);
/* Disable smart idle */ regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET)); regVal |= UART_SMART_IDLE_EN; __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));
/* Initialize the Timer */ init_timer();
preloader_console_init();
config_am335x_ddr(); i2c1(); ----------------------------------------------------------------------------my i2c1 API#endif}
the result still the same, the u-boot didn't execute the i2c1().
HI All;
if your paritcular i2c need to be worked means,
which bus you are using, need to initialize in i2c_init function last line okay!
bus_initialized[current_bus] = X; // X is the bus number
It' will work!!!!!!!!!!
santosh vastrad