Saturday, March 14, 2009

Linux Kernel for Fujitsu-Siemens Loox N560/C550 with support for CPLD and builtin leds

I've implemented support for CPLD and leds. htc-gpio driver is used with a custom list of CPLD registers/resources for Fujitsu-Siemens Loox 5XX (N560/C550). Now CPLD interface is available for all other drivers (existing and planned) of the linux/android kernel.

It is interesting how CPLD is implemented in the linux kernel. Actually CPLD is a chip that supports very simple custom logic (and that is the reason why it is much faster than CPU). CPLD chip has a set of input pins and output pins. All these pins are mapped to a region of memory address space. The most important work with CPLD is that modifying values of pins to control devices. This is done setting a value to 0 or 1. In fact, programming of GPIO (general purpose input/output of CPU) is done in the same way: a programmer writes code that sets a GPIO pin to either 0 or 1. Linux kernel already has support for GPIO which provides a set of functions for platform drivers. In addition, GPIO driver provides a way to map any virtual GPIO pin to some custom code that is responsible for handling of setters and getters for the mapped pins. And indeed, that is how htc-egpio driver does the job. The driver leverages gpiolib mapping CPLD registers to GPIO pins. Thanks to this approach, no addition functions are required to work with CPLD. It is enough to use gpio_set_value/.. methods.
After the CPLD driver had been implemented, it was possible to implement a driver for the leds of Loox N560/C550. The leds driver, I implemented, exports a set of functions that other drivers (wifi, gps, bluetooth, pm, ...) are supposed to use to control the leds. Also, the leds driver makes it possible to control the leds from userspace (shell scripts, java program, ...) using files under sysfs filesystem.

The following is the list of files exported by the leds driver and the possible content values for the each file:
/sys/devices/platform/loox5xx-leds.1/keyboard: on, off, any
- backlight for keyboard

/sys/devices/platform/loox5xx-leds.1/left_green: on, off, any
- green led on the left side. WM5 indicates WiFi activity with this led

/sys/devices/platform/loox5xx-leds.1/left_blue: on, off, any
- blue led on the left side. WM5 indicates Bluetooth activity with this led

/sys/devices/platform/loox5xx-leds.1/left_orange: on, off, any
- orange led on the left side. WM5 indicates GPS activity with this led on Loox N560

/sys/devices/platform/loox5xx-leds.1/right_green: on, off, any
- green led on the right side. WM5 allows programs to control this led using winapi.

/sys/devices/platform/loox5xx-leds.1/right_orange: on, off, blink, any
- orange led on the left side. WM5 indicates charging activity with this led

on - the led is on regardless of the kernel activity,
off - the led is off regardless of the kernel activity,
blink - the led is blinking regardless of the kernel activity,
any - the led is controlled by the kernel.

For instance, if the content of the right_orange file is set to 'on', then the orange led (on right side of PDA) will be on no matter what you do: plug or unplug your device to/from a cradle. The driver will hold on the state of the led until, you write 'any' into the file right_orange. With 'any' value in file, the first 'power' event will change state of the led. The interface of the driver makes it possible to implement any notification (low battery, new mail..) effects you can imagine involving all leds of the device. The following script demonstrates how to blink with the keyboard backlight led:

while true;
do echo on > /sys/devices/platform/loox5xx-leds.1/keyboard;
sleep 0.1;
echo off > /sys/devices/platform/loox5xx-leds.1/keyboard;
sleep 0.1;
# Condition for break...
echo any > /sys/devices/platform/loox5xx-leds.1/keyboard;

The current patch for the android cupcake kernel is located here.

1 comment: