[ Content | Sidebar ]

Posts tagged linux

Samsung Q320 Fn-keys in Linux 2.6.32

February 20th, 2010

If you’ve been following my attempts to get the brightness up/down and other fn-keys on my Samsung Q320 laptop to work in Linux, you might like to know the saga has reached a happy conclusion. Previously I published a hack to the atkbd kernel driver to get these problematic keys to send key release events. My attempt to get this included in the kernel failed, but I was told the 2.6.32 kernel would contain a new mechanism for fixing this from userspace.

Well, 2.6.32 is here so how can we fix the fn-key release problem? Documentation for the new sysfs attribute is a bit scanty as it’s intended to be used only by udev/HAL/DeviceKit, but you can set it yourself quite easily. The relevant file is /sys/devices/platform/i8042/serio0/force_release – this lets you manipulate a bitmap in atkbd.c indicating which scancodes don’t send key release events.

echo 130-132,134,136,137,179,247,249 \
    > /sys/devices/platform/i8042/serio0/force_release

The bitmap editing syntax is quite nice – done in lib/bitmap.c rather than the atkbd driver itself. I got those scancodes from the array atkbd_samsung_forced_release_keys in atkbd.c. They were originally intended for the NC20 but the Q320 keyboard seems to be the same. It works for me anyway.

You still need to map the brightness up/down keys to the correct X11 codes, which you can do like this:

setkeycodes e008 225 e009 224

Job’s a good’un.

All my Samsung Q320 coverage is here.

Samsung Q320 Fn-key release hack update

September 19th, 2009

Earlier I posted a hack to get the Linux kernel to send synthetic key release events for the Fn-keys on a Samsung Q320. But I forgot about actually submitting the patch to the kernel developers until today. However, it looks like this hack will be unnecessary as of 2.6.32:

Hi Nick,

On Sep 19, 2009, at 12:20 AM, Nick Gasson wrote:

> This adds a workaround for the missing fn-key release
> events on Samsung Q320 and similar laptops.
>
> Tested extensively on my own laptop.
>
> Signed-off-by: Nick Gasson

Thank you very much for your patch, hovewer I will not be accepting any more patches for the force release quirk in the kernel. 2.6.32 will have ‘force_release’ sysfs attribute allowing to apply the quirk from userspace.


Dmitry

Which is good, because either way I won’t have to use a custom kernel. I wonder how long this will take to propagate to Debian though…

Linux on a Samsung Q320: Part 7

July 13th, 2009

Argh! Another problem! Over the last couple of days I’ve being trying to figure out why the brightness fn-keys on my laptop don’t seem to work: they either set the brightness to maximum-bright or maximum-dim. (Although they inexplicably sometimes work.) At first I thought it was a problem with my earlier HAL hackery, but this isn’t the case as the HAL brightness scripts work fine when not using the fn-keys.

After a while I discovered the problem was that some of the fn-keys weren’t sending key release events (easy to see in xev or with lshal -m). Turns out this is a problem with lots of laptop keyboards: look at the thousands of lines of hacks in drivers/input/keyboard/atkbd.c in the Linux kernel source. The good news is that this is easy to fix: the Q320 uses exactly the same scancodes as an earlier Samsung laptop. The bad news is that you have to compile your own kernel. Ho hum.

Apply this patch to a 2.6.30 kernel and rebuild. Voila! And the problem is gone!

--- drivers/input/keyboard/atkbd.c.old  2009-07-13 00:34:14.000000000 +0100
+++ drivers/input/keyboard/atkbd.c      2009-07-13 00:35:19.000000000 +0100
@@ -1550,6 +1550,15 @@
                .driver_data = atkbd_samsung_forced_release_keys,
        },
        {
+               .ident = "Samsung Q320/P320",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Q320/P320"),
+               },
+               .callback = atkbd_setup_forced_release,
+               .driver_data = atkbd_samsung_forced_release_keys,
+       },
+       {
                .ident = "Samsung SQ45S70S",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),

I found the DMI_PRODUCT_NAME using dmidecode if you were wondering.

Will test it for a few days and if nothing is borked maybe I shall try to get it merged into the kernel. It would certainly be annoying to have to compile my own kernel for every release.

