[Meego-kernel] [PATCH 4/5] tc35894xbg: add key events

Bin Yang bin.yang at intel.com
Wed Nov 24 01:46:14 PST 2010


From: Ken Lierman <kenx.lierman at intel.com>

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 <bin.yang at intel.com>
---
 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



More information about the MeeGo-kernel mailing list