This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

I2C2 (bus3) on ti811x is not working

Other Parts Discussed in Thread: DM385

Hi,

We have an custom board based on J5 ti811x.

ezsdk uboot version    :u-boot-2010.06-psp04.07.00.02
ezsdk kernel version    :linux-2.6.37-psp04.07.00.02

As per our design i2c2 (omap_i2c.3) need to configure with a speed of 400KHz and connect to amplifier chip. But the SCL line shows 8KHz. When I debugged, I found out that fclk_rate in i2c_omap.c assigned with 0 due to below line in clock814x_data.c:
CLK(NULL,        "i2c3_fck",            &i2c3_fck,            CK_TI814X | CK_DM385 | CK_TI811X),

When I changed as shown below i am able to get 392KHz when registered bus with 400.

CLK("omap_i2c.3",    "fck",                &i2c3_fck,            CK_TI814X | CK_DM385 | CK_TI811X),

My question is

1) But Only address is transmitted through i2c driver and I got ack. But data is not transmitting on i2c line.

2) Is there any specific reason why the clock is not enabled for omap_i2c.3.

2) After the modification I am not able to do devmem2 0x4819C0B0. it shows below error.

root@c6a811x-evm:~# devmem2 0x4819C0B0
/dev/mem opened.Unhandled fault: external abort on non-linefetch (0x1018) at 0x4030f0b0

Memory mapped at address 0x4030f000.
Bus error
root@c6a811x-evm:~# devmem2 0x48140BC8

BR/-

