Brightness control of external monitors with ddcci-backlight

I have a desktop connected to two external monitors. I usually change the brightness and contrast of these monitors multiple times a day and I’d like to have an easy way to change the brightness and contrast.

So far, I’ve mostly been following the answers on this stackexchange question. Using this answer I was able to some scripts to change the brightness and contrast.

However, I’d rather have a slider I can adjust. This other answer states that the ddcci-backlight module should enable the brightness slider:

The DDC/CI kernel module includes a ddcci-backlight module which can integrate most DDC/CI-capable monitors into the kernel’s backlight system ( /sys/class/backlight ). This allows any tool which can use the latter to drive the backlight on a DDC/CI monitor.

The Arch Linux wiki states something similar:

Alternatively, one may use ddcci-driver-linux-dkmsAUR to expose external monitors in sysfs. Then, after loading the ddcci kernel module, one can use any backlight utility.

After some googling I found the ddcci-driver kernel module, which I enabled by including
boot.extraModulePackages = with config.boot.kernelPackages; [ ddcci-driver ];

in my configuration.nix. However, this doesn’t change anything. No slider shows up in the power management, and when I install acpilight and try to change the brightness it seems to have no effect. Also, when I list the devices no monitor seems to show up:

ruben@nixos> sudo xbacklight -l                                                                                   ~
input0::compose
input0::scrolllock
input0::kana
input0::capslock
input0::numlock

I haven’t done anything with kernel modules before and it feels like I’m missing steps here. Is there anyone who got brightness control for external monitors working on NixOS? I can’t imagine that I’m the only one who wants this, yet I can barely find any information on it.

do you know about services.redshift = { enable = true; };
(you can control brightness between day and night)

redshift is about changing the color temperature - not the brightness.

@ruben, if you’re using KDE, it’s possible to do directly from KDE since https://github.com/NixOS/nixpkgs/pull/88942

1 Like

Redshift has a brightness adjustment setting but it does not work the way most people might expect. In fact it is a fake brightness adjustment obtained by manipulating the gamma ramps which means that it does not reduce the backlight of the screen. Preferably only use it if your normal backlight adjustment is too coarse-grained

well, how to check which tools is doing it?

Indeed I’m using KDE, so that’s great news, thanks :slight_smile:

Could you elaborate on how I can enable it? From the code you merged to master I would say I should put

services.xserver.desktopManager.plasma5.supportDDC = true;

in my configuration.nix file, but this doesn’t work. Maybe I need a newer version of the KDE (or at least the configuration file). Not sure, I’m not so experienced with NixOS…

services.xserver.desktopManager.plasma5.supportDDC = true;

Yep, that’s it.

Then click “Battery and Brightness” in the tray and you should see a slider for “Display Brightness”.

Please note that if you have multiple monitors, you will be setting the brightness on both.

Thanks, but I get a ‘option does not exist’ error:

ruben@nixos> sudo nixos-rebuild switch                                                               ~
building Nix...
building the system configuration...
error: The option `services.xserver.desktopManager.plasma5.supportDDC' defined in `/etc/nixos/configuration.nix' does not exist.
(use '--show-trace' to show detailed location information)

I guess I somehow need to update something?

Ah, that bit is only in unstable. If you’re on the 20.03 (and want to stay on a release channel), you’ll have to wait for 20.09. Alternatively, you can just switch to unstable which is what I’m doing on on workstations.

1 Like

For me, the issue was that the proprietary nvidia driver doesn’t work correctly with ddcci. I found a way to force the display to be detected by the ddcci driver correctly. But you have to wait until after the i2c device shows up before you can force it, and the kernel module has to be loaded after that. Since I couldn’t find a proper systemd dependency to do this at the right time, I just threw the necessary commands in displayManager.setupCommands.

{ config, pkgs, ... }: {
  boot.extraModulePackages = [config.boot.kernelPackages.ddcci-driver];
  services.xserver.displayManager.setupCommands = ''
    echo 'ddcci 0x37' | tee /sys/bus/i2c/devices/i2c-5/new_device
    ${pkgs.kmod}/bin/modprobe ddcci_backlight
  '';
}

Where i2c-5 is the i2c device for my display. Also, plasma5.supportDDC = true; enables i2c-dev, and note from the Arch wiki:

Using ddcci and i2c-dev simultaneously may result in resource conflicts such as a Device or resource busy error.

Following the instructions from this stackoverflow answer, I ran

sudo nix-channel --add https://nixos.org/channels/nixos-unstable nixos
sudo nixos-rebuild switch --upgrade

I then added the line

services.xserver.desktopManager.plasma5.supportDDC = true;

to my configuration.nix. After running

sudo nixos-rebuild switch

and restarting (I think logging out and in again should work as well), it works! :slight_smile:

@peterhoeg Thank you so much! You have no idea how much time I spent trying to get this working (in fact I gave up several times) :slight_smile:

Do you need the ddcci-driver for things to work in KDE or is that for a different use-case?

No, you’re right; It’s not necessary. I have removed it from my last post.