Linux kernel V4L2 driver code for GMSL2 MAX9296 deserializer on Jetson — driver registration in terminal
gmsl2linux driverv4l2max9296kernel driverdevice treejetson

GMSL2 camera driver on Linux: V4L2, MAX9296 kernel driver, device tree

Aaron Angulo ·

The GMSL2 camera driver stack on Linux involves multiple kernel drivers working in coordination — the MAX9296 deserializer driver, the serializer driver, and the sensor driver — with the V4L2 subdev framework tying them together. Understanding where each piece lives and how they communicate is the prerequisite for debugging when any part of it fails. This post covers the full driver architecture.

Key Insights

  • A GMSL2 camera driver on Linux is a chain of V4L2 subdevs: sensor → serializer → deserializer → NVCSI → VI
  • NVIDIA provides reference drivers for specific module/sensor combinations — everything else needs custom work
  • Probe success on the deserializer does not mean the V4L2 video node exists — that depends on the VI driver linking correctly
  • media-ctl -p is the fastest way to see the full pipeline state and identify broken links
  • The DTS must describe every node in the chain with correct compatible strings, I2C addresses, and port linkages

The V4L2 subdev chain for GMSL2

A GMSL2 camera on Jetson is not a single driver — it is a chain of V4L2 subdevices that must all probe successfully and link together before any capture is possible.

The chain, from camera to memory:

IMX390 (sensor subdev)
  → MAX9295A (serializer subdev)
    → MAX9296A (deserializer subdev)
      → NVCSI (CSI receiver subdev)
        → VI (Video Input capture node → /dev/videoN)

Each component is a separate Linux kernel driver. Each must probe successfully. Each must be linked to the next in the V4L2 media graph. If any link is broken — wrong DTS, wrong compatible string, missing regulator — the entire chain fails and no video node appears.

# View the media controller pipeline
sudo media-ctl -p

# Output shows all entities and their link state:
# - pad links between sensor, serializer, deserializer, NVCSI, VI
# - enabled (=>) vs disabled (->) links
# All links from sensor to VI must be enabled for capture to work

The kernel drivers involved

Each component in the chain has a corresponding kernel driver:

ComponentDriver locationCompatible string
IMX390 sensordrivers/media/i2c/imx390.c"sony,imx390"
MAX9295A serializerdrivers/media/i2c/max9295.c"maxim,max9295"
MAX9296A deserializerdrivers/media/i2c/max9296.c"maxim,max9296"
NVCSIdrivers/media/platform/tegra/camera/vi/channel.cTegra-internal
VIdrivers/media/platform/tegra/camera/vi/Tegra-internal

NVIDIA ships these drivers in the L4T kernel source for reference sensor combinations. For a custom sensor (not IMX390), you need to either port an existing driver or write a new one using the tegra-camera-platform sensor driver framework.

The NVCSI and VI drivers are Tegra-internal and are not modified for custom cameras — they are configured through the device tree and through V4L2 controls.

Device tree structure

The DTS for a GMSL2 setup declares every node in the chain. The NVCSI port binding connects the deserializer output to the Jetson capture hardware.

/* Binding the deserializer output to NVCSI port 0 */
nvcsi@15a00000 {
    num-lanes = <4>;
    ports {
        port@0 {
            reg = <0>;
            nvcsi_in0: endpoint@0 {
                remote-endpoint = <&max9296_csi_out0>;
                data-lanes = <0 1 2 3>;
            };
        };
    };
};

The remote-endpoint reference ties the deserializer output port to the NVCSI input port. Both sides must declare the same endpoint with reciprocal remote-endpoint references — if one side references a node that does not exist or has a typo in the label, the media controller cannot build the graph and the VI node does not appear.

Diagnosing probe failures

Work through this sequence when the driver fails to probe:

# 1. Check which drivers probed
sudo dmesg | grep -E "max929[56]|imx390|nvcsi|tegra-vi"

# 2. Check for deferred probe (dependency not ready)
sudo dmesg | grep "probe deferred"
# Common causes: GPIO not ready, regulator not ready, clock not ready

# 3. Check I2C bus accessibility
sudo i2cdetect -y 3  # Replace 3 with your camera I2C bus
# Should show 0x48 (MAX9296A), 0x40 (MAX9295A), sensor address

