Greetings,

Dmitry could use some input on this. 

On the hp6xx we got 3 external buttons (record / play / rewind), the status of 
those buttons can be read
from PGDR where each bit = one button. Value 0 means pressed key and value 1 
means non_pressed. I start out by reversing the bit values,
just to get it more logical.

When I bootup with this patch applied I get :
1 key is dead (maybe some weird keymap thingi.. probably logical)
2 keys give correct keymap output (B & C) but doesn't turn off when I release 
key so they keep adding. When I finally press enter
and "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb..... 
cccccccccccccccccccccccccccccccccccc.... : File name too long", the keys are 
dead.

I must be doing something wrong, so appreciate some guru input. Worth knowing 
is that when I just did a simple "printk(KERN_INFO "you press key X\n"); it 
works fine, its when I try to merge it with the keyboard that stuff get messed 
up.

Below is the critical section, its set at beginning of keyboard interrupt:
+       /* grab status byte for external keys */        
+       new_status = (~(inb(PGDR)));
+       old_status = jornadakbd->old_status;
+
+       diff = ((new_status) ^ (old_status));
+
+       if (diff > 0) {
+           /* Run through all extra keys */
+           for (i = 0; i < EXTERN_KEYS; i++) {
+               scancode = (129 + i);
+               /* Has this key changed? */
+               if (diff & (jornadakbd->status_regs[i])) {
+                   if (new_status & jornadakbd->status_regs[i]) {
+                       /* Key Pressed */
+                       input_event(input_dev, EV_MSC, MSC_SCAN, scancode);
+                       input_report_key(input_dev, keymap[scancode], 1);
+                   } else {
+                       /* Key Released */
+                       input_event(input_dev, EV_MSC, MSC_SCAN, scancode);
+                       input_report_key(input_dev, keymap[scancode], 0);
+                   }
+               }       
+               
+           }
+       jornadakbd->old_status = jornadakbd->new_status;
+       sync_me = 1;
+       }
+               



Entire patch :
--------------
diff --git a/drivers/input/keyboard/jornada680_kbd.c 
b/drivers/input/keyboard/jornada680_kbd.c
index a23633a..6f2ca27 100644
--- a/drivers/input/keyboard/jornada680_kbd.c
+++ b/drivers/input/keyboard/jornada680_kbd.c
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
+#include <asm/hp6xx.h>
 #include <asm/delay.h>
 #include <asm/io.h>
 
@@ -59,11 +60,12 @@ static const unsigned short jornada_scancodes[] = {
                KEY_W, KEY_E, KEY_R, KEY_O, KEY_I, KEY_U, KEY_T, KEY_Y,         
                        /* 105 -> 112 */
 /* PTE7 */     KEY_0, KEY_MINUS, KEY_EQUAL, 0, KEY_1, 0, 0, 0,                 
                        /* 113 -> 120 */
                KEY_2, KEY_3, KEY_4, KEY_9, KEY_8, KEY_7, KEY_5, KEY_6,         
                        /* 121 -> 128 */
-/* **** */     0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+/* **** */     KEY_A, KEY_B, KEY_C, 0, 0, 0, 0, 0, 0, 0,                       
                        /* 129 -> 136 */
                0, 0, 0, 0, 0
 };
 
