public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
From: lamikr <lamikr@cc.jyu.fi>
To: Tony Lindgren <tony@atomide.com>
Cc: linux-omap-open-source@linux.omap.com
Subject: Re: [PATCH] keypad: platform_data and 24xx support -exp
Date: Sat, 14 Jan 2006 04:04:17 +0200	[thread overview]
Message-ID: <43C85C21.6030202@cc.jyu.fi> (raw)
In-Reply-To: <20060114003728.GJ5499@atomide.com>

[-- Attachment #1: Type: text/plain, Size: 1205 bytes --]

Has anybody needed a joypad driver for the omap-boards? 
I have made changes to keypad driver so that it will support h6300 joypad ok, but I think my approach is a little bit hackish.
The iPAQ h6300 joypad has 5 sensors that are located in following diagonal locations

	UL - Up/Left
	DL - Down/Left
	DR - Down/Right
	UR - Up/Right
	CT - Center

If I press the key-pad for example to North, the joypad will generate 3 keydown events. (CT, UL and UR)
Same logic applies to all 4 main directions both when the key is pressed down or released.
Therefore I have put the driver to listen the real sensor events, but instead of sending them to userspace
I will calculate a "virtual" key event (up, right, down or left) and send that to the userspace.

I am not yet proposing this patch to be applied to omap kernel, but would anyway like to hear
some suggestions how to handle this kind of situation.

Mika

>I like this patch, takes care of the keypad mapping problems nicely.
>Can you please refresh it?
>
>Tony
>_______________________________________________
>Linux-omap-open-source mailing list
>Linux-omap-open-source@linux.omap.com
>http://linux.omap.com/mailman/listinfo/linux-omap-open-source
>
>  
>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: h6300_omap_keypad.patch --]
[-- Type: text/x-patch; name="h6300_omap_keypad.patch", Size: 10009 bytes --]

diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 7e851e2..157ef8d 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -5,10 +5,11 @@
  *
  * Copyright (C) 2003 Nokia Corporation
  * Written by Timo Teräs <ext-timo.teras@nokia.com>
+ * iPAQ h6300 key and joypad support added by Mika Laitio. (2005)
  *
  * Added support for H2 & H3 Keypad
  * Copyright (C) 2004 Texas Instruments
- *
+ * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -41,13 +42,16 @@
 #include <asm/arch/mux.h>
 
 #undef NEW_BOARD_LEARNING_MODE
+//#define NEW_BOARD_LEARNING_MODE 1
 
 static void omap_kp_tasklet(unsigned long);
-static void omap_kp_timer(unsigned long);
+static void omap_§kp_timer(unsigned long);
 
 static unsigned char keypad_state[8];
 static unsigned int keypad_irq = INT_KEYBOARD;
 
