From c98f963a0cf92f9511f98e2c3383bb7b98937206 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 15 Mar 2026 18:25:21 +0100 Subject: [PATCH] Add omarchy-mipi-camera package to drive webcam in XPS 16 and other Panther Lake units --- ...camera_pwrup_host-0-for-Panther-Lake.patch | 30 +++ .../omarchy-mipi-camera/90-ipu7-psys.rules | 6 + pkgbuilds/edge/omarchy-mipi-camera/PKGBUILD | 220 ++++++++++++++++++ .../edge/omarchy-mipi-camera/camera-deps.conf | 5 + .../omarchy-mipi-camera/camera-feed-watch | 144 ++++++++++++ .../camera-feed-watch.service | 12 + .../omarchy-mipi-camera/camera-init.service | 11 + .../omarchy-mipi-camera/camera-tmpfiles.conf | 1 + .../disable-libcamera.conf | 16 ++ .../dkms-ipu7-drivers.conf | 30 +++ .../dkms-vision-drivers.conf | 10 + .../omarchy-mipi-camera/hide-ipu7-v4l2.conf | 16 ++ .../omarchy-mipi-camera.install | 47 ++++ .../edge/omarchy-mipi-camera/ov08x40.yaml | 16 ++ .../v4l2loopback-modprobe.conf | 1 + .../v4l2loopback-modules-load.conf | 1 + 16 files changed, 566 insertions(+) create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/0003-icvs-set-rgbcamera_pwrup_host-0-for-Panther-Lake.patch create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/90-ipu7-psys.rules create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/PKGBUILD create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/camera-deps.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch.service create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/camera-init.service create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/camera-tmpfiles.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/disable-libcamera.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/dkms-ipu7-drivers.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/dkms-vision-drivers.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/hide-ipu7-v4l2.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/omarchy-mipi-camera.install create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/ov08x40.yaml create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modprobe.conf create mode 100644 pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modules-load.conf diff --git a/pkgbuilds/edge/omarchy-mipi-camera/0003-icvs-set-rgbcamera_pwrup_host-0-for-Panther-Lake.patch b/pkgbuilds/edge/omarchy-mipi-camera/0003-icvs-set-rgbcamera_pwrup_host-0-for-Panther-Lake.patch new file mode 100644 index 0000000..8f2fc00 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/0003-icvs-set-rgbcamera_pwrup_host-0-for-Panther-Lake.patch @@ -0,0 +1,30 @@ +From 8d49375eff603615323a6144e287ffd6a8429b1b Mon Sep 17 00:00:00 2001 +From: Intel +Date: Tue, 3 Mar 2026 15:30:43 -0800 +Subject: [PATCH] icvs: set rgbcamera_pwrup_host=0 for Panther Lake + +On Panther Lake, sensor power goes through USBIO GPIO which is managed +by CVS firmware, not the host. With the default rgbcamera_pwrup_host=1, +the sensor never powers up and I2C reads time out with -ETIMEDOUT. + +Setting this to 0 tells CVS firmware to handle sensor power sequencing +via USBIO GPIO, which is the correct path on PTL. +--- + drivers/misc/icvs/intel_cvs_update.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/misc/icvs/intel_cvs_update.c b/drivers/misc/icvs/intel_cvs_update.c +index 5f069aa..5dc4c85 100644 +--- a/drivers/misc/icvs/intel_cvs_update.c ++++ b/drivers/misc/icvs/intel_cvs_update.c +@@ -54,7 +54,7 @@ int cvs_write_i2c(u16 cmd, u8 *data, u32 len) + host_identifiers.field.vision_sensing = 0; + host_identifiers.field.device_power_setting = 0; + host_identifiers.field.privacy_led_host = 0; +- host_identifiers.field.rgbcamera_pwrup_host = 1; ++ host_identifiers.field.rgbcamera_pwrup_host = 0; + + memcpy(&out_buff[2], &host_identifiers.value, + cv_host_identifier_size); +-- +2.53.0 diff --git a/pkgbuilds/edge/omarchy-mipi-camera/90-ipu7-psys.rules b/pkgbuilds/edge/omarchy-mipi-camera/90-ipu7-psys.rules new file mode 100644 index 0000000..bf62c6d --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/90-ipu7-psys.rules @@ -0,0 +1,6 @@ +KERNEL=="ipu7-psys0", MODE="0666", SYMLINK+="ipu-psys0" + +# Hide raw IPU7 ISYS capture devices from applications. +# These are internal ISP nodes that cannot produce frames directly. +# Camera is provided via v4l2loopback (/dev/video50) instead. +SUBSYSTEM=="video4linux", ATTR{name}=="Intel IPU7 ISYS Capture *", TAG-="uaccess" diff --git a/pkgbuilds/edge/omarchy-mipi-camera/PKGBUILD b/pkgbuilds/edge/omarchy-mipi-camera/PKGBUILD new file mode 100644 index 0000000..a2b04f3 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/PKGBUILD @@ -0,0 +1,220 @@ +# Maintainer: Omarchy + +pkgname=omarchy-mipi-camera +pkgver=1.0.0 +pkgrel=1 +pkgdesc="Intel IPU7 MIPI camera stack for Hurrican/Performance (OV08X40 + hardware ISP)" +arch=('x86_64') +url="https://github.com/TsaiGaggery/hurrican_omarchy_enabling" +license=('GPL-2.0-or-later') +depends=( + 'dkms' + 'linux-headers' + 'v4l2loopback-dkms' + 'gstreamer' + 'gst-plugins-base' + 'gst-plugins-good' + 'gst-plugins-bad' + 'jsoncpp' + 'libdrm' + 'python' +) +makedepends=( + 'git' + 'base-devel' + 'cmake' + 'autoconf' + 'automake' + 'libtool' + 'pkgconf' +) +install=omarchy-mipi-camera.install +options=('!strip') + +_ipu7_drivers_commit="a88b19096a738d0708742a78d6540d6d4a3021ff" +_vision_drivers_commit="a8d772f261bc90376944956b7bfd49b325ffa2f2" +_ipu7_camera_bins_commit="403c67db6b279dd02752f11db6a34552f31a3ac5" +_ipu7_camera_hal_commit="b1f6ebef12111fb5da0133b144d69dd9b001836c" +_icamerasrc_commit="4fb31db76b618aae72184c59314b839dedb42689" + +source=( + "ipu7-drivers::git+https://github.com/intel/ipu7-drivers.git#commit=${_ipu7_drivers_commit}" + "vision-drivers::git+https://github.com/intel/vision-drivers.git#commit=${_vision_drivers_commit}" + "ipu7-camera-bins::git+https://github.com/intel/ipu7-camera-bins.git#commit=${_ipu7_camera_bins_commit}" + "ipu7-camera-hal::git+https://github.com/intel/ipu7-camera-hal.git#commit=${_ipu7_camera_hal_commit}" + "icamerasrc::git+https://github.com/intel/icamerasrc.git#commit=${_icamerasrc_commit}" + "0003-icvs-set-rgbcamera_pwrup_host-0-for-Panther-Lake.patch" + "dkms-ipu7-drivers.conf" + "dkms-vision-drivers.conf" + "camera-deps.conf" + "v4l2loopback-modprobe.conf" + "v4l2loopback-modules-load.conf" + "camera-init.service" + "camera-feed-watch" + "camera-feed-watch.service" + "hide-ipu7-v4l2.conf" + "disable-libcamera.conf" + "90-ipu7-psys.rules" + "camera-tmpfiles.conf" + "ov08x40.yaml" +) +sha256sums=( + 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' + 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' + 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' + 'SKIP' +) + +prepare() { + cd "${srcdir}/vision-drivers" + git config user.email "build@localhost" + git config user.name "Build" + if ! git log --oneline -1 | grep -q "rgbcamera_pwrup_host"; then + git am "${srcdir}/0003-icvs-set-rgbcamera_pwrup_host-0-for-Panther-Lake.patch" + fi + + # Stage proprietary libs/headers for build-time use + local staging="${srcdir}/staging" + rm -rf "${staging}" + mkdir -p "${staging}/usr/lib" "${staging}/usr/include" "${staging}/usr/lib/pkgconfig" + + cd "${srcdir}/ipu7-camera-bins" + cp -P lib/lib* "${staging}/usr/lib/" + cp -r include/* "${staging}/usr/include/" + cp -r lib/pkgconfig/* "${staging}/usr/lib/pkgconfig/" + + for pc in "${staging}"/usr/lib/pkgconfig/*.pc; do + sed -i "s|^prefix=.*|prefix=${staging}/usr|" "$pc" + done + + if [[ -d /usr/include/json ]] && [[ ! -e /usr/include/jsoncpp/json ]]; then + mkdir -p "${staging}/usr/include/jsoncpp" + ln -sf /usr/include/json "${staging}/usr/include/jsoncpp/json" + fi +} + +build() { + local staging="${srcdir}/staging" + + export PKG_CONFIG_PATH="${staging}/usr/lib/pkgconfig:${PKG_CONFIG_PATH:-}" + export LIBRARY_PATH="${staging}/usr/lib:${LIBRARY_PATH:-}" + export LD_LIBRARY_PATH="${staging}/usr/lib:${LD_LIBRARY_PATH:-}" + export CPATH="${staging}/usr/include:${CPATH:-}" + + cd "${srcdir}/ipu7-camera-hal" + rm -rf build && mkdir -p build && cd build + cmake -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DBUILD_CAMHAL_ADAPTOR=ON \ + -DBUILD_CAMHAL_PLUGIN=ON \ + -DIPU_VERSIONS="ipu75xa" \ + -DUSE_STATIC_GRAPH=ON \ + -DUSE_STATIC_GRAPH_AUTOGEN=ON \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -DCMAKE_PREFIX_PATH="${staging}/usr" \ + -DCMAKE_LIBRARY_PATH="${staging}/usr/lib" \ + -DCMAKE_INCLUDE_PATH="${staging}/usr/include" \ + .. + make -j"$(nproc)" + + make DESTDIR="${staging}" install + install -Dm644 "${srcdir}/ipu7-camera-hal/libcamhal.pc" \ + "${staging}/usr/lib/pkgconfig/libcamhal.pc" + sed -i "s|^prefix=.*|prefix=${staging}/usr|" "${staging}/usr/lib/pkgconfig/libcamhal.pc" + + cd "${srcdir}/icamerasrc" + export CHROME_SLIM_CAMHAL=ON + [[ ! -f configure ]] && ./autogen.sh + ./configure --prefix=/usr + make -j"$(nproc)" +} + +package() { + # DKMS: IPU7 drivers (ISYS + PSYS + ACPI) + local ipu7_dkms_dir="${pkgdir}/usr/src/ipu7-drivers-${pkgver}" + install -dm755 "${ipu7_dkms_dir}" + cp -r "${srcdir}/ipu7-drivers/"* "${ipu7_dkms_dir}/" + rm -rf "${ipu7_dkms_dir}/.git" + install -Dm644 "${srcdir}/dkms-ipu7-drivers.conf" "${ipu7_dkms_dir}/dkms.conf" + sed -i "s/@PKGVER@/${pkgver}/" "${ipu7_dkms_dir}/dkms.conf" + + # DKMS: Vision drivers (CVS) + local cvs_dkms_dir="${pkgdir}/usr/src/vision-drivers-${pkgver}" + install -dm755 "${cvs_dkms_dir}" + cp -r "${srcdir}/vision-drivers/"* "${cvs_dkms_dir}/" + install -Dm644 "${srcdir}/dkms-vision-drivers.conf" "${cvs_dkms_dir}/dkms.conf" + sed -i "s/@PKGVER@/${pkgver}/" "${cvs_dkms_dir}/dkms.conf" + + # Firmware + install -dm755 "${pkgdir}/usr/lib/firmware/intel/ipu" + install -Dm644 "${srcdir}/ipu7-camera-bins/lib/firmware/intel/ipu/"*.bin \ + -t "${pkgdir}/usr/lib/firmware/intel/ipu/" + + # Proprietary libraries + headers from ipu7-camera-bins + cd "${srcdir}/ipu7-camera-bins" + install -dm755 "${pkgdir}/usr/lib" + cp -P lib/lib* "${pkgdir}/usr/lib/" + install -dm755 "${pkgdir}/usr/include" + cp -r include/* "${pkgdir}/usr/include/" + install -dm755 "${pkgdir}/usr/lib/pkgconfig" + cp -r lib/pkgconfig/* "${pkgdir}/usr/lib/pkgconfig/" + + # Camera HAL + config + cd "${srcdir}/ipu7-camera-hal/build" + make DESTDIR="${pkgdir}" install + + cd "${srcdir}/ipu7-camera-hal" + install -dm755 "${pkgdir}/usr/share/defaults/etc/camera" + install -Dm644 config/linux/ipu75xa/libcamhal_configs.json \ + "${pkgdir}/usr/share/defaults/etc/camera/" + install -Dm644 config/linux/ipu75xa/*.aiqb \ + -t "${pkgdir}/usr/share/defaults/etc/camera/" + + install -dm755 "${pkgdir}/etc/camera/ipu75xa/gcss" + install -Dm644 config/linux/ipu75xa/gcss/*.bin \ + -t "${pkgdir}/etc/camera/ipu75xa/gcss/" + + install -dm755 "${pkgdir}/etc/camera/ipu75xa/sensors" + install -Dm644 config/linux/ipu75xa/sensors/*.json \ + -t "${pkgdir}/etc/camera/ipu75xa/sensors/" + + install -Dm644 config/linux/ipu75xa/pipe_scheduler_profiles.json \ + "${pkgdir}/etc/camera/ipu75xa/" + install -Dm644 config/linux/ipu75xa/pnp_profiles.json \ + "${pkgdir}/etc/camera/ipu75xa/" + + # icamerasrc GStreamer plugin + cd "${srcdir}/icamerasrc" + make DESTDIR="${pkgdir}" install + + # modprobe / modules-load + install -Dm644 "${srcdir}/camera-deps.conf" \ + "${pkgdir}/usr/lib/modprobe.d/camera-deps.conf" + install -Dm644 "${srcdir}/v4l2loopback-modprobe.conf" \ + "${pkgdir}/usr/lib/modprobe.d/v4l2loopback-camera.conf" + install -Dm644 "${srcdir}/v4l2loopback-modules-load.conf" \ + "${pkgdir}/usr/lib/modules-load.d/v4l2loopback.conf" + + # systemd + install -Dm644 "${srcdir}/camera-init.service" \ + "${pkgdir}/usr/lib/systemd/system/camera-init.service" + install -Dm644 "${srcdir}/camera-feed-watch.service" \ + "${pkgdir}/usr/lib/systemd/user/camera-feed-watch.service" + install -Dm755 "${srcdir}/camera-feed-watch" \ + "${pkgdir}/usr/bin/camera-feed-watch" + + # WirePlumber + install -Dm644 "${srcdir}/hide-ipu7-v4l2.conf" \ + "${pkgdir}/usr/share/wireplumber/wireplumber.conf.d/hide-ipu7-v4l2.conf" + install -Dm644 "${srcdir}/disable-libcamera.conf" \ + "${pkgdir}/usr/share/wireplumber/wireplumber.conf.d/disable-libcamera.conf" + + # udev / tmpfiles / libcamera tuning + install -Dm644 "${srcdir}/90-ipu7-psys.rules" \ + "${pkgdir}/usr/lib/udev/rules.d/90-ipu7-psys.rules" + install -Dm644 "${srcdir}/camera-tmpfiles.conf" \ + "${pkgdir}/usr/lib/tmpfiles.d/camera.conf" + install -Dm644 "${srcdir}/ov08x40.yaml" \ + "${pkgdir}/usr/share/libcamera/ipa/simple/ov08x40.yaml" +} diff --git a/pkgbuilds/edge/omarchy-mipi-camera/camera-deps.conf b/pkgbuilds/edge/omarchy-mipi-camera/camera-deps.conf new file mode 100644 index 0000000..0c4ab5f --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/camera-deps.conf @@ -0,0 +1,5 @@ +# Blacklist ov08x40 - it must load AFTER intel_cvs acquires camera ownership +blacklist ov08x40 + +# Soft dependency: if ov08x40 is loaded, ensure intel_cvs loads first +softdep ov08x40 pre: intel_cvs diff --git a/pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch b/pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch new file mode 100644 index 0000000..5edfef0 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +"""On-demand camera feed for v4l2loopback. + +Holds /dev/video50 open permanently so v4l2loopback stays in capture mode. +Writes black frames when idle (0% CPU, LED off). Starts the real camera +pipeline when an app opens the device, relaying frames through the same fd. +Stops the camera when all readers close. No fd gap = no stream interruption. +""" + +import fcntl, os, signal, struct, subprocess, sys, threading, time + +DEVICE = "/dev/video50" +W, H = 1920, 1080 +FSIZE = W * H * 3 // 2 +POLL = 2 +STOP_DELAY = 6 + +BLACK = bytes(W * H) + bytes([128] * (W * H // 2)) + +dev = os.open(DEVICE, os.O_WRONLY) +pixfmt = struct.pack("II4sIIII4x188x", W, H, b"NV12", 1, W, FSIZE, 0) +fmt = struct.pack("I4x", 2) + pixfmt +fcntl.ioctl(dev, 0xC0D05605, fmt) +os.write(dev, BLACK) + +# Restart WirePlumber so it sees the capture device +time.sleep(1) +subprocess.run(["systemctl", "--user", "restart", "wireplumber.service"], + capture_output=True, timeout=10) + +cam_proc = None +cam_lock = threading.Lock() +stop_idle = threading.Event() + + +def write_idle(): + while not stop_idle.is_set(): + try: + os.write(dev, BLACK) + except OSError: + pass + stop_idle.wait(2) + + +def relay_camera(): + global cam_proc + env = os.environ.copy() + env["GST_PLUGIN_PATH"] = "/usr/lib/gstreamer-1.0" + cam_proc = subprocess.Popen( + ["gst-launch-1.0", "-q", + "icamerasrc", "device-name=ov08x40-uf", + "sharpness=80", "ev=-1", "saturation=10", + "!", "video/x-raw,format=NV12,width=1920,height=1080", + "!", "videoflip", "method=rotate-180", + "!", "fdsink", "fd=1"], + stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env, + ) + buf = b"" + while cam_proc.poll() is None: + data = cam_proc.stdout.read(65536) + if not data: + break + buf += data + while len(buf) >= FSIZE: + try: + os.write(dev, buf[:FSIZE]) + except OSError: + pass + buf = buf[FSIZE:] + cam_proc = None + + +def has_readers(): + try: + r = subprocess.run(["fuser", DEVICE], capture_output=True, text=True, timeout=5) + for pid in r.stdout.strip().split(): + pid = pid.strip() + if not pid: + continue + if int(pid) == os.getpid(): + continue + with cam_lock: + if cam_proc and int(pid) == cam_proc.pid: + continue + return True + except Exception: + pass + return False + + +def start_camera(): + stop_idle.set() + t = threading.Thread(target=relay_camera, daemon=True) + t.start() + return t + + +def stop_camera(): + with cam_lock: + if cam_proc: + cam_proc.terminate() + try: + cam_proc.wait(timeout=5) + except subprocess.TimeoutExpired: + cam_proc.kill() + stop_idle.clear() + t = threading.Thread(target=write_idle, daemon=True) + t.start() + return t + + +def shutdown(sig, frame): + stop_idle.set() + with cam_lock: + if cam_proc: + cam_proc.terminate() + os.close(dev) + sys.exit(0) + + +signal.signal(signal.SIGTERM, shutdown) +signal.signal(signal.SIGINT, shutdown) + +# Start idle +idle_thread = threading.Thread(target=write_idle, daemon=True) +idle_thread.start() + +active = False +idle_count = 0 + +while True: + if has_readers(): + idle_count = 0 + if not active: + start_camera() + active = True + else: + if active: + idle_count += 1 + if idle_count >= STOP_DELAY // POLL: + stop_camera() + active = False + idle_count = 0 + time.sleep(POLL) diff --git a/pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch.service b/pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch.service new file mode 100644 index 0000000..cc0c90b --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/camera-feed-watch.service @@ -0,0 +1,12 @@ +[Unit] +Description=Camera feed for v4l2loopback (on-demand, LED off when idle) +After=pipewire.service camera-init.service + +[Service] +Type=simple +ExecStart=/usr/bin/camera-feed-watch +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=default.target diff --git a/pkgbuilds/edge/omarchy-mipi-camera/camera-init.service b/pkgbuilds/edge/omarchy-mipi-camera/camera-init.service new file mode 100644 index 0000000..2a1085a --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/camera-init.service @@ -0,0 +1,11 @@ +[Unit] +Description=Initialize camera (CVS ownership then sensor driver) +After=systemd-modules-load.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/bash -c "modprobe intel_cvs && sleep 2 && modprobe ov08x40" + +[Install] +WantedBy=multi-user.target diff --git a/pkgbuilds/edge/omarchy-mipi-camera/camera-tmpfiles.conf b/pkgbuilds/edge/omarchy-mipi-camera/camera-tmpfiles.conf new file mode 100644 index 0000000..4b88626 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/camera-tmpfiles.conf @@ -0,0 +1 @@ +d /run/camera 0777 root root - diff --git a/pkgbuilds/edge/omarchy-mipi-camera/disable-libcamera.conf b/pkgbuilds/edge/omarchy-mipi-camera/disable-libcamera.conf new file mode 100644 index 0000000..5892238 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/disable-libcamera.conf @@ -0,0 +1,16 @@ +# Disable libcamera monitor - make it a no-op to prevent crash +# Camera is provided via v4l2loopback + icamerasrc instead +wireplumber.components.rules = [ + { + matches = [ + { + name = "monitors/libcamera/enumerate-device.lua" + } + ] + actions = { + override = { + name = /dev/null, type = script/lua + } + } + } +] diff --git a/pkgbuilds/edge/omarchy-mipi-camera/dkms-ipu7-drivers.conf b/pkgbuilds/edge/omarchy-mipi-camera/dkms-ipu7-drivers.conf new file mode 100644 index 0000000..af9f6cb --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/dkms-ipu7-drivers.conf @@ -0,0 +1,30 @@ +PACKAGE_NAME="ipu7-drivers" +PACKAGE_VERSION="@PKGVER@" +AUTOINSTALL="yes" + +BUILT_MODULE_NAME[0]="intel-ipu7" +BUILT_MODULE_LOCATION[0]="drivers/media/pci/intel/ipu7/" +DEST_MODULE_LOCATION[0]="/updates" + +BUILT_MODULE_NAME[1]="intel-ipu7-isys" +BUILT_MODULE_LOCATION[1]="drivers/media/pci/intel/ipu7/" +DEST_MODULE_LOCATION[1]="/updates" + +BUILT_MODULE_NAME[2]="intel-ipu7-psys" +BUILT_MODULE_LOCATION[2]="drivers/media/pci/intel/ipu7/psys/" +DEST_MODULE_LOCATION[2]="/updates" + +BUILT_MODULE_NAME[3]="ipu-acpi" +BUILT_MODULE_LOCATION[3]="drivers/media/platform/intel/" +DEST_MODULE_LOCATION[3]="/updates" + +BUILT_MODULE_NAME[4]="ipu-acpi-pdata" +BUILT_MODULE_LOCATION[4]="drivers/media/platform/intel/" +DEST_MODULE_LOCATION[4]="/updates" + +BUILT_MODULE_NAME[5]="ipu-acpi-common" +BUILT_MODULE_LOCATION[5]="drivers/media/platform/intel/" +DEST_MODULE_LOCATION[5]="/updates" + +MAKE[0]="make BUILD_INTEL_IPU_ACPI=1 KERNEL_SRC=${kernel_source_dir}" +CLEAN="make KERNEL_SRC=${kernel_source_dir} clean" diff --git a/pkgbuilds/edge/omarchy-mipi-camera/dkms-vision-drivers.conf b/pkgbuilds/edge/omarchy-mipi-camera/dkms-vision-drivers.conf new file mode 100644 index 0000000..3582d0f --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/dkms-vision-drivers.conf @@ -0,0 +1,10 @@ +PACKAGE_NAME="vision-drivers" +PACKAGE_VERSION="@PKGVER@" +AUTOINSTALL="yes" + +BUILT_MODULE_NAME[0]="intel_cvs" +BUILT_MODULE_LOCATION[0]="" +DEST_MODULE_LOCATION[0]="/updates" + +MAKE[0]="make KERNEL_SRC=${kernel_source_dir}" +CLEAN="make KERNEL_SRC=${kernel_source_dir} clean" diff --git a/pkgbuilds/edge/omarchy-mipi-camera/hide-ipu7-v4l2.conf b/pkgbuilds/edge/omarchy-mipi-camera/hide-ipu7-v4l2.conf new file mode 100644 index 0000000..b056172 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/hide-ipu7-v4l2.conf @@ -0,0 +1,16 @@ +# Hide raw IPU7 V4L2 devices from PipeWire - they are internal ISP nodes +# Camera is provided via v4l2loopback + icamerasrc instead +monitor.v4l2.rules = [ + { + matches = [ + { + device.bus-path = "pci-0000:00:05.0" + } + ] + actions = { + update-props = { + device.disabled = true + } + } + } +] diff --git a/pkgbuilds/edge/omarchy-mipi-camera/omarchy-mipi-camera.install b/pkgbuilds/edge/omarchy-mipi-camera/omarchy-mipi-camera.install new file mode 100644 index 0000000..86307a0 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/omarchy-mipi-camera.install @@ -0,0 +1,47 @@ +_add_pipewire_camera() { + local conf="$1" + if [ -f "$conf" ] && grep -q 'enable-features=' "$conf" && ! grep -q 'PipeWireCamera' "$conf"; then + sed -i 's/--enable-features=\([^ ]*\)/--enable-features=\1,PipeWireCamera/' "$conf" + fi +} + +_remove_pipewire_camera() { + local conf="$1" + [ -f "$conf" ] && sed -i 's/,PipeWireCamera//g' "$conf" +} + +post_install() { + systemctl daemon-reload + systemctl enable camera-init.service + udevadm control --reload-rules 2>/dev/null || true + + if [ -n "$SUDO_USER" ]; then + usermod -aG video "$SUDO_USER" 2>/dev/null || true + su - "$SUDO_USER" -c "systemctl --user daemon-reload; systemctl --user enable camera-feed-watch.service" 2>/dev/null || true + + _add_pipewire_camera "/home/$SUDO_USER/.config/chromium-flags.conf" + _add_pipewire_camera "/home/$SUDO_USER/.config/brave-flags.conf" + fi +} + +post_upgrade() { + systemctl daemon-reload + udevadm control --reload-rules 2>/dev/null || true +} + +pre_remove() { + systemctl disable camera-init.service 2>/dev/null || true + systemctl stop camera-init.service 2>/dev/null || true + + if [ -n "$SUDO_USER" ]; then + su - "$SUDO_USER" -c "systemctl --user stop camera-feed-watch.service; systemctl --user disable camera-feed-watch.service" 2>/dev/null || true + + _remove_pipewire_camera "/home/$SUDO_USER/.config/chromium-flags.conf" + _remove_pipewire_camera "/home/$SUDO_USER/.config/brave-flags.conf" + fi +} + +post_remove() { + systemctl daemon-reload + udevadm control --reload-rules 2>/dev/null || true +} diff --git a/pkgbuilds/edge/omarchy-mipi-camera/ov08x40.yaml b/pkgbuilds/edge/omarchy-mipi-camera/ov08x40.yaml new file mode 100644 index 0000000..12e19c5 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/ov08x40.yaml @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: CC0-1.0 +# Tuning file for OmniVision OV08X40 +# Used by libcamera simple pipeline handler software ISP +%YAML 1.1 +--- +version: 1 +algorithms: + - BlackLevel: + r: 16 + gr: 16 + gb: 16 + b: 16 + - Awb: + - Adjust: + - Agc: +... diff --git a/pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modprobe.conf b/pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modprobe.conf new file mode 100644 index 0000000..26fbefe --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modprobe.conf @@ -0,0 +1 @@ +options v4l2loopback video_nr=50 card_label="Hardware ISP Camera" exclusive_caps=1 max_buffers=16 diff --git a/pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modules-load.conf b/pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modules-load.conf new file mode 100644 index 0000000..d394e47 --- /dev/null +++ b/pkgbuilds/edge/omarchy-mipi-camera/v4l2loopback-modules-load.conf @@ -0,0 +1 @@ +v4l2loopback