VOXL2 SPI3: sharing bus 3 between the onboard ICM-42688 and a second SPI device — SPI_NO_CS rejected, requesting cs-gpios guidance
-
Setup
- Board: VOXL2 (M0054)
- System image:
1.7.8-M0054-14.1a-perf, kernel4.19.125 libqrb5165-io0.5.0- Bus 3 controller:
qcom,spi-geni, bound to thespi_geniplatform driver, exposing a single chip select (spi3.0→/dev/spidev3.0)
We are adding an ams TMF8829 time-of-flight ranging sensor to an existing VOXL2 design. For layout reasons it is wired to SPI3, the same bus as the onboard ICM-42688 IMU that
voxl-imu-serverservices. The IMU runs atSPI_MODE_3on the controller's native chip select; the TMF8829 runs atSPI_MODE_0and is selected through a TLMM GPIO (117), with its enable line on GPIO 118.The problem
SPI3 exposes exactly one native chip select, and it is wired to the IMU. The GENI controller asserts that native CS on every transfer it performs, so any transfer we issue for the TMF8829 also selects the IMU. Since the TMF8829 wire protocol begins each transaction with a write opcode (
0x02), the IMU interprets TMF traffic as register writes addressed to itself. That is not merely a corrupted read — it can reconfigure the IMU mid-flight and take down a flight-critical data stream.The standard Linux remedy is the
SPI_NO_CSmode flag, suppressing the controller's chip select so our GPIO alone selects the target. The kernel rejects it on this platform. Issuing the ioctl directly on the descriptor returned byvoxl_spi_get_fd(3):spi_bus3: SPI_IOC_WR_MODE32 0x40 failed: Invalid argument0x40isSPI_MODE_0 | SPI_NO_CS. Both the legacy 8-bitSPI_IOC_WR_MODEand the 32-bitSPI_IOC_WR_MODE32returnEINVAL, which points toSPI_NO_CSnot being advertised in the controller driver'smode_bits. Separately,voxl_spi_init()inlibqrb5165-iovalidates its mode argument strictly againstSPI_MODE_0..3and rejects any extra flag bits, so the flag cannot be requested through the library either — but we bypassed that with direct ioctls on the raw fd and the kernel is the hard stop.Our integration treats this as a safety gate: at startup it writes
SPI_MODE_0 | SPI_NO_CS, reads it back, and if the readback fails it disables the TMF entirely and leaves IMU publication untouched rather than risk corrupting the IMU. That gate is what fires today, so the second sensor never comes up.For completeness, the surrounding work is done and validated on hardware. We have a bus-3 arbiter that serializes access with a mutex, switches mode and clock per transaction, and restores
SPI_MODE_3with native CS on every success and error path. Matched 10-second A/B captures with the TMF path compiled in but gated off show no IMU regression: 1024 Hz in both conditions, 0.977 ms mean sample interval with no interval above 2 ms, and zero FIFO errors, logger drops, or mode-restore failures. The TMF8829 itself is known good and streams reliably at 15–18 MHz when it has a bus to itself. The only missing capability is per-device chip-select control on a shared bus 3.Path 1 (preferred): declare bus 3 with
cs-gpiosand a second spidev child nodeRather than work around chip select in userspace, we would rather let the kernel own it, which is how Linux is designed to share an SPI bus. Concretely, on the SPI3 node: raise the chip-select count to 2, add
cs-gpioswith the native CS in slot 0 and&tlmm 117in slot 1, and add a secondspidevchild atreg = <1>. The TMF8829 then appears as its own/dev/spidev3.1with its ownspi-max-frequencyand mode.With that in place the kernel handles chip-select assertion, clock, and mode switching per device. On our side we delete the manual GPIO chip-select toggling and the entire mode-restore arbiter, and the IMU is never exposed to TMF traffic at all — a substantially safer arrangement than anything we can build in userspace.
Questions on this path:
- Does the
spi_genidriver in the 1.7.8 kernel cooperate with the SPI core's genericcs-gpioshandling, or does its ownset_csimplementation bypass GPIO chip selects? - Is there a supported way for us to apply a devicetree overlay or a patched DTB to a VOXL2 system image, or does this have to come from ModalAI as an image change?
- Are there known constraints on SPI3 specifically — reserved chip selects, pinmux conflicts on TLMM 117, or other consumers of that controller we should know about?
Path 2 (fallback): add
SPI_NO_CSto the controller driver's supported mode bitsIf the devicetree route isn't viable, the smaller change is to advertise
SPI_NO_CSin the GENI SPI controller'smode_bitsand honor it in the driver's chip-select path. Our existing arbiter code already works unmodified against that interface, so this would unblock us with no changes on our side, and it would also needvoxl_spi_init()inlibqrb5165-ioto stop rejecting mode values with flag bits set (or we continue issuing raw ioctls on the fd fromvoxl_spi_get_fd()).We consider this less idiomatic than Path 1 — chip select stays a userspace responsibility, with per-transaction GPIO toggling and mode restoration that has to be correct on every error path — and it still requires a custom kernel build. But it is a much narrower diff if that matters for your release process.
Question: is
SPI_NO_CSomitted frommode_bitsdeliberately, for a hardware reason on the GENI controller, or simply because nothing has needed it yet?What we're asking
Guidance on which of these two you'd support, and whether either can be delivered through an official system image rather than a fork we have to maintain. If neither is practical in the near term, our fallback is a hardware change moving the TMF8829 to its own SPI bus, and we'd appreciate confirmation that a shared bus 3 is simply not supported on this platform so we can commit to that redesign.
Happy to share the arbiter source, the A/B log captures, or a minimal reproducer that only issues the failing ioctl if that's useful.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login