Shutting down and rebooting via HAL

July 12th, 2009

You know how GNOME/KDE have “shutdown” and “reboot” buttons that normal users can use to turn off the computer? Rather than using sudo or making /sbin/shutdown setuid, they use HAL which provides a nice power management interface. Turns out this is pretty easy to call from the command line so you can use it in Fluxbox, etc.

The DBus object is /org/freedesktop/Hal/devices/computer which has lots of interesting methods including Shutdown(), Reboot(), and Suspend(). For example, you can reboot the computer using:

qdbus --system org.freedesktop.Hal /org/freedesktop/Hal/devices/computer \
org.freedesktop.Hal.Device.SystemPowerManagement.Reboot

This is using the qdbus tool which is distributed with QT. If you get permission errors you may have to configure PolicyKit to let you call this interface. Here’s my PolicyKit.conf which works for me on Arch Linux. (You’ll also need to add your user to the power group.)

Here’s a simple script to wrap this up: hal-power. Usage example: hal-power reboot to reboot the computer.

Linux on a Samsung Q320: Part 6

July 9th, 2009

I’ve been playing around with powertop trying to reduce power usage. I’m using laptop-mode to spin down the disk when its not needed (it automatically activates when on battery power). I’ve also added these two powertop suggestions to /etc/rc.local

# Reduce the frequency of disk flushes
echo 1500 > /proc/sys/vm/dirty_writeback_centisecs
 
# Turn off the SATA link whenever possible
echo min_power > /sys/class/scsi_host/host0/link_power_management_policy

I’ve also enabled CPU frequency scaling. If I dim the brightness, the laptop uses around 16W of power under light usage: amarok playing in the background and browsing the tubes. It guesses this will give around 3 hours battery life. Not sure if I can make it better…

Addictive game

July 9th, 2009

I wasted today playing UFO: Alien Invasion. It’s unusually polished for an open source game. The graphics are very nice, especially in the battle mode. The storyline is also quite engrossing and surprisingly well written – I like the non-linearity of it too. Recommended.

Going to stop now and do something useful like add scenery to Train Game.

Linux on a Samsung Q320: Part 5

July 7th, 2009

This morning I have learned a lot about HAL. I have been trying to get the brightness up/down controls on my laptop to work (they need to use a non-standard Nvidia interface).

If you have the same laptop then these are the steps I went through to get it work. Disclaimer: your mileage may vary; no warranty; may be somewhat Arch Linux specific.

First we need to make sure the kernel sends the right key symbols, which it doesn’t by default. Add the following to /etc/rc.local

setkeycodes e008 225 e009 224

Here e008 and e009 are the scancodes, and 225 and 224 are the keysyms we want them translated to.

Next we need to get HAL to recognize the Samsung Q320 and handle it specially. Copy 10-samsung-q320-brightness.fdi to /etc/hal/fdi/information/.

Now restart HAL and this file should be loaded (you can check with /usr/lib/hal/hald-generate-fdi-cache --verbose 2>&1 | grep samsung). This does two things: it sets the access_method for the brightness control to a special value “samsung-q320” rather than the default “generic” – we’ll check for this later; it also removes the key that tells HAL to look for the brightness control under /sys – this doesn’t work. Check this has worked by running lshal | grep samsung-q320.

Now, HAL uses two scripts to handle getting and setting the brightness. These are hal-system-lcd-get-brightness and hal-system-lcd-set-brightness located in /usr/lib/hal/scripts. We’re going to hack them so they use smartdimmer (from the nvclock package). Apply this patch to hal-system-lcd-get-brightness:

--- hal-system-lcd-get-brightness.old   2009-07-07 11:42:25.000000000 +0100
+++ hal-system-lcd-get-brightness       2009-07-07 13:10:17.000000000 +0100
@@ -9,6 +9,10 @@
 
 . hal-functions
 
+if [ "$HAL_PROP_LAPTOP_PANEL_ACCESS_METHOD" = "samsung-q320" ]; then
+       exit `smartdimmer -g | awk '/SmartDimmer level: / {print int(($3 - 15) / 5)}'`
+fi
+
 # Check for environment variables
 if [ -z "$HAL_PROP_LAPTOP_PANEL_ACCESS_METHOD" -a -z "$HAL_PROP_LINUX_SYSFS_PATH" ]; then
         echo "org.freedesktop.Hal.Device.UnknownError" >&2

