Posts Setting up External Monitor Brightness Controls on Arch Linux
Post
Cancel

Setting up External Monitor Brightness Controls on Arch Linux

This will be the first technical post on my website. I will use this post to describe the process in setting up external brightness control in Sway on Arch Linux.

Background

Kernel 5.9 added improved I2C support to Navi 10 cards1, which include the Radeon RX 5600XT. Using I2C in combination with ddcutil can allow us to control an external monitors brightness using commands.

Using ddcutil

Detecting Monitors

First we need to make sure that the i2c-dev module is loaded into the system; In my case, it was loaded automatically. We now want to identify the monitors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ddcutil detect
Display 1
   I2C bus:             /dev/i2c-5
   EDID synopsis:
      Mfg id:           GSM
      Model:            LG QHD
      Serial number:
      Manufacture year: 2020
      EDID version:     1.4
   VCP version:         2.1

Display 2
   I2C bus:             /dev/i2c-6
   EDID synopsis:
      Mfg id:           DEL
      Model:            DELL P2014H
      Serial number:    J6HFT3B9AK7L
      Manufacture year: 2013
      EDID version:     1.4
   VCP version:         2.1

The monitor I am interested in is the LG QHD, with a bus number of 5. ddcutil can change various properties of connected monitors, we are only interested i brightness right now.

We want to get current brightness value. We can use the ddcutil getvcp command to get our current value. The id for brightness is 10, so we can get our brightness value:

1
2
# ddcutil --bus 5 getvcp 10
VCP code 0x10 (Brightness                    ): current value =   100, max value =   100

We can see that the range for the brightness on this monitor is 0 to 100.

Adjusting Brightness

We can change the brightness by using the ddcutil setvcp command. We also need to use the --bus parameter to specify which monitor we want to adjust. For example, to set the brightness to 50:

1
# ddcutil --bus 5 setvcp 10 50

Brightness can also be set relatively:

1
# ddcutil --bus 5 setvcp 10 - 5

lowers the brightness by 5. The - can be replaced with a + to increase the brightness instead.

Now that we know the commands, we can now figure out how to bind the command to a shortcut in our display manager, which is Sway in my case.

There is a problem: all the commands we have run require root access, we don’t have access to /dev/i2c-5.

1
2
3
$ ddcutil --bus 5 setvcp 10 - 5
Open failed for /dev/i2c-5: errno=EACCES(13): Permission denied
No monitor detected on I2C bus /dev/i2c-5

Permitting user access to /dev/i2c-*

I follow the instructions layed out here. Here is a summary:

Create group i2c:

1
# groupadd i2c

Add your user to i2c group:

1
# usermod -aG i2c lsanche

Create a udev rule to make the changes permanent:

1
# echo 'KERNEL=="i2c-[0-9]*", GROUP="i2c"' >> /etc/udev/rules.d/10-local_i2c_group.rules

Reboot and test it out.

When I attempt to change the brightness command again as a non-root user, it is now successful.

Now it is time to implement the shortcuts into Sway.

Setting Up Sway Shortcuts

This part is quick and easy. I wanted to be able to hold the Windows key and press F11 or F12 to adjust brightness, so this is what I put into my Sway config:

1
2
3
4
5
### Brightness Controls ###
bindsym $mod+F12 exec ddcutil --bus 5 setvcp 10 + 10
bindsym $mod+F11 exec ddcutil --bus 5 setvcp 10 - 10
bindsym ctrl+$mod+F12 exec ddcutil --bus 5 setvcp 10 100
bindsym ctrl+$mod+F11 exec ddcutil --bus 5 setvcp 10 0

You can see I have also added the same combos, but with the control key added as I wanted a way to quickly make the monitor the brightest or darkest as possible.

And that’s it! Enjoy your new DIY brightness controls for your external monitor.

  1. Commit adding this support can be found here

This post is licensed under CC BY 4.0 by the author.