Tux
Communication
Mailing lists
Documentation
User Manual
Target board info.
Target chip info.
Support
Linux support
Bugzilla
Downloads
STLinux
Updates
Search
Google


The web
stlinux.com
Distribution Guide
Device drivers
Keyboard drivers
ST Logo
Previous   Contents   Next


Keyboard drivers

The ST Linux distribution supports keyboard connections via USB. All STMicroelectronics' System on Chip (SoC) hardware now has an OHCI controller integrated on the chip. The default configuration should enable USB keyboards to work straight out of the box.

When the keyboard is plugged into the USB port, the kernel should detect it and print a message to confirm this. The message varies according to the type of keyboard, for example:

input: USB HID v1.10 Keyboard [CHESEN PS2 to USB Converter] on usb-STB7100_ehci_bus-1.4 

The easiest way to test that the keyboard is working is to use the command:

host% cat < /dev/tty0

Anything typed on the keyboard should be echoed to the screen. By default, the console will be in line mode, so nothing will be displayed until the return key is pressed. (To end the test, type Ctrl-D).

Similarly, to test that the mouse is working, use the command:

host% od -x /dev/mouse

A stream of hexadecimal numbers will be displayed when the mouse is moved or the buttons are clicked.

Kernel configuration

A number of options must be enabled in the kernel to add the support for the keyboard driver. The easiest way to set these is to bring up the Linux Kernel Configuration screen on the host, for example:

host% cd /home/STLinux/linux-sh4-2.6.11_20050523
host% make ARCH=st200 CROSS_COMPILE=st231-linux- menuconfig

Enter the following sections in the order given:

  1. Device Drivers ---> USB Support ---> USB Human Interface Device (full HID) support

  2. Device Drivers ---> USB Support ---> HID input layer support

  3. Device Drivers ---> Character devices ---> Virtual terminal

  4. Device Drivers ---> Graphics Support ---> Support for frame buffer devices

  5. Device Drivers ---> Graphics Support ---> Console display driver support ---> Framebuffer Console support.

This sets the configuration options CONFIG_USB_HID, CONFIG_USB_HIDINPUT, CONFIG_VT, CONFIG_FB and CONFIG_FRAMEBUFFER_CONSOLE.

Other commands

There are a large number of other commands associated with keyboards, which accommodate different keyboards, languages and user customization. This section provides a brief overview of what can be done, but assumes a reasonable understanding of how keyboards are driven by Linux. For more details see How keyboards work or the Linux keyboard and console HOWTO.

The following console utilities are useful in keyboard configuration. (Most of these are supplied in the package console-tools.)

  • showkey displays the codes that a key generates when it is pressed or released:

    • showkey --scancodes shows the scancodes generated by the keyboard controller,

    • showkey --keycodes shows the keycodes generated by the Linux kernel from the scancodes, which give each key a unique number,

    • showkey --keymap shows the effects of the current keyboard translation table (also called the keymap). This handles modifier and compose keys, and other actions such as switching virtual consoles.

  • xev is an X application which shows the X events sent by the X server to an application. When a key is pressed or released in the xev window, xev displays the key's keycode (the unique number X assigns to each key), and the state of any modifiers currently pressed. Together, these allow the X library to display the keysym (the symbol which X expects to be engraved on the key, taking into account the modifiers).

    The ST Linux distribution does not ship with a native version of xev; however it can be used from the host machine by specifying the -display option to view the target.

Most of these mappings are programmable, and utility programs are provided to change the mappings.

  • For the low level keyboard mapping, from scancode to keycode, the utility getkeycodes shows the current mapping, and the utility setkeycodes can be used to modify this map.

  • The keyboard translation table (or keymap) describes what the Linux console should do when a certain key in pressed in conjunction with any modifier keys (such as Shift or Alt). These actions are normally to input one or more characters to the console, but can also be commands such as switch to a different virtual console. The keymap can be printed in various formats using the dumpkeys utility, and can be modified using loadkeys.

  • X programs map keycode to keysym using a mapping also called the keymap. This mapping can be updated using the xmodmap program. The ST Linux distribution does not include a native version of xmodmap, but like xev it can be used from a host.

Note: The Linux kernel keycode and the X keycode may be different. There is another mapping within the X server translating Linux kernel keysyms to X keysyms. This mapping is fixed and arbitrary.

The non-standard keys which are provided on some keyboards often cause problems. For example, some keyboards provide a top row of keys which are useful in audio/video applications, but by default these keys will not function as they are not mapped correctly.

Mapping the keys

To begin the mapping, the scancode currently generated by the key is needed. To find this enter:

host% showkey --scancode

