The Sanctuary

Writing about interests; Computer Science, Philosophy, Mathematics and AI.

Intel IPU6 Camera on Linux: Automated Setup for Meteor Lake Laptops

linuxdriversubuntuhardwareopen-sourceipu6intelmeteor-lake

The Problem

Intel Meteor Lake laptops (14th Gen Core Ultra) ship with an IPU6-based camera that does not work out of the box on Linux. The camera sensor (typically OmniVision OV08F40) is physically present but invisible to the OS.

The root cause is a dependency chain with two broken links:

  1. Missing USBIO driver: The Lattice USB-IO bridge (2ac1:20c9) provides GPIO/I2C access to the sensor’s power controller. Without the usbio kernel module, the INT3472 discrete power controller cannot find its GPIO chip (INTC1007:00), and the sensor never powers on.

  2. Missing IPU6 PSYS module: The Processing System kernel module is not in mainline. The Intel Camera HAL requires it to process frames.

Even with both modules loaded, there is no direct V4L2 streaming path — the Camera HAL operates in userspace and requires a GStreamer pipeline to feed frames into a v4l2loopback virtual device.

The Stack

Browser / Application
  ↑
/dev/video99 (v4l2loopback)
  ↑
GStreamer: icamerasrc → videoconvert → v4l2sink
  ↑
Intel Camera HAL (libcamhal)
  ↑
IPU6 PSYS (out-of-tree) + ISYS (mainline ≥6.10)
  ↑
Camera sensor driver (ov08x40, mainline)
  ↑
INT3472 power controller ← GPIO from INTC1007
  ↑
USBIO drivers (out-of-tree) → Lattice USB bridge

Five components need to be built and installed in order:

#ComponentSource
1Intel USBIO drivers (usbio, gpio-usbio, i2c-usbio)intel/usbio-drivers
2IPU6 PSYS kernel moduleintel/ipu6-drivers
3Camera HAL binaries (firmware + ISP libs)intel/ipu6-camera-bins
4Camera HAL (libcamhal)intel/ipu6-camera-hal
5icamerasrc GStreamer pluginintel/icamerasrc

Both kernel modules are installed via DKMS, so they rebuild automatically on kernel updates.

The GStreamer Pipeline

The systemd service runs this pipeline on boot:

gst-launch-1.0 -e icamerasrc buffer-count=7 \
    ! video/x-raw,format=NV12,width=1280,height=720 \
    ! videoconvert \
    ! video/x-raw,format=YUY2,width=1280,height=720,framerate=30/1 \
    ! identity drop-allocation=true \
    ! v4l2sink device=/dev/video99 sync=false

CPU usage: ~3–5% at 720p, ~5–8% at 1080p (Core Ultra 7 165U). Only 1280×720 and 1920×1080 are supported by the Camera HAL graph configuration.

Firefox PipeWire Support

Firefox Snap cannot access V4L2 devices directly from its sandbox. It requires a PipeWire camera path:

  1. A PipeWire V4L2 SPA node created via pw-cli create-node spa-node-factory pointing at /dev/video99, with port.physical=true and port.terminal=true — these properties are required for the XDG desktop portal to expose the device.
  2. Portal camera permissions granted in org.freedesktop.impl.portal.PermissionStore.
  3. Firefox pref media.webrtc.camera.allow-pipewire set to true (Firefox does not use PipeWire for cameras by default).
  4. Portal restart after the V4L2 node is created.

The ipu6-pipewire-fixup script handles all of this automatically as a systemd ExecStartPost.

Note: pipewiresink mode=provide does not work here — it creates a stream node, not a device node. Only spa-node-factory with api.v4l2.source creates a node the camera portal will expose.

System Tray Utility

The setup includes ipu6-camera-tray, a Python 3 applet using AyatanaAppIndicator3 for native GNOME/Wayland tray support.

  • Left-click: Toggle camera on/off via pkexec systemctl start/stop
  • Settings dialog: Switch between 720p/1080p, toggle auto-start on boot
  • Status dialog: Service state, PipeWire video nodes, portal IsCameraPresent
  • Dynamic icon: Active (colour) / inactive (symbolic grey), polled every 5 seconds

Platform Support

The setup script auto-detects the IPU6 variant from the PCI ID:

PlatformPCI IDHAL variant
Tiger Lake8086:9a19ipu6
Jasper Lake8086:4e19ipu6
Alder/Raptor Lake8086:462eipu6ep
Meteor Lake8086:7d19ipu6epmtl

Automated Setup

The entire process is automated in ipu6-camera:

git clone https://github.com/achrafsoltani/ipu6-camera.git
cd ipu6-camera
sudo ./setup.sh
sudo reboot

After reboot, the camera appears as “Integrated Camera” on /dev/video99 in any browser.

Upstream Contributions

Two patches submitted upstream during this work:

  • intel/ipu6-drivers PR #424: Kernel 6.17 support — dropped merged patches, kept only the ones still needed.
  • intel/usbio-drivers PR #43: Fixed DKMS version mismatch (0.2→0.3) and Makefile KERNELDIR handling.

Limitations

  • Only 1280×720 and 1920×1080 resolutions work (Camera HAL graph config limitation).
  • Raw IPU6 ISYS nodes may still appear if udev ACLs persist — one-time fix: sudo setfacl -b /dev/video{0..47}.
  • The PSYS module and USBIO drivers remain out-of-tree. Until they are upstreamed, kernel updates require DKMS rebuilds.

Achraf SOLTANI — February 16, 2026