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 | 60 ++++++++++++++++++++++++++++------- include/linux/i2c/tc35894xbg.h | 1 + 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/input/keyboard/tc35894xbg.c b/drivers/input/keyboard/tc35894xbg.c index 68e197d..244f4cf 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,60 @@ 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); + 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) { + for (i = 0; i < eventCount; i++) { + + event = event_queue[i]; - u8 key = keypad_whichkey(event); - int isdown = keypad_ispress(event); - unsigned short keycode = tc->pd.keymap[tc->keymap_index][key]; + /* 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 +614,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