Nihad

  • Abdul,

    Refer to the below pointers:

    processors.wiki.ti.com/.../TI81xx_PSP_Porting_Guide
    e2e.ti.com/.../191819
    e2e.ti.com/.../395084

    Let me know if you have more questions here.

    BR
    Pavel
  • Pavel,

    Still I have not received answer to my previous 3 points. Please answer that. I have gone through the references. I understood that i can enable clock from devices.c file. But it will not set
    OMAP_I2C_PSC_REG
    OMAP_I2C_SCLL_REG
    OMAP_I2C_SCLH_REG
    and also i2c2 is used in vpss. I have removed vpss from config file. there no registration of vpss during kernel boot up. Even though i have disabled below modules, I can see below messages during booting sequence.

    Configuring kernel-module-vpss.
    Configuring kernel-module-sii9022a.
    Configuring kernel-module-ti81xxhdmi.
    Configuring kernel-module-tlc59108.
    Configuring kernel-module-ti81xxfb.
    Configuring kernel-module-tvp7002.
    Configuring kernel-module-ti81xxvo.
    Configuring kernel-module-ti81xxvin.

    But still i2c2 send only address and immediately stop bit. but after that it is not sending data. my device address is 0x6C and I was writing 0x09 to 0x0e register of my device. find the dmesg output when i run i2cset command. Also no device listed in i2c2(Bus3)

    root@c6a811x-evm:~# i2cdetect -r 3
    WARNING! This program can confuse your I2C bus, cause data loss and worse!
    I will probe file /dev/i2c-3 using read byte commands.
    I will probe address range 0x03-0x77.
    Continue? [Y/n] y
    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- --
    root@c6a811x-evm:~# i2cset -y 3 0x6c 0x0e 0x09
    Error: Write failed
    root@c6a811x-evm:~# dmesg | tail -40
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0006,0x4040)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0016,0x0001)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x001f)
    i2c i2c-3: ioctl, cmd=0x703, arg=0x77
    i2c i2c-3: ioctl, cmd=0x720, arg=0xbecaac58
    i2c i2c-3: master_xfer[0] R, addr=0x77, len=1
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0001,0x001f)
    omap_i2c omap_i2c.3: addr: 0x0077, len: 1, flags: 0x1, stop: 1
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x000c,0x0077)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0007,0x0001)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0006,0x4040)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x000a,0x8403)
    omap_i2c omap_i2c.3: IRQ (ISR = 0x0006)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x0006)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x000a,0x8002)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x0000)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0006,0x4040)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0016,0x0001)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x001f)
    i2c i2c-3: ioctl, cmd=0x705, arg=0xbea8dc58
    i2c i2c-3: ioctl, cmd=0x703, arg=0x6c
    i2c i2c-3: ioctl, cmd=0x720, arg=0xbea8dc4c
    i2c i2c-3: master_xfer[0] W, addr=0x6c, len=2
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0001,0x001f)
    omap_i2c omap_i2c.3: addr: 0x006c, len: 2, flags: 0x0, stop: 1
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x000c,0x006c)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0007,0x0002)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0006,0x4040)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x000a,0x8603)
    omap_i2c omap_i2c.3: IRQ (ISR = 0x1010)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x1000)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0008,0x000e)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x0010)
    omap_i2c omap_i2c.3: IRQ (ISR = 0x0006)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x0006)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x000a,0x8202)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x0000)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0006,0x4040)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0016,0x0001)
    omap_i2c omap_i2c.3: omap_i2c_write_data_reg (0x0002,0x001f)
    root@c6a811x-evm:~#

    BR/-
    Nihad
  • Nihad,

    Abdul VK said:
    Still I have not received answer to my previous 3 points. Please answer that.

    OK, let we go back there.

    1) But Only address is transmitted through i2c driver and I got ack. But data is not transmitting on i2c line.

    I do not see a question here! If your question is why you are not getting data on i2c data line, there could be many reasons.

    2) Is there any specific reason why the clock is not enabled for omap_i2c.3.

    What makes you think i2c2 (0x4819C000) clock is not enabled? From what I can find, I2c2 both clocks (interface/interconnect and functional) are enabled by default:

    ./osc0_clkin_ck/usb_dpll_clkin_ck/usb_dpll_ck/usb_dpll_clk2_ck/sysclk10_ck/i2c02_ck/i2c3_fck/rate ==> 48000000

    ./osc0_clkin_ck/iss_dpll_ck/iss_dpll_d2_ck/sysclk4_ck/sysclk6_ck/i2c3_ick/rate ==> 100000000

    2) After the modification I am not able to do devmem2 0x4819C0B0. it shows below error.

    This error means that i2c3 clock is now disabled. And this is in result of your modification of clock814x_data.c file.

    BR
    Pavel

     

     

  • Nihad,

    HDVPSS should be by default build as a module (vpss.ko). Make sure you are not loading vpss.ko and hdvpss.xem3 firmware by the init scripts of the rootfs. No need to change config file.

    Then on kernel boot up, make sure you have the below messages:

    omap_i2c omap_i2c.1: bus 1 rev4.0 at 100 kHz

    omap_i2c omap_i2c.3: bus 3 rev4.0 at 100 kHz

    i2c /dev entries driver

    After kernel is loaded, check you have the below devices:

    evm:~#

    /dev/i2c-1  /dev/i2c-3

    Check if you can access/read I2C2 registers (by default, no modifications):

    evm:~# devmem2 0x4819C0B0

    /dev/mem opened.

    Memory mapped at address 0x40251000.

    Read at address  0x4819C0B0 (0x402510b0): 0x000000FF

  • Abdul VK said:
    I understood that i can enable clock from devices.c file

    It is enabled by default from devices.c ti814x_enable_i2c2() function. No need to modify.

    Abdul VK said:
    But it will not set
    OMAP_I2C_PSC_REG
    OMAP_I2C_SCLL_REG
    OMAP_I2C_SCLH_REG

    The clock speed (from 100KHz to 400KHz) can be set like this:

    board-ti811xevm.c

    omap_register_i2c_bus(3, 100 400, ti811x_i2c_boardinfo1, ARRAY_SIZE(ti811x_i2c_boardinfo1));

    The I2C2 pins used by default are L27 and L25. If you use these two pins for I2C2, no need for additional pin mux.

    Abdul VK said:
    my device address is 0x6C

    Add it to the below array:

    static struct i2c_board_info __initdata ti811x_i2c_boardinfo1[] = {
        {
            I2C_BOARD_INFO("sii9022a", 0x39),
            .platform_data = &sii9022a_pdata,
        },
    };

    BR
    Pavel

     

  • Pavel,
    I need to set register as below
    OMAP_I2C_PSC_REG = 0x03
    OMAP_I2C_SCLL_REG = 0x09
    OMAP_I2C_SCLH_REG=0x0A

    What is the virtual address for these registers. Do I need to set these register before clock enable?. How can I set these register from ti814x_enable_i2c2()?

    BR/-
    Nihad
  • Nihad,

    Abdul VK said:
    I need to set register as below
    OMAP_I2C_PSC_REG = 0x03
    OMAP_I2C_SCLL_REG = 0x09
    OMAP_I2C_SCLH_REG=0x0A

    By default, these registers are adjust for 100KHz on the I2C2_SCL pin, during kernel boot we have:

    omap_i2c omap_i2c.3: bus 3 rev4.0 at 100 kHz

    And these registers have the below values:

    I2C2.I2C_PSC/0x4819C0B0 = 0xFF

    I2C2.I2C_SCLL/0x4819C0B4 = 0xD

    I2C2.I2C_SCLH/0x4819C0B8 = 0xF

    When you change omap_register_i2c_bus() from 100 to 400, you will have the below message during boot up:

    omap_i2c omap_i2c.3: bus 3 rev4.0 at 400 kHz

    Thus you should have 400KHz clock on I2C2_SCL pin.

    And these registers have the below values:

    I2C2.I2C_PSC/0x4819C0B0 = 0xFF

    I2C2.I2C_SCLL/0x4819C0B4 = 0x9

    I2C2.I2C_SCLH/0x4819C0B8 = 0x3

    BR
    Pavel

  • Pavel,

    Even I am getting same value as you mentioned, But I need to set below values
    I2C2.I2C_PSC/0x4819C0B0 = 0x03
    I2C2.I2C_SCLH/0x4819C0B8 = 0xA

    BR/-
    Nihad
  • Abdul VK said:
    Even I am getting same value as you mentioned, But I need to set below values
    I2C2.I2C_PSC/0x4819C0B0 = 0x03
    I2C2.I2C_SCLH/0x4819C0B8 = 0xA

    The fastest way is to hardcode these values in the linux kernel:

    linux-kernel/drivers/i2c/busses/i2c-omap.c

    static int omap_i2c_init(struct omap_i2c_dev *dev)
    {

    ....

    /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
        if(dev->base == 0xFA19C000) {
          psc = 0x3;
          sclh = 0xA;
        }

    omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);

    /* SCL low and high time values */
        omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
        omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);

    ...

    }

    BR
    Pavel

  • Other approach can be to modify the code like below:

    linux-kernel/drivers/i2c/busses/i2c-omap.c

    static int omap_i2c_init(struct omap_i2c_dev *dev)

    {

    ....

    if (dev->speed > 400 || cpu_is_omap2430())

    internal_clk = 19200;

    else if (dev->speed > 100)

    internal_clk = 9600;

    else

    internal_clk = 4000;

    if(dev->base != 0xFA19C000) {

    fclk = clk_get(dev->dev, "fck");

    fclk_rate = clk_get_rate(fclk) / 1000;

    clk_put(fclk);

    }

    else {

    fclk = clk_get(NULL, "i2c3_fck");

    fclk_rate = clk_get_rate(fclk) / 1000;

    clk_put(fclk);

    }

    ....

    }

    As result you will have psc=0x4, scll = 0x9, sclh = 0x3

  • Dear pavel,

    Appreciated your dedication and valuable support. I have fixed the i2c2 issue. it is working now. one issue was without knowing default pin muxing in i2c.c file, I have added board specific pin muxing for i2c2 in devices.c file. So its started working when I merged board specific pin muxing to pin muxing in i2c.c file.

    BR/-
    Nihad
  • Nihad,

    Good to see you have fix it. Just to note I2C2 pinmux is done in devices.c file, ti81xx_video_mux() function :

    else if (cpu_is_ti811x()){
    /*Temporary hack, till we have interface
    to configure pin mux for J5-Eco*/

    /*I2c2 - Pin Muxing*/
    omap_writel(0x60040, 0x48140A18);
    omap_writel(0x60040, 0x48140A1c);