#!/bin/ibash # Write the address for the LCD panel to repair brightness hotkey. Underlying # bug: https://bugs.freedesktop.org/show_bug.cgi?id=45452 # brightness bug on Ubuntu: https://bugs.launchpad.net/bugs/806032 # # Author: Peter Lekensteyn # This script is released into public domain, do whatever you want with it set -e modprobe acpi_call if ! [ -f /proc/acpi/call ]; then echo "Could not load acpi_call. If not installed, get it from" echo "https://github.com/Bumblebee-Project/acpi_call" exit 1 fi if ! type xxd &>/dev/null; then echo "Cannot find xxd program for hex to bin conversion" exit 1 fi if ! [ -w /dev/mem ]; then echo "Cannot write to memory" exit 1 fi # retrieve base address of Intel OpRegion echo '\ASLB' > /proc/acpi/call base=$(cat /proc/acpi/call) if ! [ "${base:0:2}" = "0x" ]; then echo "\ASLB field not found, cannot retrieve base address" exit 1 fi # Currently Active Display Devices List (CADL) is fixed at 0x160, see # http://intellinuxgraphics.org/ACPI_IGD_OpRegion_%20Spec.pdf addr=$((base+0x160)) # look for the LCD device handle, e.g. \_SB.PCI0.GFX0.LCD0 handle=$(grep -m 1 -h LCD /sys/bus/acpi/drivers/video/*/*/path) if [ -z "$handle" ]; then echo "No LCD ACPI handle found" exit 1 fi # Get ID for LCD device echo "$handle._ADR" > /proc/acpi/call disp=$(cat /proc/acpi/call) if ! [ "${base:0:2}" = "0x" ]; then echo "Invalid LCD ID" exit 1 fi # strip 0x disp=${disp:2} # make sure the length is a multiple of two, i.e. 0400 instead of 400 case ${#disp} in *[13579]) disp=0$disp ;; esac # since we have a DWORD here (32-bit number), insert padding disp_endian=00000000 # little-endian, 0400 must be written as 0004 for ((i=0; i<${#disp}; i+=2)); do disp_endian="${disp:i:2}$disp_endian" done echo 0x${disp_endian:0:8} | xxd -r | dd of=/dev/mem bs=1 seek=$addr count=4