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.

AM62L: AM62L I2C OMAP: two target-capable controllers on same bus time out when either initiates

Part Number: AM62L

I am working on BeagleBadge, based on TI AM62L, using the K3 vendor kernel 6.12.57-vendor-edge-k3. I am extending drivers/i2c/busses/i2c-omap.c so an AM62L I2C adapter can register a Linux I2C slave backend and still temporarily act as an I2C master/initiator.

The immediate test setup uses two AM62L OMAP I2C instances on the same board:

  • J6 is /dev/i2c-1, controller instance 20010000.i2c
  • J7 is /dev/i2c-3, controller instance 20020000.i2c
  • J6 and J7 are physically shorted together
  • Linux i2c-slave-testunit is used as the target/slave backend
  • No external I2C devices are connected for this test

Validated working cases:

  • J6 target at 0x30, J7 initiator: true SMBus block-proc-call works
  • J7 target at 0x30, J6 initiator: true SMBus block-proc-call works
  • repeated-start version reads work in the single-target reverse-topology case

The remaining failing case is when both adapters are target-capable at the same time:

  • J6 target at 0x30
  • J7 target at 0x31

After both targets are registered and bound, either initiation direction times out:

i2ctransfer -f -y 3 w1@0x30 0x00
i2ctransfer -f -y 3 r1@0x30
i2ctransfer -f -y 1 w1@0x31 0x00
i2ctransfer -f -y 1 r1@0x31
 

All four commands time out, even though each single-target topology works.

Driver changes already tested:

  • added OMAP reg_slave / unreg_slave plumbing
  • clear stale master state before returning to slave listen mode
  • switch from the slave IRQ mask to the normal master IRQ mask when an adapter with a registered slave backend initiates a master transfer
  • on AM62L/IP-v2, clear I2C_IRQENABLE_CLR before writing the next role's desired interrupt mask, because I2C_IRQENABLE_SET only sets bits

The last change did remove the previous stale IRQ mask problem:

  • before: failing dual-listener logs showed accumulated ie=0x661f
  • now: logs show cleaned masks such as ie=0x61f and ie=0x601f
  • Transmit underflow is no longer observed

But the dual-listener case still times out in both directions.

The relevant current kernel state is:

  • components/ti-linux-kernel: eb09330dc065 Clear OMAP IRQ enables before role mask writes
  • components/armbian-build: b17e72e32 Add OMAP IRQENABLE clear patch
  • tested artifact: 6.12.57-S22fb-D0000-Pb163-C2876Hb496-HK01ba-Vc222-Be8e3-R448a
  • booted kernel: Linux beaglebadge 6.12.57-vendor-edge-k3 #27 SMP PREEMPT Tue May 5 16:45:44 UTC 2026 aarch64 GNU/Linux

Question:

For AM62L OMAP I2C IP-v2, is there an additional required sequence when two controllers on the same physical I2C bus are both left in target/slave listen mode, but either one may temporarily become master?

Specifically:

  1. When switching a target-capable adapter from slave-listen mode into master mode, besides clearing I2C_IRQENABLE_CLR, clearing status, setting MST, and restoring slave-listen mode afterward, is there another register or FIFO state that must be reset?
  2. Is it expected that an OMAP I2C controller with own address enabled can interfere with another controller's transaction to a different target address on the same bus?
  3. Should OA / target addressing be disabled while an adapter is initiating a master transfer, then restored afterward?
  4. Are there AM62L-specific constraints for using two OMAP I2C instances as multi-controller participants on the same physical bus?

The attached/pasted reproduction log includes:

  • exact commands
  • uname -a
  • target backend status
  • exit status for each i2ctransfer
  • dmesg lines containing omap_i2c, Transmit underflow, Arbitration lost, timeout, slave irq, isr-master, and master-enter

The goal is not to debug the Linux slave-testunit backend itself. The single target cases prove that target mode and true SMBus block-proc-call work in both directions. The problem only appears when both OMAP adapters are simultaneously registered as target-capable listeners on the shorted J6/J7 bus.

run.log 

dmesg.log 

Kernel patches are at https://github.com/just-kitting/ti-linux-kernel/tree/badge-snake

  • Hi Jason,

    I'll redirect your question to the I2C hardware expert.

    Hi Stan, 

    For AM62L OMAP I2C IP-v2, is there an additional required sequence when two controllers on the same physical I2C bus are both left in target/slave listen mode, but either one may temporarily become master?

    Can you have a look at the query?

    Regards,
    Vinu

  • Hello Jason,

    If two or more controller transmitters start a transmission on the same bus almost simultaneously, an arbitration procedure is invoked. The arbitration procedure uses the data presented on the serial bus by the competing transmitters. When a transmitter senses that a high signal it has presented on the bus has been overruled by a low signal, it switches to the target receiver mode, sets the arbitration lost (I2C_IRQSTATUS_RAW[0] AL) flag, and generates the arbitration lost interrupt.

    The figure above shows I2C Arbitration between controller transmitters. It shows the arbitration procedure between two devices. The arbitration procedure gives priority to the device that transmits the serial data stream with the lowest binary value. If two or more devices send identical first bytes, arbitration continues on the subsequent bytes.

    Please refer to section I2C Programmable Multitarget Channel Feature in the AM62L TRM document. 

    Please review in the AM62L TRM document point 12.2.3.4.1.1.3 Programming Flow-Diagrams.

    Best Regards,

    Borislav Lazarkov

  • I've not yet progressed to testing arbitration. I'm still in the phase of testing that I can send from one I2C to another on the same device, then initiate a transfer in the opposite direction. This is fully synchronous in that the transfer in the alternative initiator is not started until the first one transfer has fully completed.

    The query is about a case that does not seem to be covered by the TRM where two AM62L I2C are setup as Target at the same time, but only one is being asked to be a Controller for a transfer at a time. In this case, the arbitration loss is unexpected or perhaps I am misinterpreting the expected response to it. The Controller/Initiator should not back off because there is only 1 Controller/Initiator at the time.

    Perhaps a better way to ask the question is "Do I need to do something to exit Target mode to enter Controller/Initiator mode?" and "What is it that needs to be done in that case?".

  • Hello Jason,

    Please give me some time to contact the I2C expert.

    Thank you for your patience!

    Best Regards,

    Borislav Lazarkov

  • Any update? Any conservative recommendation?

  • It is has been 2 weeks. Is there still a chance you will look at what it takes to transition between modes?

  • Hello Jason,

    Apologies for the delayed responses here, been catching up from leave and missed your e2e thread.

    We don't have support in the Linux driver to transition between master and slave modes - the I2C driver is master only.

    Double-checking w/ claude:

      The i2c-omap driver (drivers/i2c/busses/i2c-omap.c) supports master mode only.
    
      Evidence from the driver:
    
      1. i2c_algorithm struct (line 1203): registers only .master_xfer and .master_xfer_atomic — there is no .reg_slave or .unreg_slave
      callback, which are required for slave mode support in the Linux I2C framework.
      2. functionality return value (line 851): returns I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING — notably absent is
       I2C_FUNC_SLAVE.
      3. Slave-related register bits exist (OMAP_I2C_STAT_AAS, OMAP_I2C_CON_MST, etc.) confirming the hardware IP has slave capability, but
       the driver does not implement it. There is one reference to a slave in a comment (line 593) describing bus contention detection, not
       slave operation.
    

    You can find my understanding of the "why" for no Linux I2C slave support in these threads:
    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1024619/am6412-i2c-multi-master-mode/3793533#3793533

    https://e2e.ti.com/support/processors/f/791/t/887456

    Regards,

    Nick