From: Ken Lierman <[email protected]>

The old driver does not support scan key. Some applications need it to build 
its keymap.

This patch adds scan key support. Driver sends MSC_SCAN events to userspace to 
ease task of 
adjusting keymap.

Signed-off-by: Bin Yang <[email protected]>
---
 drivers/input/keyboard/tc35894xbg.c |   73 ++++++++++++++++++++++++++++-------
 include/linux/i2c/tc35894xbg.h      |    1 +
 2 files changed, 60 insertions(+), 14 deletions(-)

diff --git a/drivers/input/keyboard/tc35894xbg.c 
b/drivers/input/keyboard/tc35894xbg.c
index 68e197d..321892f 100644
--- a/drivers/input/keyboard/tc35894xbg.c
+++ b/drivers/input/keyboard/tc35894xbg.c
@@ -194,7 +194,7 @@ static int keypad_configure(struct tc35894xbg_keypad_chip 
*tc)
        /* clear pending interrupts before irq enabled */
        keypad_write(tc, 2, TC_REG_KBDIC, (TC_VAL_EVTIC | TC_VAL_KBDIC));
 
-       /* Enable keycode lost intr & keyboard status intr */
+       /* disable keycode lost intr & keyboard status intr */
        keypad_write(tc, 2, TC_REG_KBDMSK, 0x00);
 
        return 0;
@@ -241,6 +241,7 @@ static void set_keymap_bit(struct tc35894xbg_keypad_chip 
*tc)
 static void report_shift_key(struct tc35894xbg_keypad_chip *tc, int isdown)
 {
        if (tc->kp_enabled) {
+               input_event(tc->idev, EV_MSC, MSC_SCAN, tc->pd.right_shift_key);
                input_report_key(tc->idev,
                        
tc->pd.keymap[TC_DEFAULT_KEYMAP][tc->pd.right_shift_key],
                        isdown);
@@ -267,6 +268,7 @@ static void submit_key(struct tc35894xbg_keypad_chip *tc, 
u8 key,
 
        /* report the key */
        if (tc->kp_enabled) {
+               input_event(tc->idev, EV_MSC, MSC_SCAN, key);
                input_report_key(tc->idev, (keycode & ~(SHIFT_NEEDED)), isdown);
                input_sync(tc->idev);
        }
@@ -282,28 +284,69 @@ static void submit_key(struct tc35894xbg_keypad_chip *tc, 
u8 key,
 static inline void process_keys(struct tc35894xbg_keypad_chip *tc)
 {
        u8 event;
+       u8 status;
        int ret, i = 0;
+       int eventCount = 0;
+       u8 key = 0;
+       int isdown = 0;
+       unsigned short keycode = 0;
        static u8 queue[TC35894XBG_MAX_FIFO];
+       static u8 event_queue[TC_EVENT_Q_MAX];
        static int tail;
 
-       ret = keypad_read(tc, TC_REG_EVTCODE, &event, 1);
-       if (ret < 0) {
+       memset(event_queue, 0x00, sizeof(event_queue));
+ 
+       for (i=0; i<TC_EVENT_Q_MAX; i++)
+       {
+               ret = keypad_read(tc, TC_REG_EVTCODE, &event, 1);
+               if (ret < 0) {
+                       dev_err(&tc->client->dev, "Failed reading fifo\n");
+                       /* clear event buffer */
+                       keypad_write(tc, 2, TC_REG_KBDIC, 0x83);
+                       return;
+               }
+               if (event == 0x7F || event == 0xFF)
+               {
+                       break;
+               }
+               else
+               {
+                       event_queue[eventCount++] = event;
+                       if (eventCount > TC_EVENT_Q_MAX)
+                       {
+                               dev_err(&tc->client->dev, "exceeded key 
fifo\n");
+                               eventCount = TC_EVENT_Q_MAX;
+                       }
+               }
+       }
+ 
+       /*
+        * Check for lost key events. If one occurred, log it
+        */
+       ret = keypad_read(tc, TC_REG_KBDRIS, &status, 1);
+       if (ret < 0)
+       {
                dev_err(&tc->client->dev, "Failed reading fifo\n");
-               /* clear event buffer */
-               keypad_write(tc, 2, TC_REG_KBDIC, 0x83);
-               return;
+       }
+       else
+       {
+               if (status & TC_VAL_RELINT)
+               {
+                       dev_err(&tc->client->dev, "Lost a key event\n");
+               }
        }
 
        /* clear event buffer */
        keypad_write(tc, 2, TC_REG_KBDIC, 0x83);
 
-       i = 0;
-       /* modified feature enable on KBDMFS */
-       if (event != 0x7F && event != 0xFF) {
-
-               u8 key = keypad_whichkey(event);
-               int isdown = keypad_ispress(event);
-               unsigned short keycode = tc->pd.keymap[tc->keymap_index][key];
+       for (i = 0; i < eventCount; i++) {
+ 
+               event = event_queue[i];
+ 
+               /* modified feature enable on KBDMFS */
+               key = keypad_whichkey(event);
+               isdown = keypad_ispress(event);
+               keycode = tc->pd.keymap[tc->keymap_index][key];
 
                /* The function key pressed */
                if ((key == tc->pd.function_key) && isdown) {
@@ -580,7 +623,9 @@ keypad_probe(struct i2c_client *client, const struct 
i2c_device_id *id)
                                        dev_name(&client->dev));
        idev->phys = tc->phys;
        /* the two bit set */
-       idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
+       idev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_MSC) | BIT(EV_REP);
+       __set_bit(MSC_SCAN, idev->mscbit);
+       __set_bit(EV_REP, idev->evbit);
 
        tc->keymap_index = TC_DEFAULT_KEYMAP;
        set_keymap_bit(tc);
diff --git a/include/linux/i2c/tc35894xbg.h b/include/linux/i2c/tc35894xbg.h
index 6cb9c03..f2ef149 100644
--- a/include/linux/i2c/tc35894xbg.h
+++ b/include/linux/i2c/tc35894xbg.h
@@ -44,6 +44,7 @@
 #define TC_DEFAULT_KEYMAP       (0)
 #define TC_ALT_KEYMAP           (1)
 #define TC35894XBG_MAX_FIFO     (8)
+#define TC_EVENT_Q_MAX          (8)
 
 
 struct tc35894xbg_platform_data {
-- 
1.7.0.4

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to