gnome-shell Macbook/applesmc keyboard brightness extension

So, since this needs a bit of hacking – because of permission and such, I decided to put up a small howto on how to add an extension to gnome-shell where you can set the keyboard brightness.

First off we need to setup a bash-script who takes care of the keyboard-backlight settings.

The following script will do the trick:

#!/bin/bash
 
BACKLIGHT=$(cat /sys/class/leds/smc::kbd_backlight/brightness)
 
BACKLIGHT=$1
 
echo $BACKLIGHT | tee -a /sys/class/leds/smc::kbd_backlight/brightness
exit 0

Put that into /usr/local/bin/applekb-backlight with your favorite editor(emacs, vim, nano).

After you’ve done this(which of course needs to be sudo`ed) you need to add execution permissions to the script.

sudo chmod +x /usr/local/bin/applekb-backlight

Now the script is ready to work – you can test it by entering:

applekb-backlight [0-255]

After this i put together a gnome-shell extension who uses this script to set the brightness, just like the screen-brightness extension.

The extension can be downloaded here.

NOTE!
This is just a quick workup and need modification and error-handling to work properly, but it gives a general idea on how to solve this issue.

Of course the best solution would be to be able to use the fn + F5/F6 keys!

applesmc read fail on mid-2012 Macbooks

The error is simple “applesmc: read arg fail” – this happens when trying to modprobe the applesmc module.

[   46.584969] applesmc: LSSB: read arg fail
[   46.672745] applesmc: LSSB: read arg fail
[   46.759992] applesmc: : read arg fail
[   46.847830] applesmc: : read arg fail
[   46.935599] applesmc: : read arg fail
[   47.023427] applesmc: : read arg fail
[   47.111244] applesmc: : read arg fail
[   47.199101] applesmc: : read arg fail

So I’ve been hacking around and reading forum threads when this genius over at Ubuntu forums came up with the solution – really simple.

The solution is a patch which actually only modifies one line of code – the constant telling the read from SMC to wait for feedback.

static int __wait_status(u8 val)
{
    int us;
    val = val & APPLESMC_STATUS_MASK;
 
    for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
        udelay(us);
        if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val)
            return 0;
    }
 
    return -EIO;
}

The constant to be changed is the APPLESMC_MIN_WAIT.

#define APPLESMC_MIN_WAIT     0x0040

is changed to

#define APPLESMC_MIN_WAIT     0x0010

This should take care of your problems!

Compiling the new module on Ubunutu

On Ubuntu systems you can get the kernel source by typing

sudo apt-get install linux-source

You can find the source in /usr/src. Uncompress it!

When you’ve applied the patch

index 0162f55..f41585e 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -54,7 +54,7 @@
#define APPLESMC_MAX_DATA_LENGTH 32
/* wait up to 32 ms for a status change. */
-#define APPLESMC_MIN_WAIT	0x0040
+#define APPLESMC_MIN_WAIT	0x0010
#define APPLESMC_MAX_WAIT	0x8000
 
#define APPLESMC_STATUS_MASK	0x0f
--
1.7.11.1

Then simply run

cd /usr/src/linux-source-x.x.x/linux-source-x-x-x/drivers/hwmon/
sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) applesmc.ko
sudo insmod applesmc.ko
dmesg | grep applesmc

`dmesg | grep applesmc` should read something like
[ 70.969188] applesmc: key=375 fan=1 temp=22 acc=1 lux=2 kbd=1

Hope this works for you! :)