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.

AM335x I2C Linux driver and receive length flag

Other Parts Discussed in Thread: AM3352

Hello,

I have been looking into the Linux kernel (3.14.49) driver for I2C controller (i2c-omap.c) and I do not find support for I2C_M_RECV_LEN flag.

From what I can see in the implementation, the FIFOs are configured according to the length given from i2c message structure. So, in fact, the application "must" know what length it "expects".

The flag I2C_M_RECV_LEN tells the driver that the length of the response will be sent in the first byte of the response. It is used in SMbus read block command.

I have a chip connected to the I2C controller and the chip uses a protocol, that requires the flag. So my question is, can I use it on AM335x?

Are there any limitations that do not allow using this mode? If yes, how can I use AM335x and the chip that requires this operation mode?

If this is an incorrect forum, please tell me where can I look for answers.

Best regards,

Rafal Fabich

  • Hi,

    What is this chip and what is the protocol it uses?
  • Biser Gatchev-XID said:
    Hi,

    What is this chip and what is the protocol it uses?

    Hi,

    It is one of the security chips and it uses a proprietary protocol based on SMBus. From the specs I know that the master device and the slave device SHALL implement the following SMBus packets:

    - Quick command
    - Send byte
    - Block write
    - Block read

    And the problem is with the 'Block read' which requires the I2C_M_RECV_LEN flag to be supported.

    I tried calling the SMBus wrappers (that use I2C_SMBUS) and direct (I2C_RDWR) ioctls on the i2c device. In each case, I get the same result because I end in the same low-level implementation (omap_i2c_xfer_msg).

    EDIT: The CPU is Sitara AM3352.

    Regards,

    Rafal

  • I am not sure to what extent is SMBUS supported. I have asked the software team to look at this. They will comment here.
  • Hi Rafal,

    You're correct, the I2C_M_RECV_LEN flag doesn't seem to be supported in i2c-omap.c, I checkec both 3.14.49 and the latest released 4.4.19 kernels...
    The higher level driver i2c-core.c supports this flag, but device specific i2c driver does not use it.

    Best Regards,
    Yordan
  • Hi Yordan,

    Thanks for the reply. If the device specific driver does not support the length flag, is it possible to use the 'Block read' SMBus packet at all?
    From what I can see in the i2c-omap.c file, the I2C transmission is driven by interrupts, and as the RX FIFO is set up before the transmission is started, it cannot be reconfigured untill the transmission ends. So, it seems that it is impossible to change the length of the received data while the transmission is running.
    Is there any possible workaround?
    I have been thinking of using a custom GPIO based driver, but I would like to avoid it if possible.

    Best regards,
    Rafal
  • Hi Rafal,

    Is there any possible workaround?
    I have been thinking of using a custom GPIO based driver, but I would like to avoid it if possible.


    You can use the polling method to manage the fifo, see Section 21.3.14 FIFO Management in the device TRM. However this would require significant modification of the I2C driver.
    So the custom gpio based driver may be the most suitable solution in your case.

    Best Regards,
    Yordan
  • Hi Yordan,

    I have taken a look into the kernel sources and I think I might use the i2c-gpio.c driver and i2c-algo-bit.c. Please tell me if that is applicable in my case?
    Curently the HW design is such, that I have got my chip connected to I2C2 pins (uart1_ctsn.i2c2_sda and uart1_rtsn.i2c2_scl) with 1k5 Ohm pullups .

    For I2C I have got the pins configured in DTS file as below:

    i2c2_pins: pinmux_i2c2 {
    pinctrl-single,pins = <
    0x178 (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
    0x17c (PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_scl */
    >;
    };

    What should be the correct configuration of these pins for GPIO bit-banging I2C? Can you please provide any suggestion, or ideally an example for these pins configuration?

    By the way, I made a typo in my kernel version, it should be 3.14.39, not 3.14.49, but it does not matter in this context, I guess.

    Best regards,
    Rafal