From 8b9171eed79aa4094bc877f25a932f9a3b33436f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Tue, 21 Oct 2025 17:15:29 +0200 Subject: [PATCH] nixos/facter: add input peripheral detection This adds automatic detection and configuration for input peripherals: - bluetooth: Detects Bluetooth hardware and automatically enables - fingerprint: Detects USB fingerprint devices using libfprint device database Builds on PR #458177 (graphics). Part of incremental upstreaming from nixos-facter-modules. --- nixos/modules/hardware/facter/bluetooth.nix | 13 + nixos/modules/hardware/facter/default.nix | 2 + .../hardware/facter/fingerprint/default.nix | 37 +++ .../hardware/facter/fingerprint/devices.json | 233 ++++++++++++++++++ .../hardware/facter/fingerprint/update.nix | 37 +++ 5 files changed, 322 insertions(+) create mode 100644 nixos/modules/hardware/facter/bluetooth.nix create mode 100644 nixos/modules/hardware/facter/fingerprint/default.nix create mode 100644 nixos/modules/hardware/facter/fingerprint/devices.json create mode 100644 nixos/modules/hardware/facter/fingerprint/update.nix diff --git a/nixos/modules/hardware/facter/bluetooth.nix b/nixos/modules/hardware/facter/bluetooth.nix new file mode 100644 index 000000000000..5294589269f4 --- /dev/null +++ b/nixos/modules/hardware/facter/bluetooth.nix @@ -0,0 +1,13 @@ +{ lib, config, ... }: +{ + options.hardware.facter.detected.bluetooth.enable = + lib.mkEnableOption "Enable the Facter bluetooth module" + // { + default = builtins.length (config.hardware.facter.report.hardware.bluetooth or [ ]) > 0; + defaultText = "hardware dependent"; + }; + + config.hardware.bluetooth.enable = lib.mkIf config.hardware.facter.detected.bluetooth.enable ( + lib.mkDefault true + ); +} diff --git a/nixos/modules/hardware/facter/default.nix b/nixos/modules/hardware/facter/default.nix index 30db0d10e48a..aa8a1ca4175e 100644 --- a/nixos/modules/hardware/facter/default.nix +++ b/nixos/modules/hardware/facter/default.nix @@ -5,7 +5,9 @@ }: { imports = [ + ./bluetooth.nix ./disk.nix + ./fingerprint ./firmware.nix ./graphics ./keyboard.nix diff --git a/nixos/modules/hardware/facter/fingerprint/default.nix b/nixos/modules/hardware/facter/fingerprint/default.nix new file mode 100644 index 000000000000..59929b33a7ee --- /dev/null +++ b/nixos/modules/hardware/facter/fingerprint/default.nix @@ -0,0 +1,37 @@ +# To update devices.json, run: +# $(nix-build nixos/modules/hardware/facter/fingerprint/update.nix)/bin/update-fprint-devices +{ lib, config, ... }: +let + facterLib = import ../lib.nix lib; + + devices = builtins.fromJSON (builtins.readFile ./devices.json); + default = { + value = 0; + }; + + isSupported = lib.any ( + { + vendor ? default, + device ? default, + bus_type ? { + name = ""; + }, + ... + }: + bus_type.name == "USB" + && devices ? "${facterLib.toZeroPaddedHex vendor.value}:${facterLib.toZeroPaddedHex device.value}" + ); +in +{ + options.hardware.facter.detected.fingerprint.enable = lib.mkEnableOption "Fingerprint devices" // { + default = + isSupported (config.hardware.facter.report.hardware.unknown or [ ]) + || isSupported (config.hardware.facter.report.hardware.fingerprint or [ ]) + || isSupported (config.hardware.facter.report.hardware.usb or [ ]); + defaultText = "hardware dependent"; + }; + + config.services.fprintd.enable = lib.mkIf config.hardware.facter.detected.fingerprint.enable ( + lib.mkDefault true + ); +} diff --git a/nixos/modules/hardware/facter/fingerprint/devices.json b/nixos/modules/hardware/facter/fingerprint/devices.json new file mode 100644 index 000000000000..7eea228142ed --- /dev/null +++ b/nixos/modules/hardware/facter/fingerprint/devices.json @@ -0,0 +1,233 @@ +{ + "045E:00BB": true, + "045E:00BC": true, + "045E:00BD": true, + "045E:00CA": true, + "0483:2015": true, + "0483:2016": true, + "0483:2017": true, + "04F3:0903": true, + "04F3:0907": true, + "04F3:0C01": true, + "04F3:0C02": true, + "04F3:0C03": true, + "04F3:0C04": true, + "04F3:0C05": true, + "04F3:0C06": true, + "04F3:0C07": true, + "04F3:0C08": true, + "04F3:0C09": true, + "04F3:0C0A": true, + "04F3:0C0B": true, + "04F3:0C0C": true, + "04F3:0C0D": true, + "04F3:0C0E": true, + "04F3:0C0F": true, + "04F3:0C10": true, + "04F3:0C11": true, + "04F3:0C12": true, + "04F3:0C13": true, + "04F3:0C14": true, + "04F3:0C15": true, + "04F3:0C16": true, + "04F3:0C17": true, + "04F3:0C18": true, + "04F3:0C19": true, + "04F3:0C1A": true, + "04F3:0C1B": true, + "04F3:0C1C": true, + "04F3:0C1D": true, + "04F3:0C1E": true, + "04F3:0C1F": true, + "04F3:0C20": true, + "04F3:0C21": true, + "04F3:0C22": true, + "04F3:0C23": true, + "04F3:0C24": true, + "04F3:0C25": true, + "04F3:0C26": true, + "04F3:0C27": true, + "04F3:0C28": true, + "04F3:0C29": true, + "04F3:0C2A": true, + "04F3:0C2B": true, + "04F3:0C2C": true, + "04F3:0C2D": true, + "04F3:0C2E": true, + "04F3:0C2F": true, + "04F3:0C30": true, + "04F3:0C31": true, + "04F3:0C32": true, + "04F3:0C33": true, + "04F3:0C3D": true, + "04F3:0C42": true, + "04F3:0C4B": true, + "04F3:0C4D": true, + "04F3:0C4F": true, + "04F3:0C58": true, + "04F3:0C63": true, + "04F3:0C6E": true, + "04F3:0C7D": true, + "04F3:0C7E": true, + "04F3:0C82": true, + "04F3:0C88": true, + "04F3:0C8C": true, + "04F3:0C8D": true, + "04F3:0C98": true, + "04F3:0C99": true, + "04F3:0C9D": true, + "04F3:0C9F": true, + "04F3:0CA3": true, + "04F3:241F": true, + "04F3:2766": true, + "04F3:3057": true, + "04F3:3087": true, + "04F3:309F": true, + "04F3:30B2": true, + "04F3:30C6": true, + "04F3:3128": true, + "04F3:3134": true, + "04F3:3148": true, + "05BA:0007": true, + "05BA:0008": true, + "05BA:000A": true, + "061A:0110": true, + "06CB:00BD": true, + "06CB:00C2": true, + "06CB:00C4": true, + "06CB:00C6": true, + "06CB:00DF": true, + "06CB:00F0": true, + "06CB:00F9": true, + "06CB:00FC": true, + "06CB:0100": true, + "06CB:0103": true, + "06CB:0104": true, + "06CB:0106": true, + "06CB:0107": true, + "06CB:0108": true, + "06CB:0123": true, + "06CB:0124": true, + "06CB:0126": true, + "06CB:0129": true, + "06CB:015F": true, + "06CB:0168": true, + "06CB:016C": true, + "06CB:0173": true, + "06CB:0174": true, + "06CB:019D": true, + "08FF:1600": true, + "08FF:1660": true, + "08FF:1680": true, + "08FF:1681": true, + "08FF:1682": true, + "08FF:1683": true, + "08FF:1684": true, + "08FF:1685": true, + "08FF:1686": true, + "08FF:1687": true, + "08FF:1688": true, + "08FF:1689": true, + "08FF:168A": true, + "08FF:168B": true, + "08FF:168C": true, + "08FF:168D": true, + "08FF:168E": true, + "08FF:168F": true, + "08FF:2500": true, + "08FF:2550": true, + "08FF:2580": true, + "08FF:2660": true, + "08FF:2680": true, + "08FF:2681": true, + "08FF:2682": true, + "08FF:2683": true, + "08FF:2684": true, + "08FF:2685": true, + "08FF:2686": true, + "08FF:2687": true, + "08FF:2688": true, + "08FF:2689": true, + "08FF:268A": true, + "08FF:268B": true, + "08FF:268C": true, + "08FF:268D": true, + "08FF:268E": true, + "08FF:268F": true, + "08FF:2691": true, + "08FF:2810": true, + "08FF:5501": true, + "08FF:5731": true, + "0BDA:5813": true, + "0BDA:5816": true, + "10A5:9524": true, + "10A5:9544": true, + "10A5:A305": true, + "10A5:C844": true, + "10A5:D205": true, + "10A5:D805": true, + "10A5:DA04": true, + "10A5:FFE0": true, + "138A:0001": true, + "138A:0005": true, + "138A:0008": true, + "138A:0010": true, + "138A:0011": true, + "138A:0015": true, + "138A:0017": true, + "138A:0018": true, + "138A:0050": true, + "138A:0091": true, + "147E:1000": true, + "147E:1001": true, + "147E:2016": true, + "147E:2020": true, + "147E:3001": true, + "1C7A:0570": true, + "1C7A:0571": true, + "1C7A:0582": true, + "1C7A:0583": true, + "1C7A:0586": true, + "1C7A:0587": true, + "1C7A:05A1": true, + "1C7A:0603": true, + "27C6:5840": true, + "27C6:6014": true, + "27C6:6092": true, + "27C6:6094": true, + "27C6:609A": true, + "27C6:609C": true, + "27C6:60A2": true, + "27C6:60A4": true, + "27C6:60BC": true, + "27C6:60C2": true, + "27C6:6304": true, + "27C6:631C": true, + "27C6:633C": true, + "27C6:634C": true, + "27C6:6384": true, + "27C6:639C": true, + "27C6:63AC": true, + "27C6:63BC": true, + "27C6:63CC": true, + "27C6:6496": true, + "27C6:650A": true, + "27C6:650C": true, + "27C6:6512": true, + "27C6:6582": true, + "27C6:6584": true, + "27C6:658C": true, + "27C6:6592": true, + "27C6:6594": true, + "27C6:659A": true, + "27C6:659C": true, + "27C6:689A": true, + "27C6:6A94": true, + "2808:9E48": true, + "2808:A57A": true, + "2808:A78A": true, + "2808:A959": true, + "2808:A99A": true, + "2808:D979": true, + "298D:1010": true +} diff --git a/nixos/modules/hardware/facter/fingerprint/update.nix b/nixos/modules/hardware/facter/fingerprint/update.nix new file mode 100644 index 000000000000..492f3aec2845 --- /dev/null +++ b/nixos/modules/hardware/facter/fingerprint/update.nix @@ -0,0 +1,37 @@ +# Run: $(nix-build nixos/modules/hardware/facter/fingerprint/update.nix)/bin/update-fprint-devices +{ + pkgs ? import ../../../../.. { }, +}: +let + fprint-supported-devices = pkgs.libfprint.overrideAttrs (old: { + nativeBuildInputs = old.nativeBuildInputs or [ ] ++ [ + pkgs.jq + pkgs.gawk + ]; + buildPhase = '' + ninja libfprint/fprint-list-supported-devices + ''; + outputs = [ "out" ]; + installPhase = '' + ./libfprint/fprint-list-supported-devices | \ + grep -o -E '(\b[0-9a-fA-F]{4}:[0-9a-fA-F]{4}\b)' | \ + awk '{print toupper($0)}' | \ + jq -S -R -s 'split("\n") | map(select(. != "")) | map({key: ., value: true}) | from_entries' > $out + ''; + # we cannot disable doInstallcheck because than we are missing nativeCheckInputs dependencies + installCheckPhase = ""; + }); +in +pkgs.writeShellApplication { + name = "update-fprint-devices"; + runtimeInputs = with pkgs; [ + coreutils + git + ]; + text = '' + root="$(git rev-parse --show-toplevel)" + target="$root/nixos/modules/hardware/facter/fingerprint/devices.json" + cp ${fprint-supported-devices} "$target" + echo "Updated $target" + ''; +}