I’ve been LOVING NixOS so far and have figured everything out except this LAST issue of being able to control my external monitor’s brightness from the computer. I know this is done with ddcutil and I’ve successfully got this working on Arch and PopOS, but i’m lost as to how to set this up in Nix.
This makes the display brightness work the same as if it were a laptop backlight, so the brightness controls on my keyboard work. No extension required. The important part is the ddcci_backlight kernel module, which is supposed to be all you need, but due to a bug in Nvidia’s drivers, I had to add the udev rule and systemd service.
This is really interesting! I wonder how it works on a docked laptop that I sometimes need ddc when docked, but sometimes internal when used as a laptop
Ok, thanks to some digging AND feedback here, i’ve got it working on rebuild and boot. Basically just add these lines to the config. (one loads the kernel module, the other sets the udev rules)
running under NixOS; I knew the answer would be something with udev rules but (at the time) didn’t know how to look further, and then totally forgot about it.
I still have had to manually do echo ddcci 0x37 > /sys/bus/i2c/devices/$dev/new_device on rare occasion, but I no longer need to have it automatically run. I guess AMD’s driver just handles this a little bit better.
That’s a good find, thanks for sharing. Though I just tested it with nixos-unstable and rebooted and it works as expected for me with just hardware.i2c.enable = true;
$ whoami
username
$ groups
users wheel video networkmanager scanner docker input qemu-libvirtd
$ ls -l /dev/i2c-7
crw-rw----+ 1 root i2c 89, 7 Mar 10 11:56 /dev/i2c-7
$ getfacl /dev/i2c-7
getfacl: Removing leading '/' from absolute path names
# file: dev/i2c-7
# owner: root
# group: i2c
user::rw-
user:username:rw-
group::rw-
mask::rw-
other::---
$ ddcutil detect
Display 1
I2C bus: /dev/i2c-7
DRM connector: card0-DP-1
EDID synopsis:
Mfg id: DEL - Dell Inc.
Model: DELL xyz
Product code: xyz (xyz)
Serial number: xyz
Binary serial number: xyz (xyz)
Manufacture year: 2020, Week: 40
VCP version: 2.1
IIUC modifying services.udev.extraRules shouldn’t be necessary:
ddcutil includes a lib/udev/rules.d/60-ddcutil-i2c.rules file containing SUBSYSTEM=="i2c-dev", KERNEL=="i2c-[0-9]*", ATTRS{class}=="0x030000", TAG+="uaccess"
This file seems to be linked as /nix/var/nix/profiles/system/etc/profiles/per-user/USERNAME/lib/udev/rules.d/60-ddcutil-i2c.rules (I installed in users.users.<name>.packages), which I believe means it’s included in the udev rules automatically.
On the other hand, trying a command from this post, sudo udevadm test $(sudo udevadm info -q path -n i2c-7), listed it reading a lot of files, but not the ddcutil one…
I don’t think I’d call it a bug… Like, we don’t include systemd units from a package unless it’s in systemd.packages. These are just things that should not be implicit.
This is why we very often have programs.foo.enable. To get it to do its thing correctly. environment.systemPackages literally just means “link things in /run/current-system/sw” and nothing else.