This checks the special key we set earlier, and if it is set we query setdimmer for the current brightness and munge it into a number between 0 and 17 (there are 18 brightness levels on this backlight). A similar patch for hal-system-lcd-set-brightness:

--- hal-system-lcd-set-brightness.old   2009-07-07 11:28:32.000000000 +0100
+++ hal-system-lcd-set-brightness       2009-07-07 16:48:16.000000000 +0100
@@ -30,5 +30,10 @@
 
 export value
 
+if [ "$HAL_PROP_LAPTOP_PANEL_ACCESS_METHOD" = "samsung-q320" ]; then
+       smartdimmer -s `expr $value \* 5 + 15`
+       exit
+fi
+
 hal_check_priv org.freedesktop.hal.power-management.lcd-panel
 hal_exec_backend

Now you should be able to test this using any HAL-enabled brightness setter (e.g. GNOME Power Manager).

I had a strange problem with the GPM in Arch: it refused to change the brightness away from 50%. I got the GPM source from ABS to try and debug it, but when I built it from source it worked fine. Hmm.

Linux on a Samsung Q320: Part 4

July 7th, 2009

VGA and HDMI out are now working nicely. I couldn’t get xrandr to work (I suspect I could with more fiddling though). Instead I’m using Nvidia’s TwinView which supports multiple monitor configurations nicely. I’ve tested it on an external TFT monitor and a widescreen TV (via HDMI) and both worked fine.

Turns out that some parts of the xorg.conf I posted earlier were redundant. You can use HAL to detect the screens, monitors, etc. All you actually need is a section to force the use of the Nvidia driver like this:

Section "Device"
   Identifier     "Device0"
   Driver         "nvidia"
   VendorName     "NVIDIA Corporation"
   BoardName      "GeForce G 105M"
   Option         "TwinView"      "1"
EndSection
 
Section "Module"
   Load         "glx"
   Disable      "dri"
   Disable      "dri2"
EndSection

The TwinView option is required to enable Nvidia’s multi-monitor stuff.

The webcam and bluetooth also seem to be working.

I’ve managed to reproduce the bug where xcowsay gets sliced across screens!

Linux on a Samsung Q320: Part 3

July 6th, 2009

Progress is good. I have wireless working (using the ath3k driver). GNOME’s network manager (nm-applet) works fine in fluxbox.

Suspend/resume works too, but it’s not automatic on lid-closing. Need to fiddle with the ACPI event handlers I think. EDIT: works fine with gnome-power-manager.

The normal ACPI brightness controls for the backlight do not work. You have to use nvclock instead (e.g. nvclock -S -10 to dim 10%).

This is my working xorg.conf file for the Nvidia G105M in the laptop. It’s fairly straightforward apart from the two “Disable” lines at the bottom – you need these or xorg will try to load those modules by default (conflict with the Nvidia stuff). Note that this assumes you’re using HAL to configure the input devices…

Section "ServerLayout"
   Identifier     "Layout0"
   Screen      0  "Screen0" 0 0
EndSection
 
Section "Files"
   FontPath "/usr/share/fonts/local/"
EndSection
 
Section "Device"
   Identifier     "Device0"
   Driver         "nvidia"
   VendorName     "NVIDIA Corporation"
   BoardName      "GeForce G105M"
EndSection
 
Section "Screen"
   Identifier     "Screen0"
   Device         "Device0"
EndSection
 
Section "Module"
   Load		"glx"
   Disable      "dri"
   Disable      "dri2"
EndSection

I’ll post an updated one when/if I get VGA/HDMI output working.

Linux on a Samsung Q320: Part 2

July 6th, 2009

Argh! The Debian installer worked perfectly, but the installed system was fail: no network drivers for wired or wireless, no X, … After several hours of frustration I gave up and installed Arch Linux. It’s not bad! The installer is a little more primitive than Debian’s, and it dumps you into a terminal without X. Managed to get X working with the proprietry Nvidia drivers and the xf86-input-synaptics package for the touchpad.

Will report back when I’ve tested more things.