# 4. Check media graph
sudo media-ctl -p 2>/dev/null | head -60
# Verify all entities are present and links are correct

# 5. Check V4L2 devices
v4l2-ctl --list-devices
# Should show sensor entries if VI linked correctly

A common failure pattern: max9296 probe success in dmesg, but /dev/video0 does not exist. This means the MAX9296A driver probed but the VI driver could not link to the NVCSI. The fix is almost always a DTS error in the NVCSI port binding or the tegra-camera-platform drivernode entry.

Common DTS errors that break probe

These are the DTS mistakes we see most often:

Wrong compatible string. The compatible string must exactly match the driver’s of_device_id table. "maxim,max9296" (not "max9296", not "maxim,max9296a").

Wrong I2C bus. The DTS node parent must be the correct I2C controller node. On Orin, camera I2C is typically on i2c@3180000 or i2c@31c0000 — check the Orin TRM for which controller maps to your carrier board’s camera I2C pins.

Wrong drivernode devname. The tegra-camera-platform devname field must exactly match the I2C device name format: "imx390 3-001a" where 3 is the I2C bus number and 001a is the address in 4-digit hex.

Missing nvidia,gmsl-dser-device phandle. The serializer DTS node must reference the deserializer via this property so the driver knows which deserializer manages the I2C tunnel for this link.

For the full GMSL2 bring-up sequence, see GMSL2 camera bring-up on Jetson Orin: MAX9295/MAX9296 setup. For writing a custom driver on top of this infrastructure, see Writing a custom GMSL2 camera driver for Jetson. If you also need a custom V4L2 driver for the sensor itself, how to write a custom V4L2 camera driver for Jetson Orin covers the full kernel driver implementation.

NVIDIA’s Sensor Driver Programming Guide covering the V4L2 subdev framework for Jetson is in the Jetson Linux Developer Guide. The Linux media controller API documentation is at kernel.org.


NVIDIA Jetson Expert Support

Stuck on a Jetson bring-up?

We've debugged this failure mode before. BSP, device tree, camera pipelines, OTA — most blockers clear in the first session. No long retainers. No guessing.

Frequently Asked Questions

Does NVIDIA provide a GMSL2 kernel driver for Jetson?

NVIDIA provides reference GMSL2 drivers in L4T for specific camera modules tested with their devkits — primarily IMX390 and a few others with TIER IV and Leopard Imaging carrier boards. These drivers are in the L4T kernel source under drivers/media/i2c/. For custom cameras or non-reference carrier boards, these drivers require modification or a new driver is needed.

What V4L2 subdev nodes does a GMSL2 camera create on Jetson?

A working GMSL2 setup creates: /dev/videoN for the capture node, /dev/v4l-subdevN for the sensor subdev, /dev/v4l-subdevN+1 for the serializer subdev, and /dev/v4l-subdevN+2 for the deserializer subdev. The media controller graph connects these. Use media-ctl to view the pipeline and verify all subdevs are linked correctly.

How do I verify the MAX9296A deserializer kernel driver probed correctly?

Run sudo dmesg | grep -i max9296 after boot. A successful probe shows 'max9296 X-0048: probe success' or similar. If you see 'probe deferred' the driver is waiting for a dependency (often a GPIO or regulator). If you see 'probe failed', check the DTS compatible string, I2C bus address, and whether the chip is powered.

What is the media controller pipeline for a GMSL2 camera on Jetson?

The pipeline is: sensor subdev → serializer subdev → deserializer subdev → NVCSI subdev → VI capture node. Each link in this chain must be configured and enabled via the media controller API or automatically by the tegra-camera-platform framework. Use media-ctl -p to print the current pipeline state.

My GMSL2 driver probes successfully but v4l2-ctl --list-devices shows nothing. Why?

Driver probe success means the chip initialized over I2C — it does not mean the V4L2 device node was created. The V4L2 video node is created by the VI (Video Input) driver when it successfully links to the NVCSI. If the NVCSI-to-VI link fails (wrong port, wrong DTS), the VI driver does not create the /dev/videoN node. Check dmesg for VI probe errors.

Aarón Angulo, Co-Founder & CEO at ProventusNova

Written by

Aarón Angulo

Co-Founder & CEO · ProventusNova

Obsessed with client outcomes. Aarón ensures every engagement delivers real results — on time, on scope, no exceptions.

Connect on LinkedIn