All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.