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 --]
next prev parent 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