SL-C3000で英語配列のUSBキーボードを使う まとめ

SL-C3000以降の機種では、USBホストケーブルでUSBキーボードを繋ぐだけでQtopiaで外部キーボードが使えるようになります。しかし、英語配列のキーボードを繋いでも日本語配列として動作してしまうという問題がありました。とりあえずKeyHelperで配列を変更しようとしたのですが、バックスラッシュキーの入力そのものがQtopiaに入ってこないため、ドライバまでいじる羽目になってしまいました……。

ちなみに僕が使っているキーボードはこれです。

PFU Happy Hacking Keyboard Lite2 日本語配列 USBキーボード ブラック PD-KB210B/U

PFU Happy Hacking Keyboard Lite2 日本語配列 USBキーボード ブラック PD-KB210B/U

キーボードが出す生のスキャンコードを調べる

……ために、usbkbdドライバのデバッグコードを有効にしてコンパイルします。ドライバのソースは linux/drivers/usb/usbkbd.c にありますので、113行目の #if 0 を #if 1 に変更します。出来上がった usbkbd.o をザウルスの /lib/modules/2.4.20/kernel/drivers/usb/usbkbd.o に置いてからキーボードを接続すると、キー押下時にメッセージが出力されるようになります('tail -f /proc/kmsg'とでもしてモニタしてください)。

んで、地道に生スキャンコードを調べます。HHKでは以下のような結果になりました。

0 1 2 3 4 5 6 7 8 9 A B C D E F
0 A B C D E F G H I J K L
1 M N O P Q R S T U V W X Y Z 1 2
2 3 4 5 6 7 8 9 0 Enter Esc BS Tab Spc - = [
3 ] \ ; ' ` , . CAPS F1 F2 F3 F4 F5 F6
4 F7 F8 F9 F10 F11 F12 PSc ScrLk Pause Ins Home PgUp Del End PgDn
5
E Ctrl 左Shift 左Alt 左Meta 右Shift 右Alt 右Meta

たぶん、このコード表は他のキーボードでもおおむね共通なんじゃないかと思います。

Linuxカーネルレベルでのキー配列を変更する

で、キーボードから送られてくるスキャンコードがそのまま使われることはなく、Linuxカーネルで使われる別のコード体系に変換されます。その変換表も usbkbd.c にあります。以下 54 行目からの抜粋です。

#if defined(CONFIG_ARCH_PXA_TOSA) || defined(CONFIG_ARCH_SHARP_SL)
static unsigned char usb_kbd_keycode[256] = {
          0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
         13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 41, 42,
         43, 44, 45, 46, 47, 48, 49, 50, 28, 34, 31, 65, 92, 51, 52, 55,
         54,  0, 97, 95, 96, 70, 98, 99,100, 60, 33, 58, 94, 39, 88, 89,
         70,110,117,120, 30, 40,115,  0,  0, 80,104,106, 81,105,107, 124,
        121,123,122, 32, 82, 83, 85, 86, 87, 71, 72, 73, 74, 75, 76, 77,
         78, 79, 80, 93,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,101, 69, 53,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         56, 27, 57, 29,111,112,113,114,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
};
#else

この定義は上記HHKのコード表と一対一で対応しています。例えばバックスラッシュキーだと生スキャンコード 0x31 ですから、上から4行目の左から2桁目にある 0 が変換後のスキャンコードになります(0なので前述したように無反応なわけです)。

変換後のスキャンコードがどのキーに対応するのかは、通常はカーネルソースの linux/include/linux/input.h を見ればわかるようになっています。しかしザウルスではLinux標準とは関係の無い独自のコードが使われているので input.h は参考になりません。その独自コードは linux/include/asm-arm/sharp_keyboard.h で定義されています。普通に考えるとこの定義を参照しながらキー配列をいじればいいように思えますが、実は sharp_keyboard.h て定義されている名前と数値はまったく参考になりません。例えばスキャンコード 106 は SLKEY_LALT という名前で定義されているので「左Alt」キーのように思えますが、QtopiaではPageUpキーとして機能します。

