# Cameras on the Lenovo Duet 3 (`lenovo-wormdingler`) — TODO The front and rear cameras do **not** work on the current Mobile NixOS image. This file is a starting point for picking the work back up later, so we don't have to re-diagnose from scratch. ## Current state (May 2026) Empirical, taken on the running device: ``` $ uname -a Linux ideapad 6.5.0 #1-mobile-nixos SMP Tue Jan 1 00:00:00 UTC 1980 aarch64 GNU/Linux $ ls /dev/video* /dev/video0 ← Qualcomm Venus video decoder (h.264/h.265 dec) /dev/video1 ← Qualcomm Venus video encoder (h.264/h.265 enc) $ ls /dev/media* # nothing — no media controller graph at all $ lsmod | grep -i camss # nothing $ wpctl status | grep -A1 Sources # nothing — PipeWire has no camera sources ``` Relevant kernel config bits in `/proc/config.gz` on the running image: ``` CONFIG_MEDIA_CAMERA_SUPPORT=y ← media framework is on # CONFIG_VIDEO_QCOM_CAMSS is not set ← Qualcomm Camera Subsystem driver is OFF # CONFIG_VIDEO_OV5675 is not set ← every relevant sensor driver is OFF # CONFIG_VIDEO_OV13858 is not set # CONFIG_VIDEO_HI556 is not set # (full grep of `VIDEO_OV*` / `VIDEO_HI*` is all `not set`) ``` So the *media framework* is enabled, but the *ISP driver* (CAMSS) and every plausible sensor driver are off, and no out-of-tree modules are shipped. The two `/dev/video*` nodes are the Venus codecs, not cameras — that's why `snapshot` reports "no camera found." ## Why this is non-trivial 1. **Kernel rebuild required.** `mobile-nixos` builds its own kernel for this device (see `mobile.kernel.structuredConfig` in `hardware.nix`, where we already enable `CIFS` and `EXFAT_FS`). Adding camera support means adding: - `VIDEO_QCOM_CAMSS = module;` - The right sensor driver(s) — and we don't currently know which ones the Duet 3 actually uses. The `wormdingler` Chromium-OS DT references a pair of OV-series sensors but the exact part numbers can vary by SKU and production batch. - Their dependencies (`I2C`, `V4L2`, `MEDIA_CONTROLLER`, etc. — most are already pulled in by `MEDIA_CAMERA_SUPPORT`). 2. **Device-tree wiring.** Even with the drivers compiled in, the device tree has to describe the CCI bus, the sensor I²C addresses, the regulators, the reset/enable GPIOs, and the CSI port mapping. Mobile NixOS' DT for wormdingler may or may not include these nodes — needs verification by reading the upstream device file at `${inputs.mobile-nixos}/devices/lenovo-wormdingler/`. 3. **libcamera is the user-space side.** CAMSS is not a "single v4l2 device" driver — it exposes a media-controller graph that has to be configured by libcamera (per-sensor IPA, format negotiation, etc.). Apps then talk to libcamera via the `libcamerasrc` PipeWire module or directly. So the user-space stack is: - `pkgs.libcamera` (system-wide) - `pkgs.pipewire` already running, but needs the libcamera module enabled (`services.pipewire.libcamera = …` or equivalent — check current option name) - GUI: `snapshot`, `gnome-camera`, or anything that talks to PipeWire video sources. ## Investigation checklist When picking this up again, do these in order: 1. **Identify the actual sensors.** The cleanest way: - Read the upstream Mobile NixOS device file for wormdingler (`devices/lenovo-wormdingler/default.nix` and any `.dts` overlays). - Cross-check with the Chromium OS overlay at and the upstream Linux DTS at `arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler-*.dts`. - As a runtime cross-check, when CAMSS is eventually loaded, `dmesg | grep -i -E 'cci|sensor|isp'` will print the I²C probe attempts. 2. **Enable kernel options** in `modules/hosts/ideapad/hardware.nix` under `mobile.kernel.structuredConfig`: ```nix (helpers: with helpers; { VIDEO_QCOM_CAMSS = module; # plus whatever sensors step 1 identified, e.g.: # VIDEO_OV5675 = module; # VIDEO_OV13858 = module; }) ``` Cross-build on the 14900k via the existing flow (binfmt aarch64 + push back). Reboot, then check: ``` ls /dev/media* # expect at least /dev/media0 sudo dmesg | grep -i -E 'camss|sensor|isp|cci' # probe history sudo modprobe -v qcom-camss # if not auto-loaded ``` 3. **Install diagnostic tools** for this round of work (do **not** keep these in the long-term config unless cameras actually work): ```nix environment.systemPackages = with pkgs; [ v4l-utils # provides v4l2-ctl, media-ctl libcamera # provides `cam`, `qcam` ]; ``` Then: ``` v4l2-ctl --list-devices media-ctl -p # dumps the full media-controller graph cam -l # libcamera's view of available cameras ``` 4. **Wire libcamera into PipeWire.** Once `cam -l` shows at least one camera, enable PipeWire's libcamera module (option name may have shifted; current nixpkgs typically has `services.pipewire.wireplumber.extraConfig` or similar). Then `wpctl status` should show new Sources under "Video", and `snapshot` will see them. 5. **Re-add a camera GUI** to `configuration.nix`. `snapshot` is the simplest touch-first option; `gnome-camera` and `cheese` are alternatives. ## Why nothing else is being touched right now Steps 1–4 above are speculative — there's no guarantee the Duet 3 cameras have working mainline-Linux sensor drivers at all. The conservative move is to leave the config tablet-usable without them, document the dead end, and revisit when there's time for a real spike.