X-Sieve: cmu-sieve 1.3 Return-Path: Received: from tce.co.jp (sv.tce.co.jp [210.239.47.27]) by www.sodan.org (8.9.3+3.2W/3.7W/Sodan.smtpfeed) with SMTP id SAA16882 for ; Thu, 24 Feb 2000 18:17:54 +0900 Received: (qmail 1326 invoked by uid 5555); 24 Feb 2000 09:15:23 -0000 Received: from localhost (HELO sv.tce.co.jp) (127.0.0.1) by localhost with SMTP; 24 Feb 2000 09:15:23 -0000 Received: from inet-tsb.toshiba.co.jp (inet-tsb.toshiba.co.jp [202.33.96.40]) by sv.tce.co.jp (8.9.3/3.7WPOP-auth 99021516) with ESMTP id SAA01321 for ; Thu, 24 Feb 2000 18:15:21 +0900 Received: from tis2.tis.toshiba.co.jp by inet-tsb.toshiba.co.jp (8.8.8/3.3W9-04/12/95) id SAA13125; Thu, 24 Feb 2000 18:15:20 +0900 (JST) Received: from mx2.toshiba.co.jp by tis2.tis.toshiba.co.jp (8.8.4+2.7Wbeta4/3.3W9-95082317) id SAA06311; Thu, 24 Feb 2000 18:15:19 +0900 (JST) Received: by toshiba.co.jp (8.7.1+2.6Wbeta4/3.3W9-TOSHIBA-GLOBAL SERVER) id SAA14103; Thu, 24 Feb 2000 18:15:18 +0900 (JST) Date: Thu, 24 Feb 2000 18:14:14 +0900 From: Tatsuhiro Nishioka Reply-To: tlinux-users-j@tce.co.jp Subject: [tlinux-users-j:00847] patch for keyboard chattering Sender: tatsuhiro.nishioka@toshiba.co.jp To: tlinux-users-j@tce.co.jp Message-Id: <200002240915.SAA14103@toshiba.co.jp> X-ML-Name: tlinux-users-j X-Mail-Count: 00847 X-MLServer: fml [fml 3.0_BETA#5]; post only (only members can post) X-ML-Info: If you have a question, send e-mail with the body "# help" (without quotes) to the address tlinux-users-j-ctl@tce.co.jp; help= X-Mailer: Mozilla 4.08C-ja [Vine-ja] (X11; I; Linux 2.2.13 i686) Mime-Version: 1.0 Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit Precedence: bulk Lines: 191 X-UIDL: 59f96ee704b1fdb60cbb944010a2534f Status: U はじめまして、西岡@東芝と申します。 私も以前から SS3380のキーボードのチャタリングは気になっていましたので カーネルのソースを変更して実験したところ、 Key down シグナルが連続して複数送られる事があるようです。 実際のキースキャンシグナルから最初の不必要なキースキャンシグナルが 送信されるまでは 1000〜3000 usec と、とても短い時間なのですが、 その後は 10000〜30000 usec 位の間隔で3〜5回送られているようでした。 そこで、これらの不要なキースキャン信号のフィルタ関数を作成して kernel-2.2.13 用のパッチにまとめてみました。 私の使っているマシンでは、ほとんどのチャタリングを抑制できている ように思われますので、ぜひお試し下さい。 なお、SS3380 専用のパッチではありませんので、チャタリングが起きるPCに 苛立ちを感じていらっしゃる方も、一度お試し下さい。 私は kernel-2.2.13 に 2.3.28 からの usb backport パッチを当てていますが 通常の linux-2.2.13 のソースにパッチを当てても大丈夫なようです。 パッチに不具合がある場合は tatsuhiro.nishioka@toshiba.co.jp まで 御連絡下さい。 以下にパッチの当て方とパッチを送ります。 関係のない方には、長いメールをお送りすることをお詫び申し上げます。 [パッチの当て方] /usr/src/linux にでも 下のパッチファイルを kernel-2.2.13-chattering.diff というファイル名で置き, % patch -p1 < kernel-2.2.13-chattering.diff としてください。 [カーネルコンパイルオプションの設定] このパッチを当てた後は、make menuconfig で オプション指定し、再コンパイルして下さい。 オプションの設定方法は、make menuconfig から Code maturity level options -> Prompt for development and/or incomplete code/drivers オプションを有効にして Character devices -> Keyboard Chattering Reduction を選択して下さい。 Character devices -> Write chattering info into syslog オプションはチャタリングが発生したときの状況を syslog に書き出します。 チャタリングが発生しているかをモニタして、パッチが有効かを確かめたり、 このパッチを当ててもチャタリング症状が改善しないときの調整用として ご利用下さい。 [調整方法] まだ、調整用の定数はカーネルのコンパイルオプションにしていないので、 調整の際は linux/drivers/char/keyboard.c の #define CONFIG_CHATTER_INTERVAL という値で行って下さい。 [その他] まだ1台のSS3380 でしか試していませんので調整の余地があるかもしれません。 みなさんに御協力頂き、より多くのユーザの方々にご利用頂けるようにして 行けたらと思います。 なお、このパッチは東芝としての正式パッチではなく、あくまで1ユーザとし てのパッチですので、パッチに関して弊社お客様相談室等や川井さんへ問い合 わせたりしないで下さい。本パッチは再配付可能ですが、その際には「実験的 なパッチ」であることを伝え、必ずこの文章も一緒に配付して下さい。 最後に、このパッチで皆様が快適にPCを利用できることをお祈り申し上げます。 --------------------------------------------------- 西岡 竜大 [Tatsuhiro Nishioka] (株)東芝 研究開発センター システム技術ラボラトリー E-mail: tatsuhiro.nishioka@toshiba.co.jp --------------------------------------------------- -------------------------- CUT FROM HERE --------------------------- diff -uNr -U 4 linux-2.2.13.org/drivers/char/Config.in linux-2.2.13/drivers/char/Config.in --- linux-2.2.13.org/drivers/char/Config.in Thu Feb 24 14:37:29 2000 +++ linux-2.2.13/drivers/char/Config.in Thu Feb 24 14:34:52 2000 @@ -110,8 +110,15 @@ if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then bool 'Tadpole ANA H8 Support' CONFIG_H8 fi +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Keyboard Chattering Reduction(EXPERIMENTAL)' CONFIG_CHATTERING_REDUCTION + if [ "$CONFIG_CHATTERING_REDUCTION" = "y" ]; then + bool ' Write chattering info into syslog' CONFIG_CHATTERING_LOG + fi +fi + mainmenu_option next_comment comment 'Video For Linux' tristate 'Video For Linux' CONFIG_VIDEO_DEV diff -uNr -U 4 linux-2.2.13.org/drivers/char/keyboard.c linux-2.2.13/drivers/char/keyboard.c --- linux-2.2.13.org/drivers/char/keyboard.c Thu Feb 24 14:37:29 2000 +++ linux-2.2.13/drivers/char/keyboard.c Thu Feb 24 14:36:55 2000 @@ -20,8 +20,9 @@ * parts by Geert Uytterhoeven, May 1997 * * 27-05-97: Added support for the Magic SysRq Key (Martin Mares) * 30-07-98: Dead keys redone, aeb@cwi.nl. + * 16-02-00: Added keyboard chattering reduction (Tatsuhiro Nishioka) */ #include #include @@ -193,13 +194,81 @@ { return kbd_getkeycode(scancode); } +#ifdef CONFIG_KEY_CHATTERING +#define CONFIG_CHATTER_INTERVAL 30000 +/* + * old version of description + * get time interval between 2 key events to reduce + * annoying keyboard chattering + * MAX_CHATTERING_DELAY gives the max delay(usec) to decide + * if the key is unexpectedly down + * + * new version of description + * Some TOSHIBA laptops such as SS3380 has keyboard + * chattering problem. + * The debug output of this function says several key down + * signals are is unexpectedly sent by the keyboards. + * There's no key-up signals sent while key chattering. + * So I bet that cutting off these continuous key-signals + * that has same scancode and up/down state. + */ +int chattering_filter(unsigned char scancode, int down) +{ + static unsigned char chatter_code=0; + static unsigned char prev_code=0; + static int prev_down=-1; + static struct timeval prev_time={0,0}; + struct timeval cur_time; + long interval=0; + unsigned char keycode; + + do_gettimeofday(&cur_time); + interval = (cur_time.tv_sec * 1000000 + cur_time.tv_usec) - + (prev_time.tv_sec * 1000000 + prev_time.tv_usec); + + kbd_translate(scancode, &keycode, 0); + if (chatter_code == scancode && prev_down == down) { +#ifdef CONFIG_KEY_CHATTERING_LOG + printk(KERN_INFO "KEYBOARD chattering ocurred." + " key_code=%02x, down=%d, interval=%lu (usec)\n", + keycode, down, interval); +#endif + prev_time = cur_time; + return 0; + } + else if (prev_code == scancode && interval <= CONFIG_CHATTER_INTERVAL) { +#ifdef CONFIG_KEY_CHATTERING_LOG + printk(KERN_INFO "keyboard chattering ocurred." + " key_code=%02x, down=%d, interval=%lu (usec)\n", + keycode, down, interval); +#endif + prev_time = cur_time; + chatter_code = scancode; + prev_down = down; + return 0; + } + else + chatter_code = 0; + + prev_time = cur_time; + prev_code = scancode; + prev_down = down; + return 1; +} +#endif + void handle_scancode(unsigned char scancode, int down) { unsigned char keycode; char up_flag = down ? 0 : 0200; char raw_mode; + +#ifdef CONFIG_KEY_CHATTERING + if (!chattering_filter(scancode, down)) + return; +#endif do_poke_blanked_console = 1; mark_bh(CONSOLE_BH); add_keyboard_randomness(scancode | up_flag);