-#define JORNADA_SCAN_SIZE      18
+#define JORNADA_SCAN_SIZE      16      /* 128 keys */
+#define EXTERN_KEYS            3       /* record / last / next */
 
 struct jornadakbd {
        struct input_polled_dev *poll_dev;
@@ -71,15 +73,50 @@ struct jornadakbd {
        unsigned char length;
        unsigned char old_scan[JORNADA_SCAN_SIZE];
        unsigned char new_scan[JORNADA_SCAN_SIZE];
+       unsigned char new_status;
+       unsigned char old_status;
+       unsigned char status_regs[EXTERN_KEYS];
 };
 
 static void jornada_parse_kbd(struct jornadakbd *jornadakbd)
 {
        struct input_dev *input_dev = jornadakbd->poll_dev->input;
        unsigned short *keymap = jornadakbd->keymap;
+       unsigned char old_status;
+       unsigned char new_status;
        unsigned int sync_me = 0;
        unsigned int i, j;
-
+       unsigned char diff, scancode;
+
+       /* grab status byte for external keys */        
+       new_status = (~(inb(PGDR)));
+       old_status = jornadakbd->old_status;
+
+       /* Want to reverse values at same time */
+       diff = ((new_status) ^ (old_status));
+
+       if (diff > 0) {
+           /* Run through all extra keys */
+           for (i = 0; i < EXTERN_KEYS; i++) {
+               scancode = (129 + i);
+               /* Has this key changed? */
+               if (diff & (jornadakbd->status_regs[i])) {
+                   if (new_status & jornadakbd->status_regs[i]) {
+                       /* Key Pressed */
+                       input_event(input_dev, EV_MSC, MSC_SCAN, scancode);
+                       input_report_key(input_dev, keymap[scancode], 1);
+                   } else {
+                       /* Key Released */
+                       input_event(input_dev, EV_MSC, MSC_SCAN, scancode);
+                       input_report_key(input_dev, keymap[scancode], 0);
+                   }
+               }       
+               
+           }
+       jornadakbd->old_status = jornadakbd->new_status;
+       sync_me = 1;
+       }
+               
        for (i = 0; i < JORNADA_SCAN_SIZE; i++) {
                unsigned char new = jornadakbd->new_scan[i];
                unsigned char old = jornadakbd->old_scan[i];
@@ -91,7 +128,7 @@ static void jornada_parse_kbd(struct jornadakbd *jornadakbd)
                for (j = 0; j < 8; j++) {
                        unsigned int bit = 1 << j;
                        if (xor & bit) {
-                               unsigned int scancode = (i << 3) + j;
+                               scancode = (i << 3) + j;
                                input_event(input_dev,
                                            EV_MSC, MSC_SCAN, scancode);
                                input_report_key(input_dev,
@@ -101,7 +138,7 @@ static void jornada_parse_kbd(struct jornadakbd *jornadakbd)
                        }
                }
        }
-
+       
        if (sync_me)
            input_sync(input_dev);
 }
@@ -165,8 +202,8 @@ static void jornada_scan_keyb(unsigned char *s)
        ctrl_outw((ec_static | (0x5555 & 0xf0cf)),PECR);
 
        /* Ignore extra keys and events */
-       *s++ = ctrl_inb(PGDR);
-       *s++ = ctrl_inb(PHDR);
+//     *s++ = ctrl_inb(PGDR);
+//     *s++ = ctrl_inb(PHDR);
 }
 
 static void jornadakbd680_poll(struct input_polled_dev *dev)
@@ -202,6 +239,11 @@ static int __devinit jornada680kbd_probe(struct 
platform_device *pdev)
        memcpy(jornadakbd->keymap, jornada_scancodes,
                sizeof(jornadakbd->keymap));
 
+       jornadakbd->status_regs[0] = 0x08;
+       jornadakbd->status_regs[1] = 0x10;
+       jornadakbd->status_regs[2] = 0x20;
+       jornadakbd->old_status = 0;
+
        poll_dev->private = jornadakbd;
        poll_dev->poll = jornadakbd680_poll;
        poll_dev->poll_interval = 50; /* msec */
@@ -216,11 +258,11 @@ static int __devinit jornada680kbd_probe(struct 
platform_device *pdev)
        input_dev->dev.parent = &pdev->dev;
        input_dev->id.bustype = BUS_HOST;
 
-       for (i = 0; i < 128; i++)
+       for (i = 0; i < 136; i++)
                if (jornadakbd->keymap[i])
                        __set_bit(jornadakbd->keymap[i], input_dev->keybit);
        __clear_bit(KEY_RESERVED, input_dev->keybit);
-
+       
        input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
        error = input_register_polled_device(jornadakbd->poll_dev);

Attachment: keyb_patch.patch
Description: Binary data

Reply via email to