and then press the key to be mapped. (The program will terminate when no key has been pressed for ten seconds.) The output will be a stream of hexadecimal numbers such as:

0xe0 0x32 0xe0 0xb2

In this example, the scancode for the pressed key is e0 32 on make and e0 b2 on break.

To find which (if any) keycode is generated for this make scancode, enter:

host% getkeycodes
...
Escaped scancodes e0 xx (hex)
...
e0 30: 0 0 0 0 0 98 0 99
...

This indicates that scancode e0 32 is currently bound to keycode 0, which is a pseudo-code meaning `not bound'. A free keycode must now be found. Normally keycodes 89 to 95 and 120 to 124 are unused. (To check this is the case, see the output from dumpkeys as described below.)

The command to bind keycode 89 to the key chosen earlier is:

host% setkeycodes e032 89

To use this key in a console application it has to be further bound to an action. The easiest way to do this is to simulate a function key to generate an escape sequence. For this a copy of the current keymap is needed. To create a copy in /tmp/keymap enter:

host% dumpkeys > /tmp/keymap

Find the selected keycode in the copy of the keymap and edit it to bind the keycode to a function key and to specify the string to be generated by the key. For example:

keycode 89 = F100
string F100 = "Hello"

Save the keymap copy and reload it into the kernel as follows:

host% loadkeys /tmp/keymap

To use the key from an X application the process is very similar. As before, use setkeycodes to map the scancode to a keycode. Then start X and use xev to find which keycode X has assigned to this key. To use the key in an existing application it must be entered into the keymap using xmodmap, but if it is only to be used within your own application, it is only necessary to check for that keycode in the events XKeyPressedEvent and XKeyReleasedEvent.

How keyboards work

The keyboard interface should be among the simplest peripheral interfaces, but in practice they turn out to be very complex. The reason for this is that intelligence has been built into each part of the driver, which sometimes results in the actual key presses being hidden by processing in the upstream part of the driver, which may have to be reversed in the downstream part to recover the raw data.

This section discusses how keyboards are interfaced with Linux, how this may introduce problems, and what can be done to work around these problems.

Each key is assigned a unique key number in the hardware, which simply identifies its location on the keyboard. All the keys are continually scanned, usually by a small microcontroller in the keyboard. When a key press is detected, the microcontroller reads the key number and sends a scan code to the host. Most keyboards in fact send two scan codes for each key, a make code when the key is pressed down, and a break code when the key is released. This allows the host to detect if a modifier key (for example shift) is down at the moment when the current key is pressed.

The keyboard interface became more complex when PS/2 bidirectional keyboards were developed. These keyboards can receive commands from the host as well as send key codes to it. (In fact both the clock and data lines are bidirectional, which is the reason for having a microcontroller within the keyboard itself.) The most important of these complexities are given below.

  • Some keys change the scan codes sent to the host (for example cursor keys) if modifier keys are held down.

  • The original PS/2 scan codes gave problems, so a second set was created. The second set also gave problems, so a third set was devised which was correctly specified and more logical. However, many keyboard manufacturers failed to implement set 3 correctly, so it has not been widely adopted. The result is that the microprocessor in the keyboard has to be programmable to accommodate the different scan code sets.

  • Most keyboards are able to repeat certain keys. If a key is held down longer than normal, the make code is sent repeatedly until the key is released; when a single break code is sent. (These keys are known as typematic keys.) Other keys are not typematic, and a single make code is sent no matter how long they are held down. The typematic delay (the delay between a key first being pressed and the first repeat code being sent) and the typematic rate (the rate at which the make code is repeated) can be programmed from the host.

Linux console modes

The Linux console can be in one of four modes:

  • K_RAW
    Scancodes are passed through unpreprocessed.

  • K_MEDIUMRAW
    Scancodes are converted into keycodes with a modifier appended to indicate whether it was a make or break.

  • K_XLATE or K_UNICODE
    Scancodes are translated using the keyboard map into normal 8-bit characters or unicode characters respectively.

The keyboard mode is set using the KDSKBMODE ioctl and read by the KDGKBMODE ioctl.

X Windows

The keyboard driver used by X Windows under Linux is in the file
.../xc/programs/Xserver/hw/kdrive/linux/keyboard.c.

This puts the keyboard into MEDIUMRAW mode, in which keycodes are used directly. Mapping to the X keycodes is then performed internally. In order to determine how keys should be mapped, the code also reads the keyboard translation table (as does dumpkeys) using the KDGKBENT ioctl.

Previous   Contents   Next
Valid HTML 4.01! Last updated: 2005/11/24 18:06:07
© Copyright STMicroelectronics Limited, 2005
Printer