+static int prevJoypadKeycodePressEmulated;
+
 struct omap_kp {
 	struct input_dev *input;
 	struct timer_list timer;
@@ -169,6 +173,47 @@ static int p2_keymap[] = {
 	0
 };
 
+#define _h6300_KEY_CALENDAR	67 	// xmodmap 75 aka F9
+#define _H6300_KEY_TELEPHONE	68 	// xmodmap 76 aka F10
+#define _H6300_KEY_HOMEPAGE	87 	// xmodmap 87 aka Num_Lock
+#define _H6300_KEY_MAIL		88 	// xmodmap 88 aka Scroll_Lock
+
+/*
+ * Following 5 keypad events are not really sent to userspace. 
+ * Instead if the good combination of them is sent, then that is send.
+ * (up, right, down, left, enter)
+ */
+#define	_H6300_JOYPAD_UP_RIGHT		1	// 00001
+#define _H6300_JOYPAD_DOWN_RIGHT	2	// 00010
+#define _h6300_JOYPAD_DOWN_LEFT		4	// 00100
+#define _h6300_JOYPAD_UP_LEFT		8	// 01000
+#define _H6300_JOYPAD_KEY_OK		16	// 10000
+
+static int h6300_keymap[] = {
+	KEY(2, 0, _h6300_KEY_CALENDAR),		// address button in the bottom left	
+	KEY(2, 3, _H6300_KEY_TELEPHONE),	// start call button in the bottom
+	KEY(3, 1, _H6300_KEY_HOMEPAGE),		// stop call button in the bottom
+	KEY(3, 4, _H6300_KEY_MAIL),		// messaging button in the bottom right
+
+	KEY(0, 0, KEY_VOLUMEUP),	// volume up button in the right side
+	KEY(0, 1, KEY_VOLUMEDOWN),	// volume down button in the right side
+	KEY(3, 2, KEY_RECORD),		// record button in the left side
+	
+	KEY(1, 0, _h6300_JOYPAD_UP_LEFT),	
+	KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT),	
+	KEY(1, 2, _H6300_JOYPAD_KEY_OK),		
+	KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT),
+	KEY(1, 4, _H6300_JOYPAD_UP_RIGHT),	
+	
+	KEY(5, 0, KEY_RIGHT),
+	KEY(5, 1, KEY_DOWN),
+	KEY(5, 2, KEY_LEFT),		
+	KEY(5, 3, KEY_UP),
+	KEY(5, 4, KEY_ENTER),
+
+	0
+};
+
 static int *keymap;
 
 static irqreturn_t omap_kp_interrupt(int irq, void *dev_id,
@@ -195,7 +240,8 @@ static void omap_kp_scan_keypad(unsigned
 	for (col = 0; col < 8; col++) {
 		omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
 
-		if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
+		if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()  || machine_is_h6300()) {
+			// makes keyboard act a little bit slower
 			udelay(9);
 		} else {
 			udelay(4);
@@ -218,17 +264,26 @@ static inline int omap_kp_find_key(int c
 	return -1;
 }
 
+int is_key_down(unsigned char new_state[],
+		int col,
+		int row)
+{
+	return (new_state[col] & (1 << row)) ? 1 : 0;
+}
+
 static void omap_kp_tasklet(unsigned long data)
 {
 	struct omap_kp *omap_kp_data = (struct omap_kp *) data;
 	unsigned char new_state[8], changed, key_down = 0;
 	int col, row;
 	int spurious = 0;
+	int report_key, report_col, report_row, joypad_checked;	// h6300-joypad specific variables
 
 	/* check for any changes */
 	omap_kp_scan_keypad(new_state);
 
 	/* check for changes and print those */
+	joypad_checked	= 0;
 	for (col = 0; col < 8; col++) {
 		changed = new_state[col] ^ keypad_state[col];
 		key_down |= new_state[col];
@@ -250,9 +305,173 @@ static void omap_kp_tasklet(unsigned lon
 				spurious = 1;
 				continue;
 			}
-
-			input_report_key(omap_kp_data->input, key,
-					 new_state[col] & (1 << row));
+ 			if (machine_is_h6300() && 
+ 			   ((col == 1) || (col == 5)))
+ 			{
+ 				if (col == 5)
+ 				{
+ 					continue;
+ 				}
+ 				if ((joypad_checked == 0) &&
+ 				    ((key == _H6300_JOYPAD_KEY_OK) ||
+ 				     (key == _h6300_JOYPAD_UP_LEFT) ||
+ 	    			     (key == _H6300_JOYPAD_UP_RIGHT) ||
+ 				     (key == _H6300_JOYPAD_DOWN_RIGHT) ||
+ 				     (key == _h6300_JOYPAD_DOWN_LEFT)))
+ 				{
+ 					if (is_key_down(new_state, col, row))
+ 					{
+ 						/*
+ 						 * only enter pressed
+ 						 * 1 0 0 _H6300_JOYPAD_KEY_OK 0 0
+ 						 * --> 100100 == 36
+ 						 */
+ 						 if (new_state[1] == 36)
+ 						 {
+ 						 	joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_ENTER;
+ 							new_state[5]	= 48;	//110000
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= 5;
+ 							report_row	= 4;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						 }						
+ 						/*
+ 						 * enter, up_left and up_right sensors pressed.
+ 						 * 1 _H6300_JOYPAD_UP_RIGHT 0 _H6300_JOYPAD_KEY_OK 0 _h6300_JOYPAD_UP_LEFT
+ 						 * --> 110101 == 53
+ 						 * OR
+ 						 * 1 KEY_UP_RIGHT 0 0 0 _h6300_JOYPAD_UP_LEFT
+ 						 * --> 110001 == 42
+ 						 * --> move to up
+ 						 */
+ 						else if ((new_state[1] == 53) ||
+ 						         (new_state[1] == 49))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_UP;
+ 							new_state[5]	= 40;	//101000
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= 5;
+ 							report_row	= 3;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}
+ 						/*
+ 						 * enter, down_left and down_right sensors pressed
+ 						 * --> 101110 == 46
+ 						 * OR
+ 						 * down_left and down_right
+ 						 * -->101010 == 42
+ 						 * --> move to down
+ 						 */
+ 						else if ((new_state[1] == 46) ||
+ 							 (new_state[1] == 42))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_DOWN;
+ 							new_state[5]	= 34;	//100010
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= 5;
+ 							report_row	= 1;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}												
+ 						/*
+ 						 * enter, up_right and down_right sensors pressed
+ 						 * --> 111100 == 60
+ 						 * or
+ 						 * down_right and up_right
+ 						 * --> 111000 == 56
+ 						 * --> move to right
+ 						 */
+ 						else if ((new_state[1] == 60) ||
+ 							 (new_state[1] == 56))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_RIGHT;
+ 							new_state[5]	= 33;	//100001
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= 5;
+ 							report_row	= 0;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}
+ 						/*
+ 						 * enter, up_left and down_left sensors pressed
+ 						 * --> 100111 == 39
+ 						 * or up_left and down_left
+ 						 * --> 100011 == 35
+ 						 * --> move to left
+ 						 */
+ 						else if ((new_state[1] == 39) ||
+ 							 (new_state[1] == 35))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_LEFT;
+ 							new_state[5]	= 36;	//100100
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= 5;
+ 							report_row	= 2;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}
+ 						else
+ 						{
+ 							//printk("missed new_state = %d\n", new_state[1]);
+ 						}
+ 					}
+ 					else
+ 					{
+ 						if (prevJoypadKeycodePressEmulated != 0)
+ 						{
+ 							// report key up event
+ 							joypad_checked	= 1;
+ 							new_state[5]	= 32;	//100000
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= 5;
+ 							switch(prevJoypadKeycodePressEmulated)
+ 							{
+ 								case KEY_RIGHT:
+									report_row	= 0;
+ 									break;
+ 								case KEY_DOWN:
+ 									report_row	= 1;
+ 									break;
+ 								case KEY_LEFT:
+ 									report_row	= 2;
+ 									break;
+ 								case KEY_UP:
+ 									report_row	= 3;
+ 									break;
+ 								case KEY_ENTER:
+ 									report_row	= 4;
+ 									break;
+ 								default:
+ 									printk(KERN_WARNING "Unknown iPAQ h6300 column 1 key = %d released. This should newer happen!\n",
+ 										key);
+ 									report_row	= 0;
+ 							}
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 							prevJoypadKeycodePressEmulated	= 0;
+ 						}
+ 					}
+ 				}
+ 			}
+ 			else
+ 			{
+ 				input_report_key(omap_kp_data->input, // &omap_kp_dev, 
+ 						key,
+ 						new_state[col] & (1 << row));
+ 			}
 #endif
 		}
 	}
@@ -321,9 +540,15 @@ static int __init omap_kp_probe(struct p
 	} else if (machine_is_omap_perseus2()) {
 		keymap = p2_keymap;
 		keypad_irq = INT_730_MPUIO_KEYPAD;
+	} else if (machine_is_h6300()) {
+		keymap = h6300_keymap;
+		// set keyboard to send repeated key events if key is hold down
+		set_bit(EV_REP, §.evbit);
 	} else {
+		printk("omap_keypad.c, keyMap = test_keymap\n");
 		keymap = test_keymap;
 	}
+	prevJoypadKeycodePressEmulated		= 0;
 
 	init_timer(&omap_kp->timer);
 	omap_kp->timer.function = omap_kp_timer;

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



  reply	other threads:[~2006-01-14  2:04 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-12-10 13:02 [PATCH] keypad: platform_data and 24xx support -exp Komal Shah
2006-01-14  0:37 ` Tony Lindgren
2006-01-14  2:04   ` lamikr [this message]
2006-01-20 23:02     ` Tony Lindgren
2006-01-20 23:27       ` lamikr

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43C85C21.6030202@cc.jyu.fi \
    --to=lamikr@cc.jyu.fi \
    --cc=linux-omap-open-source@linux.omap.com \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox