Adjusting acpi_video brightness increments on FreeBSD

March 12, 2020

On FreeBSD systems using Intel integrated graphics, intel-backlight allows the brightness to be set in nice increments using the incr and decr arguments. Alternatively, the acpi_video kernel module can also control brightness, but changes it by one-percent increments for each press of the brightness up/down Fn keys. My goal was to configure acpi_video to follow the behaviour of intel-backlight .

On my ThinkPad T480 (FreeBSD 12.1-RELEASE), I had previously used acpi_ibm and devd to call intel-backlight when pressing the corresponding Fn keys, without loading acpi_video . Downsides of this approach were that brightness would go to 100% when plugging in the AC adapter, resuming from suspend, or waking the screen from dpms sleep in X11. Alternatively, simply loading the acpi_video module would fix these issues, but brightness control was very slow because of the small adjustment increments.

The source code for intel-backlight shows the increments used by the tool. I created a simple shell script to set the display brightness according to these levels. If called with "1" as the argument, brightness will be increased; if called with "0" as the argument, it will be decreased:

#!/bin/sh

# /usr/local/bin/acpi_brightness_control.sh

CURRENT_LEVEL=$(/sbin/sysctl -n hw.acpi.video.lcd0.brightness)

UP="$1"



if [ "$UP" == 1 ]; then

for i in 1 2 4 6 9 12 16 20 25 30 36 43 51 60 70 80 90 100; do

if [ "$CURRENT_LEVEL" -lt "$i" ]; then

/sbin/sysctl "hw.acpi.video.lcd0.brightness=$i"

exit

fi

done

fi



if [ "$UP" == 0 ]; then

for i in 100 90 80 70 60 51 43 36 30 25 20 16 12 9 6 4 2 1; do

if [ "$CURRENT_LEVEL" -gt "$i" ]; then

/sbin/sysctl "hw.acpi.video.lcd0.brightness=$i"

exit

fi

done

fi

I load acpi_ibm and acpi_video in /boot/loader.conf . On my machine, the brightness Fn keys give event codes 0x10 and 0x11 (can be seen using sudo cat /var/run/devd.pipe ). To handle these keys with devd , I set dev.acpi_ibm.0.handlerevents=0x10\ 0x11 in /etc/sysctl.conf .

To handle the brightness keys, I create /etc/devd/acpi_brightness.conf :

# /etc/devd/acpi_brightness.conf

notify 20 {

match "system" "ACPI";

match "subsystem" "IBM";

match "notify" "0x10";

action "/usr/local/bin/acpi_brightness_control.sh 1";

};

notify 20 {

match "system" "ACPI";

match "subsystem" "IBM";

match "notify" "0x11";

action "/usr/local/bin/acpi_brightness_control.sh 0";

}

Again, the specific match criteria necessary for the keys on a different machine can be observed by pressing the keys while watching the output of sudo cat /var/run/devd.pipe .

Finally, restart devd ( sudo service devd restart ) to apply the new rule.

Note also that the default brightness on battery or line power can be set using the hw.acpi.video.lcd0.economy and hw.acpi.video.lcd0.fullpower sysctl variables.