about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/hardware
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/hardware')
-rw-r--r--nixpkgs/nixos/modules/hardware/acpilight.nix24
-rw-r--r--nixpkgs/nixos/modules/hardware/all-firmware.nix78
-rw-r--r--nixpkgs/nixos/modules/hardware/bladeRF.nix28
-rw-r--r--nixpkgs/nixos/modules/hardware/brillo.nix22
-rw-r--r--nixpkgs/nixos/modules/hardware/ckb-next.nix54
-rw-r--r--nixpkgs/nixos/modules/hardware/cpu/amd-microcode.nix29
-rw-r--r--nixpkgs/nixos/modules/hardware/cpu/intel-microcode.nix29
-rw-r--r--nixpkgs/nixos/modules/hardware/device-tree.nix56
-rw-r--r--nixpkgs/nixos/modules/hardware/digitalbitbox.nix30
-rw-r--r--nixpkgs/nixos/modules/hardware/ksm.nix38
-rw-r--r--nixpkgs/nixos/modules/hardware/ledger.nix14
-rw-r--r--nixpkgs/nixos/modules/hardware/logitech.nix28
-rw-r--r--nixpkgs/nixos/modules/hardware/mcelog.nix35
-rw-r--r--nixpkgs/nixos/modules/hardware/network/b43.nix34
-rw-r--r--nixpkgs/nixos/modules/hardware/network/broadcom-43xx.nix3
-rw-r--r--nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix30
-rw-r--r--nixpkgs/nixos/modules/hardware/network/smc-2632w/default.nix9
-rw-r--r--nixpkgs/nixos/modules/hardware/network/smc-2632w/firmware/cis/SMC2632W-v1.02.cis8
-rw-r--r--nixpkgs/nixos/modules/hardware/network/zydas-zd1211.nix5
-rw-r--r--nixpkgs/nixos/modules/hardware/nitrokey.nix41
-rw-r--r--nixpkgs/nixos/modules/hardware/onlykey.nix33
-rw-r--r--nixpkgs/nixos/modules/hardware/onlykey.udev4
-rw-r--r--nixpkgs/nixos/modules/hardware/opengl.nix158
-rw-r--r--nixpkgs/nixos/modules/hardware/openrazer.nix133
-rw-r--r--nixpkgs/nixos/modules/hardware/pcmcia.nix59
-rw-r--r--nixpkgs/nixos/modules/hardware/printers.nix135
-rw-r--r--nixpkgs/nixos/modules/hardware/raid/hpsa.nix61
-rw-r--r--nixpkgs/nixos/modules/hardware/sensor/iio.nix35
-rw-r--r--nixpkgs/nixos/modules/hardware/steam-hardware.nix32
-rw-r--r--nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix35
-rw-r--r--nixpkgs/nixos/modules/hardware/uinput.nix19
-rw-r--r--nixpkgs/nixos/modules/hardware/usb-wwan.nix39
-rw-r--r--nixpkgs/nixos/modules/hardware/video/amdgpu-pro.nix68
-rw-r--r--nixpkgs/nixos/modules/hardware/video/amdgpu.nix9
-rw-r--r--nixpkgs/nixos/modules/hardware/video/ati.nix40
-rw-r--r--nixpkgs/nixos/modules/hardware/video/bumblebee.nix93
-rw-r--r--nixpkgs/nixos/modules/hardware/video/capture/mwprocapture.nix61
-rw-r--r--nixpkgs/nixos/modules/hardware/video/displaylink.nix76
-rw-r--r--nixpkgs/nixos/modules/hardware/video/nvidia.nix271
-rw-r--r--nixpkgs/nixos/modules/hardware/video/radeon.nix3
-rw-r--r--nixpkgs/nixos/modules/hardware/video/uvcvideo/default.nix64
-rw-r--r--nixpkgs/nixos/modules/hardware/video/uvcvideo/uvcdynctrl-udev-rules.nix45
-rw-r--r--nixpkgs/nixos/modules/hardware/video/webcam/facetimehd.nix44
-rw-r--r--nixpkgs/nixos/modules/hardware/wooting.nix12
44 files changed, 2124 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/hardware/acpilight.nix b/nixpkgs/nixos/modules/hardware/acpilight.nix
new file mode 100644
index 000000000000..34e8a2220965
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/acpilight.nix
@@ -0,0 +1,24 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.hardware.acpilight;
+in
+{
+  options = {
+    hardware.acpilight = {
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Enable acpilight.
+          This will allow brightness control via xbacklight from users in the video group
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.udev.packages = with pkgs; [ acpilight ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/all-firmware.nix b/nixpkgs/nixos/modules/hardware/all-firmware.nix
new file mode 100644
index 000000000000..b07edb0f6acd
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/all-firmware.nix
@@ -0,0 +1,78 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware;
+in {
+
+  imports = [
+    (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableIntel3945ABGFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableIntel2100BGFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableRalinkFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+    (mkRenamedOptionModule [ "networking" "enableRTL8192cFirmware" ] [ "hardware" "enableRedistributableFirmware" ])
+  ];
+
+  ###### interface
+
+  options = {
+
+    hardware.enableAllFirmware = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Turn on this option if you want to enable all the firmware.
+      '';
+    };
+
+    hardware.enableRedistributableFirmware = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Turn on this option if you want to enable all the firmware with a license allowing redistribution.
+        (i.e. free firmware and <literal>firmware-linux-nonfree</literal>)
+      '';
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkMerge [
+    (mkIf (cfg.enableAllFirmware || cfg.enableRedistributableFirmware) {
+      hardware.firmware = with pkgs; [
+        firmwareLinuxNonfree
+        intel2200BGFirmware
+        rtl8192su-firmware
+        rt5677-firmware
+        rtl8723bs-firmware
+        rtlwifi_new-firmware
+        zd1211fw
+        alsa-firmware
+        sof-firmware
+        openelec-dvb-firmware
+      ] ++ optional (pkgs.stdenv.hostPlatform.isAarch32 || pkgs.stdenv.hostPlatform.isAarch64) raspberrypiWirelessFirmware
+        ++ optionals (versionOlder config.boot.kernelPackages.kernel.version "4.13") [
+        rtl8723bs-firmware
+      ];
+    })
+    (mkIf cfg.enableAllFirmware {
+      assertions = [{
+        assertion = !cfg.enableAllFirmware || (config.nixpkgs.config.allowUnfree or false);
+        message = ''
+          the list of hardware.enableAllFirmware contains non-redistributable licensed firmware files.
+            This requires nixpkgs.config.allowUnfree to be true.
+            An alternative is to use the hardware.enableRedistributableFirmware option.
+        '';
+      }];
+      hardware.firmware = with pkgs; [
+        broadcom-bt-firmware
+        b43Firmware_5_1_138
+        b43Firmware_6_30_163_46
+        b43FirmwareCutter
+      ] ++ optional (pkgs.stdenv.hostPlatform.isi686 || pkgs.stdenv.hostPlatform.isx86_64) facetimehd-firmware;
+    })
+  ];
+}
diff --git a/nixpkgs/nixos/modules/hardware/bladeRF.nix b/nixpkgs/nixos/modules/hardware/bladeRF.nix
new file mode 100644
index 000000000000..925443477143
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/bladeRF.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.bladeRF;
+
+in
+
+{
+  options.hardware.bladeRF = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enables udev rules for BladeRF devices. By default grants access
+        to users in the "bladerf" group. You may want to install the
+        libbladeRF package.
+      '';
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+    services.udev.packages = [ pkgs.libbladeRF ];
+    users.groups.bladerf = {};
+  };
+}
\ No newline at end of file
diff --git a/nixpkgs/nixos/modules/hardware/brillo.nix b/nixpkgs/nixos/modules/hardware/brillo.nix
new file mode 100644
index 000000000000..e970c9480998
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/brillo.nix
@@ -0,0 +1,22 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.hardware.brillo;
+in
+{
+  options = {
+    hardware.brillo = {
+      enable = mkEnableOption ''
+        Enable brillo in userspace.
+        This will allow brightness control from users in the video group.
+      '';
+    };
+  };
+
+
+  config = mkIf cfg.enable {
+    services.udev.packages = [ pkgs.brillo ];
+    environment.systemPackages = [ pkgs.brillo ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/ckb-next.nix b/nixpkgs/nixos/modules/hardware/ckb-next.nix
new file mode 100644
index 000000000000..fe0ca9f26d54
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/ckb-next.nix
@@ -0,0 +1,54 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.ckb-next;
+
+in
+  {
+    imports = [
+      (mkRenamedOptionModule [ "hardware" "ckb" "enable" ] [ "hardware" "ckb-next" "enable" ])
+      (mkRenamedOptionModule [ "hardware" "ckb" "package" ] [ "hardware" "ckb-next" "package" ])
+    ];
+
+    options.hardware.ckb-next = {
+      enable = mkEnableOption "the Corsair keyboard/mouse driver";
+
+      gid = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        example = 100;
+        description = ''
+          Limit access to the ckb daemon to a particular group.
+        '';
+      };
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.ckb-next;
+        defaultText = "pkgs.ckb-next";
+        description = ''
+          The package implementing the Corsair keyboard/mouse driver.
+        '';
+      };
+    };
+
+    config = mkIf cfg.enable {
+      environment.systemPackages = [ cfg.package ];
+
+      systemd.services.ckb-next = {
+        description = "Corsair Keyboards and Mice Daemon";
+        wantedBy = ["multi-user.target"];
+        serviceConfig = {
+          ExecStart = "${cfg.package}/bin/ckb-next-daemon ${optionalString (cfg.gid != null) "--gid=${builtins.toString cfg.gid}"}";
+          Restart = "on-failure";
+          StandardOutput = "syslog";
+        };
+      };
+    };
+
+    meta = {
+      maintainers = with lib.maintainers; [ kierdavis ];
+    };
+  }
diff --git a/nixpkgs/nixos/modules/hardware/cpu/amd-microcode.nix b/nixpkgs/nixos/modules/hardware/cpu/amd-microcode.nix
new file mode 100644
index 000000000000..621c7066bfe1
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/cpu/amd-microcode.nix
@@ -0,0 +1,29 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+
+  ###### interface
+
+  options = {
+
+    hardware.cpu.amd.updateMicrocode = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Update the CPU microcode for AMD processors.
+      '';
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf config.hardware.cpu.amd.updateMicrocode {
+    # Microcode updates must be the first item prepended in the initrd
+    boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeAmd}/amd-ucode.img" ];
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/cpu/intel-microcode.nix b/nixpkgs/nixos/modules/hardware/cpu/intel-microcode.nix
new file mode 100644
index 000000000000..acce565fd808
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/cpu/intel-microcode.nix
@@ -0,0 +1,29 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+
+  ###### interface
+
+  options = {
+
+    hardware.cpu.intel.updateMicrocode = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Update the CPU microcode for Intel processors.
+      '';
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf config.hardware.cpu.intel.updateMicrocode {
+    # Microcode updates must be the first item prepended in the initrd
+    boot.initrd.prepend = mkOrder 1 [ "${pkgs.microcodeIntel}/intel-ucode.img" ];
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/device-tree.nix b/nixpkgs/nixos/modules/hardware/device-tree.nix
new file mode 100644
index 000000000000..cf553497c89b
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/device-tree.nix
@@ -0,0 +1,56 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.deviceTree;
+in {
+  options = {
+      hardware.deviceTree = {
+        enable = mkOption {
+          default = pkgs.stdenv.hostPlatform.platform.kernelDTB or false;
+          type = types.bool;
+          description = ''
+            Build device tree files. These are used to describe the
+            non-discoverable hardware of a system.
+          '';
+        };
+
+        base = mkOption {
+          default = "${config.boot.kernelPackages.kernel}/dtbs";
+          defaultText = "\${config.boot.kernelPackages.kernel}/dtbs";
+          example = literalExample "pkgs.device-tree_rpi";
+          type = types.path;
+          description = ''
+            The package containing the base device-tree (.dtb) to boot. Contains
+            device trees bundled with the Linux kernel by default.
+          '';
+        };
+
+        overlays = mkOption {
+          default = [];
+          example = literalExample
+            "[\"\${pkgs.device-tree_rpi.overlays}/w1-gpio.dtbo\"]";
+          type = types.listOf types.path;
+          description = ''
+            A path containing device tree overlays (.dtbo) to be applied to all
+            base device-trees.
+          '';
+        };
+
+        package = mkOption {
+          default = null;
+          type = types.nullOr types.path;
+          internal = true;
+          description = ''
+            A path containing the result of applying `overlays` to `base`.
+          '';
+        };
+      };
+  };
+
+  config = mkIf (cfg.enable) {
+    hardware.deviceTree.package = if (cfg.overlays != [])
+      then pkgs.deviceTree.applyOverlays cfg.base cfg.overlays else cfg.base;
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/digitalbitbox.nix b/nixpkgs/nixos/modules/hardware/digitalbitbox.nix
new file mode 100644
index 000000000000..0888cfbef2a8
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/digitalbitbox.nix
@@ -0,0 +1,30 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.digitalbitbox;
+in
+
+{
+  options.hardware.digitalbitbox = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enables udev rules for Digital Bitbox devices.
+      '';
+    };
+
+    package = mkOption {
+      type = types.package;
+      default = pkgs.digitalbitbox;
+      defaultText = "pkgs.digitalbitbox";
+      description = "The Digital Bitbox package to use. This can be used to install a package with udev rules that differ from the defaults.";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.udev.packages = [ cfg.package ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/ksm.nix b/nixpkgs/nixos/modules/hardware/ksm.nix
new file mode 100644
index 000000000000..0938dbdc1101
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/ksm.nix
@@ -0,0 +1,38 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.ksm;
+
+in {
+  imports = [
+    (mkRenamedOptionModule [ "hardware" "enableKSM" ] [ "hardware" "ksm" "enable" ])
+  ];
+
+  options.hardware.ksm = {
+    enable = mkEnableOption "Kernel Same-Page Merging";
+    sleep = mkOption {
+      type = types.nullOr types.int;
+      default = null;
+      description = ''
+        How many milliseconds ksmd should sleep between scans.
+        Setting it to <literal>null</literal> uses the kernel's default time.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd.services.enable-ksm = {
+      description = "Enable Kernel Same-Page Merging";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "systemd-udev-settle.service" ];
+      script = ''
+        if [ -e /sys/kernel/mm/ksm ]; then
+          echo 1 > /sys/kernel/mm/ksm/run
+          ${optionalString (cfg.sleep != null) ''echo ${toString cfg.sleep} > /sys/kernel/mm/ksm/sleep_millisecs''}
+        fi
+      '';
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/ledger.nix b/nixpkgs/nixos/modules/hardware/ledger.nix
new file mode 100644
index 000000000000..41abe74315a0
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/ledger.nix
@@ -0,0 +1,14 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.ledger;
+
+in {
+  options.hardware.ledger.enable = mkEnableOption "udev rules for Ledger devices";
+
+  config = mkIf cfg.enable {
+    services.udev.packages = [ pkgs.ledger-udev-rules ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/logitech.nix b/nixpkgs/nixos/modules/hardware/logitech.nix
new file mode 100644
index 000000000000..d6f43bdddcc8
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/logitech.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.logitech;
+
+in {
+  options.hardware.logitech = {
+    enable = mkEnableOption "Logitech Devices";
+
+    enableGraphical = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Enable graphical support applications.";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    environment.systemPackages = [
+      pkgs.ltunify
+    ] ++ lib.optional cfg.enableGraphical pkgs.solaar;
+
+    # ltunifi and solaar both provide udev rules but the most up-to-date have been split
+    # out into a dedicated derivation
+    services.udev.packages = with pkgs; [ logitech-udev-rules ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/mcelog.nix b/nixpkgs/nixos/modules/hardware/mcelog.nix
new file mode 100644
index 000000000000..13ad238870c2
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/mcelog.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  meta.maintainers = with maintainers; [ grahamc ];
+  options = {
+
+    hardware.mcelog = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable the Machine Check Exception logger.
+        '';
+      };
+    };
+
+  };
+
+  config = mkIf config.hardware.mcelog.enable {
+    systemd = {
+      packages = [ pkgs.mcelog ];
+
+      services.mcelog = {
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ProtectHome = true;
+          PrivateNetwork = true;
+          PrivateTmp = true;
+        };
+      };
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/network/b43.nix b/nixpkgs/nixos/modules/hardware/network/b43.nix
new file mode 100644
index 000000000000..e63f2d04d1a6
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/network/b43.nix
@@ -0,0 +1,34 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let kernelVersion = config.boot.kernelPackages.kernel.version; in
+
+{
+
+  ###### interface
+
+  options = {
+
+    networking.enableB43Firmware = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Turn on this option if you want firmware for the NICs supported by the b43 module.
+      '';
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf config.networking.enableB43Firmware {
+    assertions = singleton
+      { assertion = lessThan 0 (builtins.compareVersions kernelVersion "3.2");
+        message = "b43 firmware for kernels older than 3.2 not packaged yet!";
+      };
+    hardware.firmware = [ pkgs.b43Firmware_5_1_138 ];
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/network/broadcom-43xx.nix b/nixpkgs/nixos/modules/hardware/network/broadcom-43xx.nix
new file mode 100644
index 000000000000..c92b7a0509d0
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/network/broadcom-43xx.nix
@@ -0,0 +1,3 @@
+{
+  hardware.enableRedistributableFirmware = true;
+}
diff --git a/nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix b/nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix
new file mode 100644
index 000000000000..17b973474c93
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/network/intel-2200bg.nix
@@ -0,0 +1,30 @@
+{ config, pkgs, lib, ... }:
+
+{
+
+  ###### interface
+
+  options = {
+
+    networking.enableIntel2200BGFirmware = lib.mkOption {
+      default = false;
+      type = lib.types.bool;
+      description = ''
+        Turn on this option if you want firmware for the Intel
+        PRO/Wireless 2200BG to be loaded automatically.  This is
+        required if you want to use this device.
+      '';
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = lib.mkIf config.networking.enableIntel2200BGFirmware {
+
+    hardware.firmware = [ pkgs.intel2200BGFirmware ];
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/network/smc-2632w/default.nix b/nixpkgs/nixos/modules/hardware/network/smc-2632w/default.nix
new file mode 100644
index 000000000000..b00286464f34
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/network/smc-2632w/default.nix
@@ -0,0 +1,9 @@
+{lib, ...}:
+
+{
+  hardware = {
+    pcmcia = {
+      firmware = [ (lib.cleanSource ./firmware) ];
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/network/smc-2632w/firmware/cis/SMC2632W-v1.02.cis b/nixpkgs/nixos/modules/hardware/network/smc-2632w/firmware/cis/SMC2632W-v1.02.cis
new file mode 100644
index 000000000000..5f13088c3735
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/network/smc-2632w/firmware/cis/SMC2632W-v1.02.cis
@@ -0,0 +1,8 @@
+  vers_1 5.0, "SMC", "SMC2632W", "Version 01.02", ""
+  manfid 0x0156, 0x0002
+  funcid network_adapter
+  cftable_entry 0x01 [default]
+    Vcc Vmin 3000mV Vmax 3300mV Iavg 300mA Ipeak 300mA
+    Idown 10mA
+    io 0x0000-0x003f [lines=6] [16bit]
+    irq mask 0xffff [level] [pulse]
diff --git a/nixpkgs/nixos/modules/hardware/network/zydas-zd1211.nix b/nixpkgs/nixos/modules/hardware/network/zydas-zd1211.nix
new file mode 100644
index 000000000000..5dd7f30ed82b
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/network/zydas-zd1211.nix
@@ -0,0 +1,5 @@
+{pkgs, ...}:
+
+{
+  hardware.firmware = [ pkgs.zd1211fw ];
+}
diff --git a/nixpkgs/nixos/modules/hardware/nitrokey.nix b/nixpkgs/nixos/modules/hardware/nitrokey.nix
new file mode 100644
index 000000000000..02e4c3f46f8d
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/nitrokey.nix
@@ -0,0 +1,41 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.nitrokey;
+
+in
+
+{
+  options.hardware.nitrokey = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enables udev rules for Nitrokey devices. By default grants access
+        to users in the "nitrokey" group. You may want to install the
+        nitrokey-app package, depending on your device and needs.
+      '';
+    };
+
+    group = mkOption {
+      type = types.str;
+      default = "nitrokey";
+      example = "wheel";
+      description = ''
+        Grant access to Nitrokey devices to users in this group.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.udev.packages = [
+      (pkgs.nitrokey-udev-rules.override (attrs:
+        { inherit (cfg) group; }
+      ))
+    ];
+    users.groups.${cfg.group} = {};
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/onlykey.nix b/nixpkgs/nixos/modules/hardware/onlykey.nix
new file mode 100644
index 000000000000..b6820fe01911
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/onlykey.nix
@@ -0,0 +1,33 @@
+{ config, lib, ... }:
+
+with lib;
+
+{
+
+  ####### interface
+
+  options = {
+
+    hardware.onlykey = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable OnlyKey device (https://crp.to/p/) support.
+        '';
+      };
+    };
+
+  };
+
+  ## As per OnlyKey's documentation piece (hhttps://docs.google.com/document/d/1Go_Rs218fKUx-j_JKhddbSVTqY6P0vQO831t2MKCJC8),
+  ## it is important to add udev rule for OnlyKey for it to work on Linux
+
+  ####### implementation
+
+  config = mkIf config.hardware.onlykey.enable {
+    services.udev.extraRules = builtin.readFile ./onlykey.udev;
+  };
+
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/onlykey.udev b/nixpkgs/nixos/modules/hardware/onlykey.udev
new file mode 100644
index 000000000000..6583530e5684
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/onlykey.udev
@@ -0,0 +1,4 @@
+ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1"
+ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", GROUP+="plugdev"
+KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", GROUP+="plugdev"
diff --git a/nixpkgs/nixos/modules/hardware/opengl.nix b/nixpkgs/nixos/modules/hardware/opengl.nix
new file mode 100644
index 000000000000..061528f4b1b5
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/opengl.nix
@@ -0,0 +1,158 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.opengl;
+
+  kernelPackages = config.boot.kernelPackages;
+
+  videoDrivers = config.services.xserver.videoDrivers;
+
+  package = pkgs.buildEnv {
+    name = "opengl-drivers";
+    paths = [ cfg.package ] ++ cfg.extraPackages;
+  };
+
+  package32 = pkgs.buildEnv {
+    name = "opengl-drivers-32bit";
+    paths = [ cfg.package32 ] ++ cfg.extraPackages32;
+  };
+
+in
+
+{
+
+  imports = [
+    (mkRenamedOptionModule [ "services" "xserver" "vaapiDrivers" ] [ "hardware" "opengl" "extraPackages" ])
+    (mkRemovedOptionModule [ "hardware" "opengl" "s3tcSupport" ] ''
+      S3TC support is now always enabled in Mesa.
+    '')
+  ];
+
+  options = {
+
+    hardware.opengl = {
+      enable = mkOption {
+        description = ''
+          Whether to enable OpenGL drivers. This is needed to enable
+          OpenGL support in X11 systems, as well as for Wayland compositors
+          like sway and Weston. It is enabled by default
+          by the corresponding modules, so you do not usually have to
+          set it yourself, only if there is no module for your wayland
+          compositor of choice. See services.xserver.enable and
+          programs.sway.enable.
+        '';
+        type = types.bool;
+        default = false;
+      };
+
+      driSupport = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Whether to enable accelerated OpenGL rendering through the
+          Direct Rendering Interface (DRI).
+        '';
+      };
+
+      driSupport32Bit = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          On 64-bit systems, whether to support Direct Rendering for
+          32-bit applications (such as Wine).  This is currently only
+          supported for the <literal>nvidia</literal> and
+          <literal>ati_unfree</literal> drivers, as well as
+          <literal>Mesa</literal>.
+        '';
+      };
+
+      package = mkOption {
+        type = types.package;
+        internal = true;
+        description = ''
+          The package that provides the OpenGL implementation.
+        '';
+      };
+
+      package32 = mkOption {
+        type = types.package;
+        internal = true;
+        description = ''
+          The package that provides the 32-bit OpenGL implementation on
+          64-bit systems. Used when <option>driSupport32Bit</option> is
+          set.
+        '';
+      };
+
+      extraPackages = mkOption {
+        type = types.listOf types.package;
+        default = [];
+        example = literalExample "with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau intel-ocl ]";
+        description = ''
+          Additional packages to add to OpenGL drivers. This can be used
+          to add OpenCL drivers, VA-API/VDPAU drivers etc.
+        '';
+      };
+
+      extraPackages32 = mkOption {
+        type = types.listOf types.package;
+        default = [];
+        example = literalExample "with pkgs.pkgsi686Linux; [ vaapiIntel libvdpau-va-gl vaapiVdpau ]";
+        description = ''
+          Additional packages to add to 32-bit OpenGL drivers on
+          64-bit systems. Used when <option>driSupport32Bit</option> is
+          set. This can be used to add OpenCL drivers, VA-API/VDPAU drivers etc.
+        '';
+      };
+
+      setLdLibraryPath = mkOption {
+        type = types.bool;
+        internal = true;
+        default = false;
+        description = ''
+          Whether the <literal>LD_LIBRARY_PATH</literal> environment variable
+          should be set to the locations of driver libraries. Drivers which
+          rely on overriding libraries should set this to true. Drivers which
+          support <literal>libglvnd</literal> and other dispatch libraries
+          instead of overriding libraries should not set this.
+        '';
+      };
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    assertions = [
+      { assertion = cfg.driSupport32Bit -> pkgs.stdenv.isx86_64;
+        message = "Option driSupport32Bit only makes sense on a 64-bit system.";
+      }
+      { assertion = cfg.driSupport32Bit -> (config.boot.kernelPackages.kernel.features.ia32Emulation or false);
+        message = "Option driSupport32Bit requires a kernel that supports 32bit emulation";
+      }
+    ];
+
+    systemd.tmpfiles.rules = [
+      "L+ /run/opengl-driver - - - - ${package}"
+      (
+        if pkgs.stdenv.isi686 then
+          "L+ /run/opengl-driver-32 - - - - opengl-driver"
+        else if cfg.driSupport32Bit then
+          "L+ /run/opengl-driver-32 - - - - ${package32}"
+        else
+          "r /run/opengl-driver-32"
+      )
+    ];
+
+    environment.sessionVariables.LD_LIBRARY_PATH = mkIf cfg.setLdLibraryPath
+      ([ "/run/opengl-driver/lib" ] ++ optional cfg.driSupport32Bit "/run/opengl-driver-32/lib");
+
+    hardware.opengl.package = mkDefault pkgs.mesa.drivers;
+    hardware.opengl.package32 = mkDefault pkgs.pkgsi686Linux.mesa.drivers;
+
+    boot.extraModulePackages = optional (elem "virtualbox" videoDrivers) kernelPackages.virtualboxGuestAdditions;
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/openrazer.nix b/nixpkgs/nixos/modules/hardware/openrazer.nix
new file mode 100644
index 000000000000..b5c3d6744142
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/openrazer.nix
@@ -0,0 +1,133 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.openrazer;
+  kernelPackages = config.boot.kernelPackages;
+
+  toPyBoolStr = b: if b then "True" else "False";
+
+  daemonExe = "${pkgs.openrazer-daemon}/bin/openrazer-daemon --config ${daemonConfFile}";
+
+  daemonConfFile = pkgs.writeTextFile {
+    name = "razer.conf";
+    text = ''
+      [General]
+      verbose_logging = ${toPyBoolStr cfg.verboseLogging}
+
+      [Startup]
+      sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled}
+      devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver}
+      mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier}
+
+      [Statistics]
+      key_statistics = ${toPyBoolStr cfg.keyStatistics}
+    '';
+  };
+
+  dbusServiceFile = pkgs.writeTextFile rec {
+    name = "org.razer.service";
+    destination = "/share/dbus-1/services/${name}";
+    text = ''
+      [D-BUS Service]
+      Name=org.razer
+      Exec=${daemonExe}
+      SystemdService=openrazer-daemon.service
+    '';
+  };
+
+  drivers = [
+    "razerkbd"
+    "razermouse"
+    "razerfirefly"
+    "razerkraken"
+    "razermug"
+    "razercore"
+  ];
+in
+{
+  options = {
+    hardware.openrazer = {
+      enable = mkEnableOption "OpenRazer drivers and userspace daemon";
+
+      verboseLogging = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable verbose logging. Logs debug messages.
+        '';
+      };
+
+      syncEffectsEnabled = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Set the sync effects flag to true so any assignment of
+          effects will work across devices.
+        '';
+      };
+
+      devicesOffOnScreensaver = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Turn off the devices when the systems screensaver kicks in.
+        '';
+      };
+
+      mouseBatteryNotifier = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Mouse battery notifier.
+        '';
+      };
+
+      keyStatistics = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Collects number of keypresses per hour per key used to
+          generate a heatmap.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    boot.extraModulePackages = [ kernelPackages.openrazer ];
+    boot.kernelModules = drivers;
+
+    # Makes the man pages available so you can succesfully run
+    # > systemctl --user help openrazer-daemon
+    environment.systemPackages = [ pkgs.python3Packages.openrazer-daemon.man ];
+
+    services.udev.packages = [ kernelPackages.openrazer ];
+    services.dbus.packages = [ dbusServiceFile ];
+
+    # A user must be a member of the plugdev group in order to start
+    # the openrazer-daemon. Therefore we make sure that the plugdev
+    # group exists.
+    users.groups.plugdev = {};
+
+    systemd.user.services.openrazer-daemon = {
+      description = "Daemon to manage razer devices in userspace";
+      unitConfig.Documentation = "man:openrazer-daemon(8)";
+        # Requires a graphical session so the daemon knows when the screensaver
+        # starts. See the 'devicesOffOnScreensaver' option.
+        wantedBy = [ "graphical-session.target" ];
+        partOf = [ "graphical-session.target" ];
+        serviceConfig = {
+          Type = "dbus";
+          BusName = "org.razer";
+          ExecStart = "${daemonExe} --foreground";
+          Restart = "always";
+      };
+    };
+  };
+
+  meta = {
+    maintainers = with lib.maintainers; [ roelvandijk ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/pcmcia.nix b/nixpkgs/nixos/modules/hardware/pcmcia.nix
new file mode 100644
index 000000000000..d7d002ae6c8a
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/pcmcia.nix
@@ -0,0 +1,59 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  pcmciaUtils = pkgs.pcmciaUtils.passthru.function {
+    inherit (config.hardware.pcmcia) firmware config;
+  };
+
+in
+
+
+{
+  ###### interface
+
+  options = {
+
+    hardware.pcmcia = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable this option to support PCMCIA card.
+        '';
+      };
+
+      firmware = mkOption {
+        type = types.listOf types.path;
+        default = [];
+        description = ''
+          List of firmware used to handle specific PCMCIA card.
+        '';
+      };
+
+      config = mkOption {
+        default = null;
+        description = ''
+          Path to the configuration file which maps the memory, IRQs
+          and ports used by the PCMCIA hardware.
+        '';
+      };
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf config.hardware.pcmcia.enable {
+
+    boot.kernelModules = [ "pcmcia" ];
+
+    services.udev.packages = [ pcmciaUtils ];
+
+    environment.systemPackages = [ pcmciaUtils ];
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/printers.nix b/nixpkgs/nixos/modules/hardware/printers.nix
new file mode 100644
index 000000000000..56b91933477d
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/printers.nix
@@ -0,0 +1,135 @@
+{ config, lib, pkgs, ... }:
+with lib;
+let
+  cfg = config.hardware.printers;
+  ppdOptionsString = options: optionalString (options != {})
+    (concatStringsSep " "
+      (mapAttrsToList (name: value: "-o '${name}'='${value}'") options)
+    );
+  ensurePrinter = p: ''
+    ${pkgs.cups}/bin/lpadmin -p '${p.name}' -E \
+      ${optionalString (p.location != null) "-L '${p.location}'"} \
+      ${optionalString (p.description != null) "-D '${p.description}'"} \
+      -v '${p.deviceUri}' \
+      -m '${p.model}' \
+      ${ppdOptionsString p.ppdOptions}
+  '';
+  ensureDefaultPrinter = name: ''
+    ${pkgs.cups}/bin/lpoptions -d '${name}'
+  '';
+
+  # "graph but not # or /" can't be implemented as regex alone due to missing lookahead support
+  noInvalidChars = str: all (c: c != "#" && c != "/") (stringToCharacters str);
+  printerName = (types.addCheck (types.strMatching "[[:graph:]]+") noInvalidChars)
+    // { description = "printable string without spaces, # and /"; };
+
+
+in {
+  options = {
+    hardware.printers = {
+      ensureDefaultPrinter = mkOption {
+        type = types.nullOr printerName;
+        default = null;
+        description = ''
+          Ensures the named printer is the default CUPS printer / printer queue.
+        '';
+      };
+      ensurePrinters = mkOption {
+        description = ''
+          Will regularly ensure that the given CUPS printers are configured as declared here.
+          If a printer's options are manually changed afterwards, they will be overwritten eventually.
+          This option will never delete any printer, even if removed from this list.
+          You can check existing printers with <command>lpstat -s</command>
+          and remove printers with <command>lpadmin -x &lt;printer-name&gt;</command>.
+          Printers not listed here can still be manually configured.
+        '';
+        default = [];
+        type = types.listOf (types.submodule {
+          options = {
+            name = mkOption {
+              type = printerName;
+              example = "BrotherHL_Workroom";
+              description = ''
+                Name of the printer / printer queue.
+                May contain any printable characters except "/", "#", and space.
+              '';
+            };
+            location = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              example = "Workroom";
+              description = ''
+                Optional human-readable location.
+              '';
+            };
+            description = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              example = "Brother HL-5140";
+              description = ''
+                Optional human-readable description.
+              '';
+            };
+            deviceUri = mkOption {
+              type = types.str;
+              example = [
+                "ipp://printserver.local/printers/BrotherHL_Workroom"
+                "usb://HP/DESKJET%20940C?serial=CN16E6C364BH"
+              ];
+              description = ''
+                How to reach the printer.
+                <command>lpinfo -v</command> shows a list of supported device URIs and schemes.
+              '';
+            };
+            model = mkOption {
+              type = types.str;
+              example = literalExample ''
+                gutenprint.''${lib.version.majorMinor (lib.getVersion pkgs.cups)}://brother-hl-5140/expert
+              '';
+              description = ''
+                Location of the ppd driver file for the printer.
+                <command>lpinfo -m</command> shows a list of supported models.
+              '';
+            };
+            ppdOptions = mkOption {
+              type = types.attrsOf types.str;
+              example = {
+                PageSize = "A4";
+                Duplex = "DuplexNoTumble";
+              };
+              default = {};
+              description = ''
+                Sets PPD options for the printer.
+                <command>lpoptions [-p printername] -l</command> shows suported PPD options for the given printer.
+              '';
+            };
+          };
+        });
+      };
+    };
+  };
+
+  config = mkIf (cfg.ensurePrinters != [] && config.services.printing.enable) {
+    systemd.services.ensure-printers = let
+      cupsUnit = if config.services.printing.startWhenNeeded then "cups.socket" else "cups.service";
+    in {
+      description = "Ensure NixOS-configured CUPS printers";
+      wantedBy = [ "multi-user.target" ];
+      requires = [ cupsUnit ];
+      # in contrast to cups.socket, for cups.service, this is actually not enough,
+      # as the cups service reports its activation before clients can actually interact with it.
+      # Because of this, commands like `lpinfo -v` will report a bad file descriptor
+      # due to the missing UNIX socket without sufficient sleep time.
+      after = [ cupsUnit ];
+
+      serviceConfig = {
+        Type = "oneshot";
+      };
+
+       # sleep 10 is required to wait until cups.service is actually initialized and has created its UNIX socket file
+      script = (optionalString (!config.services.printing.startWhenNeeded) "sleep 10\n")
+        + (concatMapStringsSep "\n" ensurePrinter cfg.ensurePrinters)
+        + optionalString (cfg.ensureDefaultPrinter != null) (ensureDefaultPrinter cfg.ensureDefaultPrinter);
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/raid/hpsa.nix b/nixpkgs/nixos/modules/hardware/raid/hpsa.nix
new file mode 100644
index 000000000000..c4977e3fd70a
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/raid/hpsa.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  hpssacli = pkgs.stdenv.mkDerivation rec {
+    pname = "hpssacli";
+    version = "2.40-13.0";
+
+    src = pkgs.fetchurl {
+      url = "https://downloads.linux.hpe.com/SDR/downloads/MCP/Ubuntu/pool/non-free/${pname}-${version}_amd64.deb";
+      sha256 = "11w7fwk93lmfw0yya4jpjwdmgjimqxx6412sqa166g1pz4jil4sw";
+    };
+
+    nativeBuildInputs = [ pkgs.dpkg ];
+
+    unpackPhase = "dpkg -x $src ./";
+
+    installPhase = ''
+      mkdir -p $out/bin $out/share/doc $out/share/man
+      mv opt/hp/hpssacli/bld/{hpssascripting,hprmstr,hpssacli} $out/bin/
+      mv opt/hp/hpssacli/bld/*.{license,txt}                   $out/share/doc/
+      mv usr/man                                               $out/share/
+
+      for file in $out/bin/*; do
+        chmod +w $file
+        patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+                 --set-rpath ${lib.makeLibraryPath [ pkgs.stdenv.cc.cc ]} \
+                 $file
+      done
+    '';
+
+    dontStrip = true;
+
+    meta = with lib; {
+      description = "HP Smart Array CLI";
+      homepage = "https://downloads.linux.hpe.com/SDR/downloads/MCP/Ubuntu/pool/non-free/";
+      license = licenses.unfreeRedistributable;
+      platforms = [ "x86_64-linux" ];
+      maintainers = with maintainers; [ volth ];
+    };
+  };
+in {
+  ###### interface
+
+  options = {
+    hardware.raid.HPSmartArray = {
+      enable = mkEnableOption "HP Smart Array kernel modules and CLI utility";
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf config.hardware.raid.HPSmartArray.enable {
+
+    boot.initrd.kernelModules = [ "sg" ]; /* hpssacli wants it */
+    boot.initrd.availableKernelModules = [ "hpsa" ];
+
+    environment.systemPackages = [ hpssacli ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/sensor/iio.nix b/nixpkgs/nixos/modules/hardware/sensor/iio.nix
new file mode 100644
index 000000000000..4c359c3b1725
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/sensor/iio.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  ###### interface
+
+  options = {
+    hardware.sensor.iio = {
+      enable = mkOption {
+        description = ''
+          Enable this option to support IIO sensors.
+
+          IIO sensors are used for orientation and ambient light
+          sensors on some mobile devices.
+        '';
+        type = types.bool;
+        default = false;
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf config.hardware.sensor.iio.enable {
+
+    boot.initrd.availableKernelModules = [ "hid-sensor-hub" ];
+
+    environment.systemPackages = with pkgs; [ iio-sensor-proxy ];
+
+    services.dbus.packages = with pkgs; [ iio-sensor-proxy ];
+    services.udev.packages = with pkgs; [ iio-sensor-proxy ];
+    systemd.packages = with pkgs; [ iio-sensor-proxy ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/steam-hardware.nix b/nixpkgs/nixos/modules/hardware/steam-hardware.nix
new file mode 100644
index 000000000000..6218c9ffbb9b
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/steam-hardware.nix
@@ -0,0 +1,32 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.steam-hardware;
+
+in
+
+{
+  options.hardware.steam-hardware = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Enable udev rules for Steam hardware such as the Steam Controller, other supported controllers and the HTC Vive";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.udev.packages = [
+      pkgs.steamPackages.steam
+    ];
+
+    # The uinput module needs to be loaded in order to trigger the udev rules
+    # defined in the steam package for setting permissions on /dev/uinput.
+    #
+    # If the udev rules are not triggered, some controllers won't work with
+    # steam.
+    boot.kernelModules = [ "uinput" ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix b/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix
new file mode 100644
index 000000000000..898eed244935
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/tuxedo-keyboard.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let 
+  cfg = config.hardware.tuxedo-keyboard;
+  tuxedo-keyboard = config.boot.kernelPackages.tuxedo-keyboard;
+in
+  {
+    options.hardware.tuxedo-keyboard = {
+      enable = mkEnableOption ''
+          Enables the tuxedo-keyboard driver.
+
+          To configure the driver, pass the options to the <option>boot.kernelParams</option> configuration.
+          There are several parameters you can change. It's best to check at the source code description which options are supported.
+          You can find all the supported parameters at: <link xlink:href="https://github.com/tuxedocomputers/tuxedo-keyboard#kernelparam" />
+
+          In order to use the <literal>custom</literal> lighting with the maximumg brightness and a color of <literal>0xff0a0a</literal> one would put pass <option>boot.kernelParams</option> like this:
+
+          <programlisting>
+          boot.kernelParams = [
+           "tuxedo_keyboard.mode=0"
+           "tuxedo_keyboard.brightness=255"
+           "tuxedo_keyboard.color_left=0xff0a0a"
+          ];
+          </programlisting>
+      '';
+    };
+
+    config = mkIf cfg.enable 
+    {
+      boot.kernelModules = ["tuxedo_keyboard"];
+      boot.extraModulePackages = [ tuxedo-keyboard ];
+    };
+  }
diff --git a/nixpkgs/nixos/modules/hardware/uinput.nix b/nixpkgs/nixos/modules/hardware/uinput.nix
new file mode 100644
index 000000000000..55e86bfa6bdb
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/uinput.nix
@@ -0,0 +1,19 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.hardware.uinput;
+in {
+  options.hardware.uinput = {
+    enable = lib.mkEnableOption "uinput support";
+  };
+
+  config = lib.mkIf cfg.enable {
+    boot.kernelModules = [ "uinput" ];
+
+    users.groups.uinput = {};
+
+    services.udev.extraRules = ''
+      SUBSYSTEM=="misc", KERNEL=="uinput", MODE="0660", GROUP="uinput", OPTIONS+="static_node=uinput"
+    '';
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/usb-wwan.nix b/nixpkgs/nixos/modules/hardware/usb-wwan.nix
new file mode 100644
index 000000000000..679a6c6497cb
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/usb-wwan.nix
@@ -0,0 +1,39 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  ###### interface
+
+  options = {
+
+    hardware.usbWwan = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Enable this option to support USB WWAN adapters.
+        '';
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf config.hardware.usbWwan.enable {
+    # Attaches device specific handlers.
+    services.udev.packages = with pkgs; [ usb-modeswitch-data ];
+
+    # Triggered by udev, usb-modeswitch creates systemd services via a
+    # template unit in the usb-modeswitch package.
+    systemd.packages = with pkgs; [ usb-modeswitch ];
+
+    # The systemd service requires the usb-modeswitch-data. The
+    # usb-modeswitch package intends to discover this via the
+    # filesystem at /usr/share/usb_modeswitch, and merge it with user
+    # configuration in /etc/usb_modeswitch.d. Configuring the correct
+    # path in the package is difficult, as it would cause a cyclic
+    # dependency.
+    environment.etc."usb_modeswitch.d".source = "${pkgs.usb-modeswitch-data}/share/usb_modeswitch";
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/amdgpu-pro.nix b/nixpkgs/nixos/modules/hardware/video/amdgpu-pro.nix
new file mode 100644
index 000000000000..ec1c8c2d57a1
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/amdgpu-pro.nix
@@ -0,0 +1,68 @@
+# This module provides the proprietary AMDGPU-PRO drivers.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  drivers = config.services.xserver.videoDrivers;
+
+  enabled = elem "amdgpu-pro" drivers;
+
+  package = config.boot.kernelPackages.amdgpu-pro;
+  package32 = pkgs.pkgsi686Linux.linuxPackages.amdgpu-pro.override { libsOnly = true; kernel = null; };
+
+  opengl = config.hardware.opengl;
+
+  kernel = pkgs.linux_4_9.override {
+    extraConfig = ''
+      KALLSYMS_ALL y
+    '';
+  };
+
+in
+
+{
+
+  config = mkIf enabled {
+
+    nixpkgs.config.xorg.abiCompat = "1.19";
+
+    services.xserver.drivers = singleton
+      { name = "amdgpu"; modules = [ package ]; display = true; };
+
+    hardware.opengl.package = package;
+    hardware.opengl.package32 = package32;
+    hardware.opengl.setLdLibraryPath = true;
+
+    boot.extraModulePackages = [ package ];
+
+    boot.kernelPackages =
+      pkgs.recurseIntoAttrs (pkgs.linuxPackagesFor kernel);
+
+    boot.blacklistedKernelModules = [ "radeon" ];
+
+    hardware.firmware = [ package ];
+
+    system.activationScripts.setup-amdgpu-pro = ''
+      mkdir -p /run/lib
+      ln -sfn ${package}/lib ${package.libCompatDir}
+      ln -sfn ${package} /run/amdgpu-pro
+    '' + optionalString opengl.driSupport32Bit ''
+      ln -sfn ${package32}/lib ${package32.libCompatDir}
+    '';
+
+    system.requiredKernelConfig = with config.lib.kernelConfig; [
+      (isYes "KALLSYMS_ALL")
+    ];
+
+    environment.etc = {
+      "amd/amdrc".source = package + "/etc/amd/amdrc";
+      "amd/amdapfxx.blb".source = package + "/etc/amd/amdapfxx.blb";
+      "gbm/gbm.conf".source = package + "/etc/gbm/gbm.conf";
+    };
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/amdgpu.nix b/nixpkgs/nixos/modules/hardware/video/amdgpu.nix
new file mode 100644
index 000000000000..42fc8fa362de
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/amdgpu.nix
@@ -0,0 +1,9 @@
+{ config, lib, ... }:
+
+with lib;
+{
+  config = mkIf (elem "amdgpu" config.services.xserver.videoDrivers) {
+    boot.blacklistedKernelModules = [ "radeon" ];
+  };
+}
+
diff --git a/nixpkgs/nixos/modules/hardware/video/ati.nix b/nixpkgs/nixos/modules/hardware/video/ati.nix
new file mode 100644
index 000000000000..06d3ea324d8d
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/ati.nix
@@ -0,0 +1,40 @@
+# This module provides the proprietary ATI X11 / OpenGL drivers.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  drivers = config.services.xserver.videoDrivers;
+
+  enabled = elem "ati_unfree" drivers;
+
+  ati_x11 = config.boot.kernelPackages.ati_drivers_x11;
+
+in
+
+{
+
+  config = mkIf enabled {
+
+    nixpkgs.config.xorg.abiCompat = "1.17";
+
+    services.xserver.drivers = singleton
+      { name = "fglrx"; modules = [ ati_x11 ]; display = true; };
+
+    hardware.opengl.package = ati_x11;
+    hardware.opengl.package32 = pkgs.pkgsi686Linux.linuxPackages.ati_drivers_x11.override { libsOnly = true; kernel = null; };
+    hardware.opengl.setLdLibraryPath = true;
+
+    environment.systemPackages = [ ati_x11 ];
+
+    boot.extraModulePackages = [ ati_x11 ];
+
+    boot.blacklistedKernelModules = [ "radeon" ];
+
+    environment.etc.ati.source = "${ati_x11}/etc/ati";
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/bumblebee.nix b/nixpkgs/nixos/modules/hardware/video/bumblebee.nix
new file mode 100644
index 000000000000..2278c7b40611
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/bumblebee.nix
@@ -0,0 +1,93 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.hardware.bumblebee;
+
+  kernel = config.boot.kernelPackages;
+
+  useNvidia = cfg.driver == "nvidia";
+
+  bumblebee = pkgs.bumblebee.override {
+    inherit useNvidia;
+    useDisplayDevice = cfg.connectDisplay;
+  };
+
+  useBbswitch = cfg.pmMethod == "bbswitch" || cfg.pmMethod == "auto" && useNvidia;
+
+  primus = pkgs.primus.override {
+    inherit useNvidia;
+  };
+
+in
+
+{
+
+  options = {
+    hardware.bumblebee = {
+
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Enable the bumblebee daemon to manage Optimus hybrid video cards.
+          This should power off secondary GPU until its use is requested
+          by running an application with optirun.
+        '';
+      };
+
+      group = mkOption {
+        default = "wheel";
+        example = "video";
+        type = types.str;
+        description = ''Group for bumblebee socket'';
+      };
+
+      connectDisplay = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Set to true if you intend to connect your discrete card to a
+          monitor. This option will set up your Nvidia card for EDID
+          discovery and to turn on the monitor signal.
+
+          Only nvidia driver is supported so far.
+        '';
+      };
+
+      driver = mkOption {
+        default = "nvidia";
+        type = types.enum [ "nvidia" "nouveau" ];
+        description = ''
+          Set driver used by bumblebeed. Supported are nouveau and nvidia.
+        '';
+      };
+
+      pmMethod = mkOption {
+        default = "auto";
+        type = types.enum [ "auto" "bbswitch" "switcheroo" "none" ];
+        description = ''
+          Set preferred power management method for unused card.
+        '';
+      };
+
+    };
+  };
+
+  config = mkIf cfg.enable {
+    boot.blacklistedKernelModules = [ "nvidia-drm" "nvidia" "nouveau" ];
+    boot.kernelModules = optional useBbswitch "bbswitch";
+    boot.extraModulePackages = optional useBbswitch kernel.bbswitch ++ optional useNvidia kernel.nvidia_x11.bin;
+
+    environment.systemPackages = [ bumblebee primus ];
+
+    systemd.services.bumblebeed = {
+      description = "Bumblebee Hybrid Graphics Switcher";
+      wantedBy = [ "multi-user.target" ];
+      before = [ "display-manager.service" ];
+      serviceConfig = {
+        ExecStart = "${bumblebee}/bin/bumblebeed --use-syslog -g ${cfg.group} --driver ${cfg.driver} --pm-method ${cfg.pmMethod}";
+      };
+    };
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/capture/mwprocapture.nix b/nixpkgs/nixos/modules/hardware/video/capture/mwprocapture.nix
new file mode 100644
index 000000000000..61bab533edaf
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/capture/mwprocapture.nix
@@ -0,0 +1,61 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.mwProCapture;
+
+  kernelPackages = config.boot.kernelPackages;
+
+in
+
+{
+
+  options.hardware.mwProCapture.enable = mkEnableOption "Magewell Pro Capture family kernel module";
+
+  config = mkIf cfg.enable {
+
+    assertions = singleton {
+      assertion = versionAtLeast kernelPackages.kernel.version "3.2";
+      message = "Magewell Pro Capture family module is not supported for kernels older than 3.2";
+    };
+
+    boot.kernelModules = [ "ProCapture" ];
+
+    environment.systemPackages = [ kernelPackages.mwprocapture ];
+
+    boot.extraModulePackages = [ kernelPackages.mwprocapture ];
+
+    boot.extraModprobeConfig = ''
+      # Set the png picture to be displayed when no input signal is detected.
+      options ProCapture nosignal_file=${kernelPackages.mwprocapture}/res/NoSignal.png
+
+      # Set the png picture to be displayed when an unsupported input signal is detected.
+      options ProCapture unsupported_file=${kernelPackages.mwprocapture}/res/Unsupported.png
+
+      # Set the png picture to be displayed when an loking input signal is detected.
+      options ProCapture locking_file=${kernelPackages.mwprocapture}/res/Locking.png
+
+      # Message signaled interrupts switch
+      #options ProCapture disable_msi=0
+
+      # Set the debug level
+      #options ProCapture debug_level=0
+
+      # Force init switch eeprom
+      #options ProCapture init_switch_eeprom=0
+
+      # Min frame interval for VIDIOC_ENUM_FRAMEINTERVALS (default: 166666(100ns))
+      #options ProCapture enum_frameinterval_min=166666
+
+      # VIDIOC_ENUM_FRAMESIZES type (1: DISCRETE; 2: STEPWISE; otherwise: CONTINUOUS )
+      #options ProCapture enum_framesizes_type=0
+
+      # Parameters for internal usage
+      #options ProCapture internal_params=""
+    '';
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/displaylink.nix b/nixpkgs/nixos/modules/hardware/video/displaylink.nix
new file mode 100644
index 000000000000..912f53da836a
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/displaylink.nix
@@ -0,0 +1,76 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  enabled = elem "displaylink" config.services.xserver.videoDrivers;
+
+  evdi = config.boot.kernelPackages.evdi;
+
+  displaylink = pkgs.displaylink.override {
+    inherit evdi;
+  };
+
+in
+
+{
+
+  config = mkIf enabled {
+
+    boot.extraModulePackages = [ evdi ];
+    boot.kernelModules = [ "evdi" ];
+
+    environment.etc."X11/xorg.conf.d/40-displaylink.conf".text = ''
+      Section "OutputClass"
+        Identifier  "DisplayLink"
+        MatchDriver "evdi"
+        Driver      "modesetting"
+        Option      "AccelMethod" "none"
+      EndSection
+    '';
+
+    # make the device available
+    services.xserver.displayManager.sessionCommands = ''
+      ${lib.getBin pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource 1 0
+    '';
+
+    # Those are taken from displaylink-installer.sh and from Arch Linux AUR package.
+
+    services.udev.packages = [ displaylink ];
+
+    powerManagement.powerDownCommands = ''
+      #flush any bytes in pipe
+      while read -n 1 -t 1 SUSPEND_RESULT < /tmp/PmMessagesPort_out; do : ; done;
+
+      #suspend DisplayLinkManager
+      echo "S" > /tmp/PmMessagesPort_in
+
+      #wait until suspend of DisplayLinkManager finish
+      if [ -f /tmp/PmMessagesPort_out ]; then
+        #wait until suspend of DisplayLinkManager finish
+        read -n 1 -t 10 SUSPEND_RESULT < /tmp/PmMessagesPort_out
+      fi
+    '';
+
+    powerManagement.resumeCommands = ''
+      #resume DisplayLinkManager
+      echo "R" > /tmp/PmMessagesPort_in
+    '';
+
+    systemd.services.dlm = {
+      description = "DisplayLink Manager Service";
+      after = [ "display-manager.service" ];
+      conflicts = [ "getty@tty7.service" ];
+
+      serviceConfig = {
+        ExecStart = "${displaylink}/bin/DisplayLinkManager";
+        Restart = "always";
+        RestartSec = 5;
+        LogsDirectory = "displaylink";
+      };
+    };
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/nvidia.nix b/nixpkgs/nixos/modules/hardware/video/nvidia.nix
new file mode 100644
index 000000000000..8c3d64fceb9c
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/nvidia.nix
@@ -0,0 +1,271 @@
+# This module provides the proprietary NVIDIA X11 / OpenGL drivers.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  drivers = config.services.xserver.videoDrivers;
+
+  # FIXME: should introduce an option like
+  # ‘hardware.video.nvidia.package’ for overriding the default NVIDIA
+  # driver.
+  nvidiaForKernel = kernelPackages:
+    if elem "nvidia" drivers then
+        kernelPackages.nvidia_x11
+    else if elem "nvidiaBeta" drivers then
+        kernelPackages.nvidia_x11_beta
+    else if elem "nvidiaLegacy304" drivers then
+      kernelPackages.nvidia_x11_legacy304
+    else if elem "nvidiaLegacy340" drivers then
+      kernelPackages.nvidia_x11_legacy340
+    else if elem "nvidiaLegacy390" drivers then
+      kernelPackages.nvidia_x11_legacy390
+    else null;
+
+  nvidia_x11 = nvidiaForKernel config.boot.kernelPackages;
+  nvidia_libs32 =
+    if versionOlder nvidia_x11.version "391" then
+      ((nvidiaForKernel pkgs.pkgsi686Linux.linuxPackages).override { libsOnly = true; kernel = null; }).out
+    else
+      (nvidiaForKernel config.boot.kernelPackages).lib32;
+
+  enabled = nvidia_x11 != null;
+
+  cfg = config.hardware.nvidia;
+
+  pCfg = cfg.prime;
+  syncCfg = pCfg.sync;
+  offloadCfg = pCfg.offload;
+  primeEnabled = syncCfg.enable || offloadCfg.enable;
+  nvidiaPersistencedEnabled =  cfg.nvidiaPersistenced;
+in
+
+{
+  imports =
+    [
+      (mkRenamedOptionModule [ "hardware" "nvidia" "optimus_prime" "enable" ] [ "hardware" "nvidia" "prime" "sync" "enable" ])
+      (mkRenamedOptionModule [ "hardware" "nvidia" "optimus_prime" "allowExternalGpu" ] [ "hardware" "nvidia" "prime" "sync" "allowExternalGpu" ])
+      (mkRenamedOptionModule [ "hardware" "nvidia" "optimus_prime" "nvidiaBusId" ] [ "hardware" "nvidia" "prime" "nvidiaBusId" ])
+      (mkRenamedOptionModule [ "hardware" "nvidia" "optimus_prime" "intelBusId" ] [ "hardware" "nvidia" "prime" "intelBusId" ])
+    ];
+
+  options = {
+    hardware.nvidia.modesetting.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enable kernel modesetting when using the NVIDIA proprietary driver.
+
+        Enabling this fixes screen tearing when using Optimus via PRIME (see
+        <option>hardware.nvidia.prime.sync.enable</option>. This is not enabled
+        by default because it is not officially supported by NVIDIA and would not
+        work with SLI.
+      '';
+    };
+
+    hardware.nvidia.prime.nvidiaBusId = mkOption {
+      type = types.str;
+      default = "";
+      example = "PCI:1:0:0";
+      description = ''
+        Bus ID of the NVIDIA GPU. You can find it using lspci; for example if lspci
+        shows the NVIDIA GPU at "01:00.0", set this option to "PCI:1:0:0".
+      '';
+    };
+
+    hardware.nvidia.prime.intelBusId = mkOption {
+      type = types.str;
+      default = "";
+      example = "PCI:0:2:0";
+      description = ''
+        Bus ID of the Intel GPU. You can find it using lspci; for example if lspci
+        shows the Intel GPU at "00:02.0", set this option to "PCI:0:2:0".
+      '';
+    };
+
+    hardware.nvidia.prime.sync.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enable NVIDIA Optimus support using the NVIDIA proprietary driver via PRIME.
+        If enabled, the NVIDIA GPU will be always on and used for all rendering,
+        while enabling output to displays attached only to the integrated Intel GPU
+        without a multiplexer.
+
+        Note that this option only has any effect if the "nvidia" driver is specified
+        in <option>services.xserver.videoDrivers</option>, and it should preferably
+        be the only driver there.
+
+        If this is enabled, then the bus IDs of the NVIDIA and Intel GPUs have to be
+        specified (<option>hardware.nvidia.prime.nvidiaBusId</option> and
+        <option>hardware.nvidia.prime.intelBusId</option>).
+
+        If you enable this, you may want to also enable kernel modesetting for the
+        NVIDIA driver (<option>hardware.nvidia.modesetting.enable</option>) in order
+        to prevent tearing.
+
+        Note that this configuration will only be successful when a display manager
+        for which the <option>services.xserver.displayManager.setupCommands</option>
+        option is supported is used.
+      '';
+    };
+
+    hardware.nvidia.prime.sync.allowExternalGpu = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Configure X to allow external NVIDIA GPUs when using optimus.
+      '';
+    };
+
+    hardware.nvidia.prime.offload.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Enable render offload support using the NVIDIA proprietary driver via PRIME.
+
+        If this is enabled, then the bus IDs of the NVIDIA and Intel GPUs have to be
+        specified (<option>hardware.nvidia.prime.nvidiaBusId</option> and
+        <option>hardware.nvidia.prime.intelBusId</option>).
+      '';
+    };
+
+    hardware.nvidia.nvidiaPersistenced = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Update for NVIDA GPU headless mode, i.e. nvidia-persistenced. It ensures all
+        GPUs stay awake even during headless mode.
+      '';
+    };
+  };
+
+  config = mkIf enabled {
+    assertions = [
+      {
+        assertion = with config.services.xserver.displayManager; gdm.nvidiaWayland -> cfg.modesetting.enable;
+        message = "You cannot use wayland with GDM without modesetting enabled for NVIDIA drivers, set `hardware.nvidia.modesetting.enable = true`";
+      }
+
+      {
+        assertion = primeEnabled -> pCfg.nvidiaBusId != "" && pCfg.intelBusId != "";
+        message = ''
+          When NVIDIA PRIME is enabled, the GPU bus IDs must configured.
+        '';
+      }
+      {
+        assertion = offloadCfg.enable -> versionAtLeast nvidia_x11.version "435.21";
+        message = "NVIDIA PRIME render offload is currently only supported on versions >= 435.21.";
+      }
+      {
+        assertion = !(syncCfg.enable && offloadCfg.enable);
+        message = "Only one NVIDIA PRIME solution may be used at a time.";
+      }
+    ];
+
+    # If Optimus/PRIME is enabled, we:
+    # - Specify the configured NVIDIA GPU bus ID in the Device section for the
+    #   "nvidia" driver.
+    # - Add the AllowEmptyInitialConfiguration option to the Screen section for the
+    #   "nvidia" driver, in order to allow the X server to start without any outputs.
+    # - Add a separate Device section for the Intel GPU, using the "modesetting"
+    #   driver and with the configured BusID.
+    # - Reference that Device section from the ServerLayout section as an inactive
+    #   device.
+    # - Configure the display manager to run specific `xrandr` commands which will
+    #   configure/enable displays connected to the Intel GPU.
+
+    services.xserver.useGlamor = mkDefault offloadCfg.enable;
+
+    services.xserver.drivers = optional primeEnabled {
+      name = "modesetting";
+      display = offloadCfg.enable;
+      deviceSection = ''
+        BusID "${pCfg.intelBusId}"
+        ${optionalString syncCfg.enable ''Option "AccelMethod" "none"''}
+      '';
+    } ++ singleton {
+      name = "nvidia";
+      modules = [ nvidia_x11.bin ];
+      display = !offloadCfg.enable;
+      deviceSection = optionalString primeEnabled
+        ''
+          BusID "${pCfg.nvidiaBusId}"
+          ${optionalString syncCfg.allowExternalGpu "Option \"AllowExternalGpus\""}
+        '';
+      screenSection =
+        ''
+          Option "RandRRotation" "on"
+          ${optionalString syncCfg.enable "Option \"AllowEmptyInitialConfiguration\""}
+        '';
+    };
+
+    services.xserver.serverLayoutSection = optionalString syncCfg.enable ''
+      Inactive "Device-modesetting[0]"
+    '' + optionalString offloadCfg.enable ''
+      Option "AllowNVIDIAGPUScreens"
+    '';
+
+    services.xserver.displayManager.setupCommands = optionalString syncCfg.enable ''
+      # Added by nvidia configuration module for Optimus/PRIME.
+      ${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource modesetting NVIDIA-0
+      ${pkgs.xorg.xrandr}/bin/xrandr --auto
+    '';
+
+    environment.etc."nvidia/nvidia-application-profiles-rc" = mkIf nvidia_x11.useProfiles {
+      source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc";
+    };
+
+    hardware.opengl.package = mkIf (!offloadCfg.enable) nvidia_x11.out;
+    hardware.opengl.package32 = mkIf (!offloadCfg.enable) nvidia_libs32;
+    hardware.opengl.extraPackages = optional offloadCfg.enable nvidia_x11.out;
+    hardware.opengl.extraPackages32 = optional offloadCfg.enable nvidia_libs32;
+
+    environment.systemPackages = [ nvidia_x11.bin nvidia_x11.settings ]
+      ++ filter (p: p != null) [ nvidia_x11.persistenced ];
+
+    systemd.tmpfiles.rules = optional config.virtualisation.docker.enableNvidia
+        "L+ /run/nvidia-docker/bin - - - - ${nvidia_x11.bin}/origBin"
+      ++ optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia)
+        "L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced";
+
+    systemd.services."nvidia-persistenced" = mkIf nvidiaPersistencedEnabled {
+      description = "NVIDIA Persistence Daemon";
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        Type = "forking";
+        Restart = "always";
+        PIDFile = "/var/run/nvidia-persistenced/nvidia-persistenced.pid";
+        ExecStart = "${nvidia_x11.persistenced}/bin/nvidia-persistenced --verbose";
+        ExecStopPost = "${pkgs.coreutils}/bin/rm -rf /var/run/nvidia-persistenced";
+      };
+    };
+
+    boot.extraModulePackages = [ nvidia_x11.bin ];
+
+    # nvidia-uvm is required by CUDA applications.
+    boot.kernelModules = [ "nvidia-uvm" ] ++
+      optionals config.services.xserver.enable [ "nvidia" "nvidia_modeset" "nvidia_drm" ];
+
+    # If requested enable modesetting via kernel parameter.
+    boot.kernelParams = optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1";
+
+    # Create /dev/nvidia-uvm when the nvidia-uvm module is loaded.
+    services.udev.extraRules =
+      ''
+        KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) 255'"
+        KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) 254'"
+        KERNEL=="card*", SUBSYSTEM=="drm", DRIVERS=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia%n c $$(grep nvidia-frontend /proc/devices | cut -d \  -f 1) %n'"
+        KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 0'"
+        KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 0'"
+      '';
+
+    boot.blacklistedKernelModules = [ "nouveau" "nvidiafb" ];
+
+    services.acpid.enable = true;
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/radeon.nix b/nixpkgs/nixos/modules/hardware/video/radeon.nix
new file mode 100644
index 000000000000..c92b7a0509d0
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/radeon.nix
@@ -0,0 +1,3 @@
+{
+  hardware.enableRedistributableFirmware = true;
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/uvcvideo/default.nix b/nixpkgs/nixos/modules/hardware/video/uvcvideo/default.nix
new file mode 100644
index 000000000000..7e3e94fdf2bd
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/uvcvideo/default.nix
@@ -0,0 +1,64 @@
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.uvcvideo;
+
+  uvcdynctrl-udev-rules = packages: pkgs.callPackage ./uvcdynctrl-udev-rules.nix {
+    drivers = packages;
+    udevDebug = false;
+  };
+
+in
+
+{
+
+  options = {
+    services.uvcvideo.dynctrl = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable <command>uvcvideo</command> dynamic controls.
+
+          Note that enabling this brings the <command>uvcdynctrl</command> tool
+          into your environement and register all dynamic controls from
+          specified <command>packages</command> to the <command>uvcvideo</command> driver.
+        '';
+      };
+
+      packages = mkOption {
+        type = types.listOf types.path;
+        example = literalExample "[ pkgs.tiscamera ]";
+        description = ''
+          List of packages containing <command>uvcvideo</command> dynamic controls
+          rules. All files found in
+          <filename><replaceable>pkg</replaceable>/share/uvcdynctrl/data</filename>
+          will be included.
+
+          Note that these will serve as input to the <command>libwebcam</command>
+          package which through its own <command>udev</command> rule will register
+          the dynamic controls from specified packages to the <command>uvcvideo</command>
+          driver.
+        '';
+        apply = map getBin;
+      };
+    };
+  };
+
+  config = mkIf cfg.dynctrl.enable {
+
+    services.udev.packages = [
+      (uvcdynctrl-udev-rules cfg.dynctrl.packages)
+    ];
+
+    environment.systemPackages = [
+      pkgs.libwebcam
+    ];
+
+  };
+}
diff --git a/nixpkgs/nixos/modules/hardware/video/uvcvideo/uvcdynctrl-udev-rules.nix b/nixpkgs/nixos/modules/hardware/video/uvcvideo/uvcdynctrl-udev-rules.nix
new file mode 100644
index 000000000000..a808429c9996
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/uvcvideo/uvcdynctrl-udev-rules.nix
@@ -0,0 +1,45 @@
+{ buildEnv
+, libwebcam
+, makeWrapper
+, runCommand
+, drivers ? []
+, udevDebug ? false
+}:
+
+let
+  version = "0.0.0";
+
+  dataPath = buildEnv {
+    name = "uvcdynctrl-with-drivers-data-path";
+    paths = drivers ++ [ libwebcam ];
+    pathsToLink = [ "/share/uvcdynctrl/data" ];
+    ignoreCollisions = false;
+  };
+
+  dataDir = "${dataPath}/share/uvcdynctrl/data";
+  udevDebugVarValue = if udevDebug then "1" else "0";
+in
+
+runCommand "uvcdynctrl-udev-rules-${version}"
+{
+  inherit dataPath;
+  buildInputs = [
+    makeWrapper
+    libwebcam
+  ];
+  dontPatchELF = true;
+  dontStrip = true;
+  preferLocalBuild = true;
+}
+''
+  mkdir -p "$out/lib/udev"
+  makeWrapper "${libwebcam}/lib/udev/uvcdynctrl" "$out/lib/udev/uvcdynctrl" \
+    --set NIX_UVCDYNCTRL_DATA_DIR "${dataDir}" \
+    --set NIX_UVCDYNCTRL_UDEV_DEBUG "${udevDebugVarValue}"
+
+  mkdir -p "$out/lib/udev/rules.d"
+  cat "${libwebcam}/lib/udev/rules.d/80-uvcdynctrl.rules" | \
+    sed -r "s#RUN\+\=\"([^\"]+)\"#RUN\+\=\"$out/lib/udev/uvcdynctrl\"#g" > \
+    "$out/lib/udev/rules.d/80-uvcdynctrl.rules"
+''
+
diff --git a/nixpkgs/nixos/modules/hardware/video/webcam/facetimehd.nix b/nixpkgs/nixos/modules/hardware/video/webcam/facetimehd.nix
new file mode 100644
index 000000000000..d311f600c319
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/video/webcam/facetimehd.nix
@@ -0,0 +1,44 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.hardware.facetimehd;
+
+  kernelPackages = config.boot.kernelPackages;
+
+in
+
+{
+
+  options.hardware.facetimehd.enable = mkEnableOption "facetimehd kernel module";
+
+  config = mkIf cfg.enable {
+
+    assertions = singleton {
+      assertion = versionAtLeast kernelPackages.kernel.version "3.19";
+      message = "facetimehd is not supported for kernels older than 3.19";
+    };
+
+    boot.kernelModules = [ "facetimehd" ];
+
+    boot.blacklistedKernelModules = [ "bdc_pci" ];
+
+    boot.extraModulePackages = [ kernelPackages.facetimehd ];
+
+    hardware.firmware = [ pkgs.facetimehd-firmware ];
+
+    # unload module during suspend/hibernate as it crashes the whole system
+    powerManagement.powerDownCommands = ''
+      ${pkgs.kmod}/bin/lsmod | ${pkgs.gnugrep}/bin/grep -q "^facetimehd" && ${pkgs.kmod}/bin/rmmod -f -v facetimehd
+    '';
+
+    # and load it back on resume
+    powerManagement.resumeCommands = ''
+      ${pkgs.kmod}/bin/modprobe -v facetimehd
+    '';
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/hardware/wooting.nix b/nixpkgs/nixos/modules/hardware/wooting.nix
new file mode 100644
index 000000000000..ee550cbbf6b8
--- /dev/null
+++ b/nixpkgs/nixos/modules/hardware/wooting.nix
@@ -0,0 +1,12 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+{
+  options.hardware.wooting.enable =
+    mkEnableOption "Enable support for Wooting keyboards";
+
+  config = mkIf config.hardware.wooting.enable {
+    environment.systemPackages = [ pkgs.wootility ];
+    services.udev.packages = [ pkgs.wooting-udev-rules ];
+  };
+}