[PATCH v3 0/7] i2c: qcom-cci: Runtime capability detection and improved read/write

From: Loic Poulain

Date: Fri Oct 16 2026 - 04:04:01 EST


Improves the Qualcomm CCI I2C driver read/write in different ways:

- Capabilities (queue sizes, max transfer lengths, supported I2C mode)
are currently hardcoded per DT compatible string in a handful of
cci_data instances. Replace the static per-compatible structs with a
single version-sorted capability catalog resolved at runtime from
CCI_HW_VERSION.

- The driver only supported single-command writes, capped at 11 bytes
regardless of how much space the command queue actually has. Factor
out the write-command queueing into a reusable helper and then add
burst-write support, chunking longer writes across the whole queue
instead of a single command's payload.

- The FIFO read path hardcoded a fixed 12-byte limit unrelated to the
actual per-revision FIFO size, with a special-cased drain loop.
Simplify the FIFO read/drain loop and derive the read-side limits
from each revision's FIFO size.

- Add burst-read support using threshold interrupts, allowing reads of
arbitrary size by draining the FIFO incrementally during the transfer.

Also add overflow and underflow IRQ reporting, as queue/fifo limits are
now derived from the hardware capabilities and exercised more
aggressively.

Unbounded writes, which refill the command queue while the transfer is
still in flight and so lift the queue-depth limit on the write side,
build on this series and will be posted separately.

Reads up to 4 KiB and writes up to the full command queue depth (451
bytes on this part) were exercised on an imx219 behind CCI v1.8
(128-word queue, 400 kHz).

Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>
---
Changes in v3:
- Reject a write longer than the advertised limit with an error rather
than ignoring it. (Bryan)
- Build the command words with FIELD_PREP() instead of open-coded
shifts, which also documents the per-opcode field widths (Konrad)
- Actually program CCI_IRQ_MASK_1, the RD_PAUSE bits were being ORed
into the value written to CCI_IRQ_MASK_0 and so never took effect
- Clear the per-transfer status on entry and stop reinitialising the
completion in the read drain loop, as RD_DONE can fire while the
fifo is being drained
- Link to v2: https://lore.kernel.org/r/20261013-cci-imp-v2-0-6873326b44a3@xxxxxxxxxxxxxxxx

Changes in v2:
- Split the HALT_ACK reset fix out into its own patch (Andi)
- Fix a typo in the "Detect capabilities from CCI_HW_VERSION" commit
message (Andi)
- Use GENMASK()/FIELD_GET() to decode the CCI_HW_VERSION fields (Konrad)
- Derive the number of masters from the DT i2c-bus subnodes instead of
encoding it per compatible string (Konrad)
- Add burst read support via RD_THRESHOLD/RD_PAUSE IRQs
- Link to v1: https://lore.kernel.org/r/20261004-cci-imp-v1-0-227d12cb4829@xxxxxxxxxxxxxxxx

---
Loic Poulain (7):
i2c: qcom-cci: Factor out write command queue programming
i2c: qcom-cci: Handle and report queue overflow/underflow interrupts
i2c: qcom-cci: Detect capabilities from CCI_HW_VERSION at runtime
i2c: qcom-cci: Add burst write support
i2c: qcom-cci: Extend i2c read limits based on CCI revision
i2c: qcom-cci: Add burst read support
i2c: qcom-cci: Build command words with FIELD_PREP()

drivers/i2c/busses/i2c-qcom-cci.c | 464 +++++++++++++++++++++++++++++---------
1 file changed, 355 insertions(+), 109 deletions(-)
---
base-commit: d6dc536a4c8bb99dd822bc349a9e801be7ea81c9
change-id: 20260929-cci-imp-8ba384309942

Best regards,
--
Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>