iMX6 solo I2C4 always reports "I2C bus is busy"

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX6 solo I2C4 always reports "I2C bus is busy"

Jump to solution
2,824 Views
scottwarner
Contributor III

We are trying to use the 4th I2C bus on our custom board using the iMX6 Solo (based on the sabresd reference board).  The other three I2C buses work fine, but after enabling the 4th bus, the I2C driver reports "I2C bus is busy".  I have I2C debug enabled, the following is an attempt to read a register from a device on this bus:

~ # i2cget -y 3 0x0b 0x51

Error: Read failed

~ # dmesg

i2c i2c-3: <i2c_imx_xfer>

i2c i2c-3: <i2c_imx_start>

i2c i2c-3: <i2c_imx_bus_busy>

i2c i2c-3: <i2c_imx_bus_busy> I2C bus is busy

i2c i2c-3: <i2c_imx_stop>

i2c i2c-3: <i2c_imx_bus_busy>

i2c i2c-3: <i2c_imx_xfer> exit with: error: -110

We placed a scope on this bus, the start condition looks fine, but there is no clock following that, both the clock and data lines stay low until the transaction is aborted.  I'm not sure if the clock is missing due to the bus busy error, or if the bus busy error was due to the missing clock.

We are running the 3.10.17-r0 release, I applied the patch to clk-imx6q.c to map in the correct clock for I2C4:

    if (cpu_is_imx6dl())

        /*

         * The multiplexer and divider of imx6q clock gpu3d_shader get

         * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.

         */

        clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);

    else

        clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);

I used the following device tree entries to enable the bus:

i2c4: i2c@021f8000 {

  #address-cells = <1>;

  #size-cells = <0>;

  compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";

  reg = <0x021f8000 0x4000>;

  interrupts = <0 35 0x04>;

  clocks = <&clks 116>;

  status = "disabled";

};

i2c4 {

  pinctrl_i2c4_1: i2c4grp-1 {

  fsl,pins = <

  MX6QDL_PAD_GPIO_7__I2C4_SCL (PAD_CTL_HYS | PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | PAD_CTL_SRE_SLOW)

  MX6QDL_PAD_GPIO_8__I2C4_SDA (PAD_CTL_HYS | PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | PAD_CTL_SRE_SLOW)

  >;

  };

};

&i2c4 {

  clock-frequency = <100000>;

  pinctrl-names = "default";

  pinctrl-0 = <&pinctrl_i2c4_1>;

  status = "okay";

};

Other notes:

- Previously this device was on I2C3 and worked fine.

- Board has external 4.7K pullups.

Any advice on what else to check?

Thanks,

Scott

Labels (3)
1 Solution
1,347 Views
igorpadykov
NXP Employee
NXP Employee

Hi Scott

ODE also should be set for i2c, like:

MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1

Linux/arch/arm/boot/dts/imx6sl-evk.dts - Linux Cross Reference - Free Electrons

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
2 Replies
1,348 Views
igorpadykov
NXP Employee
NXP Employee

Hi Scott

ODE also should be set for i2c, like:

MX6SL_PAD_I2C2_SCL__I2C2_SCL 0x4001b8b1

Linux/arch/arm/boot/dts/imx6sl-evk.dts - Linux Cross Reference - Free Electrons

Best regards

igor

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,347 Views
scottwarner
Contributor III

Thanks for the quick reply Igor, using 0x4001b8b1 made it work.  Comparing those bit fields to what we were using (and you are right we should have had ODE set), it was actually the internal 100k pullup enable that got things working.  The board has external 4.7K pullups on SDA and SCL, so we are not sure why the internal pullup made it work.  We'll continue to scope that bus at different points in the circuit, there is an isolation buffer on that bus, maybe that is giving us a problem.

Thanks again for the quick reply,

Scott