という苦労を経て辿り着いたのが、ザウルス側の /opt/QtPalmtop/etc/keycode.tbl です。これを参照しながらQtopiaのキーに対応するスキャンコードを調べて、usbkbd.cの変換表を変更していけば良いわけです。例えばAltキーを検索すると以下のような行が見つかります。

0x039 Key_Alt 0xffff 0xffff 0xffff 0xffff 0x10
0x139 Key_Alt 0xffff 0xffff 0xffff 0xffff 0x10
0x071 Key_Alt 0xffff 0xffff 0xffff 0xffff 0x10
0x171 Key_Alt 0xffff 0xffff 0xffff 0xffff 0x10

0x1xxの行はFnキーと同時押しした場合なので無視して構いません。二つエントリがあるのが気になりますが、とりあえず最初のやつを見ると Key_Alt に対応するスキャンコードは 0x39 であることがわかります。

そんなこんなで僕は以下のように変更しました。

#if defined(CONFIG_ARCH_PXA_TOSA) || defined(CONFIG_ARCH_SHARP_SL)
static unsigned char usb_kbd_keycode[256] = {
          0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
         13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 41, 42,
         43, 44, 45, 46, 47, 48, 49, 50, 28, 34, 31, 65, 92, 51, 86, 54,
         97, 53, 97, 95, 83, 55, 98, 99,100, 60, 88, 89, 90, 40, 29, 69,
         70,110,117,120, 30, 40,115,  0,  0, 80,104,106, 81,105,107, 124,
        121,123,122, 32, 82, 83, 85, 86, 87, 71, 72, 73, 74, 75, 76, 77,
         78, 79, 80, 93,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,101, 69, 53,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         56, 27, 30, 57,111,112,113, 39,  0,  0,  0,  0,  0,  0,  0,  0,
          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
};
#else

基本的に刻印どおりのキーになるようにしてます。keycode.tblにファンクションキー F1〜F8の定義がなかったので、ファンクションキーの部分はそのままで、F1〜F5にCalender,Address,Mail,Home,Menuキーを割り当てました。また、モディファイアキーの左AltをFnキーに、左MetaをAltキーに、右MetaがOKキーになるようにしています。

調整が終わったらコンパイルして usbkbd.o を置き換えます。

KeyHelperで最終調整

上記作業で全てのキーが反応するようになりました。ですが、まだShift+8で「(」が入力されてしまったりするので、KeyHelperで調整します。KeyHelperを使わずとも keycode.tbl を変更することで同じことができますが、keycode.tblを変更すると内蔵キーボードの定義にまで影響が出るので嬉しくありません。また、確認していませんが keycode.tbl の変更は Qtopia を再起動しないと有効にならないので、動的にキー配列を変更出来る KeyHelper のほうが便利だと思います。

KeyHelperの設定方法はどっか別のページを見てください。結果のxmlファイルだけ置いておきます。


	
		
			
			
			
			
		
		
			
			
			
		
		
			
			
			
		
		
			
			
			
		
		
			
			
			
		
		
			
			
			
		
		
			
			
			
			
		
		
			
			
		
		
			
			
			
		
		
			
			
		
		
			
			
			
		
		
			
			
		
		
			
			
			
		
		
			
			
			
			
		
	

	
		
	

	
		
			
		
	

あとは、キーボードを接続して khctl load keyhelper-hhk.xml とすれば普通に使えるようになります。

関連ファイル

http://atty.jp/pub/zaurus/usbkbd-hhk.tar.gz にコンパイル済み usbkbd.o(デバッグ版、改変版)と keyhelper-hhk.xml を入れて置いておきます。HHK以外でもそのまま使えるかも。

ToDo

  • キーボードの着脱に合わせて自動的にKeyHelperの設定を切り換えるようにしたい。出来ると思いますが、まだ動作を追ってないです。