This was posted to xbox linux mailing list a long time ago. Just want to document this down. Work was done by chimpanzee for emulation of ENTER, ESC, directional keys of keyboard via xbox controller (xpad driver).
To patch against 2.4.31 kernel source.
CODE
Index: kernel/drivers/usb/xpad-core.c
===================================================================
RCS file: /cvsroot/xbox-linux/kernel/drivers/usb/xpad-core.c,v
retrieving revision 1.18
diff -u -r1.18 xpad-core.c
--- kernel/drivers/usb/xpad-core.c 12 Mar 2005 20:05:41 -0000 1.18
+++ kernel/drivers/usb/xpad-core.c 13 Jul 2005 14:50:00 -0000
@@ -100,7 +100,7 @@
BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* analogue buttons */
BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
BTN_0, BTN_1, BTN_2, BTN_3, /* d-pad as buttons */
- -1 /* terminating entry */
+ KEY_DOWN,KEY_UP,KEY_LEFT,KEY_RIGHT,KEY_ENTER,KEY_ESC,KEY_SPACE, /* keyboard simulation */
};
/* these have no analogue inputs and only 10 buttons */
@@ -109,7 +109,7 @@
BTN_START, BTN_BACK, /* start/back */
BTN_0, BTN_1, BTN_2, BTN_3, /* directions, LEFT/RIGHT is mouse
* so we cannot use those! */
- -1 /* terminating entry */
+ KEY_DOWN,KEY_UP,KEY_LEFT,KEY_RIGHT,KEY_ENTER,KEY_ESC,KEY_SPACE, /* keyboard simulation */
};
static signed short xpad_abs[] = {
@@ -291,6 +291,11 @@
remove_proc_entry( proc_name, xpad_procdir_units );
}
+static int keyboard = 101;
+
+MODULE_PARM( keyboard, "i" );
+MODULE_PARM_DESC( keyboard, "set to zero to de-activate keyboard support on insmod (default 101)" );
+
/*********************** the actual xpad functions ********************/
/**
* xpad_process_packet
@@ -306,21 +311,44 @@
struct input_dev *dev = &xpad->dev;
/* digital pad: bits (3 2 1 0) (right left down up) */
- input_report_key(dev, BTN_0, (data[2] & 0x01));
- input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3);
- input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1);
- input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2);
-
- /* start/back buttons and stick press left/right */
- input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
- input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
+ if (keyboard) {
+ input_report_key(dev, KEY_RIGHT, (data[2] & 0x08) >> 3);
+ input_report_key(dev, KEY_LEFT, (data[2] & 0x04) >> 2);
+ input_report_key(dev, KEY_DOWN, (data[2] & 0x02) >> 1);
+ input_report_key(dev, KEY_UP, (data[2] & 0x01));
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_0, (data[2] & 0x01));
+ input_report_key(dev, BTN_1, (data[2] & 0x08) >> 3);
+ input_report_key(dev, BTN_2, (data[2] & 0x02) >> 1);
+ input_report_key(dev, BTN_3, (data[2] & 0x04) >> 2);
+ }
+
+ /* start and back buttons */
+ if (keyboard%100 == 2) {
+ input_report_key(dev, KEY_ENTER, (data[2] & 0x10) >> 4);
+ input_report_key(dev, KEY_ESC, (data[2] & 0x20) >> 5);
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
+ input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
+ }
/* buttons A, B, X, Y digital mode */
- input_report_key(dev, BTN_A, data[4]);
- input_report_key(dev, BTN_B, data[5]);
- input_report_key(dev, BTN_X, data[6]);
- input_report_key(dev, BTN_Y, data[7]);
-
+ if (keyboard%100 == 1 || keyboard%100 > 3) {
+ input_report_key(dev, KEY_ENTER, data[4]);
+ input_report_key(dev, KEY_ESC, data[5]);
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_A, data[4]);
+ input_report_key(dev, BTN_B, data[5]);
+ }
+
+ if (keyboard%100 == 3) {
+ input_report_key(dev, KEY_ENTER, data[6]);
+ input_report_key(dev, KEY_ESC, data[7]);
+ } else if (keyboard < 100) {
+ input_report_key(dev, BTN_X, data[6]);
+ input_report_key(dev, BTN_Y, data[7]);
+ }
+
if (xpad->isMat)
return;
@@ -342,7 +370,9 @@
/* stick press left/right */
input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
+ if (keyboard) input_report_key(dev, KEY_SPACE, (data[2] & 0x40) >> 6);
input_report_key(dev, BTN_THUMBR, data[2] >> 7);
+ if (keyboard) input_report_key(dev, KEY_SPACE, data[2] >> 7);
/* buttons A, B, X, Y analogue mode */
input_report_abs(dev, ABS_HAT1X, data[4]);
@@ -351,11 +381,11 @@
input_report_abs(dev, ABS_HAT3X, data[7]);
/* button C (black) digital/analogue mode */
- input_report_key(dev, BTN_C, data[8]);
+ if (keyboard < 100) input_report_key(dev, BTN_C, data[8]);
input_report_abs(dev, ABS_HAT2X, data[8]);
/* button Z (white) digital/analogue mode */
- input_report_key(dev, BTN_Z, data[9]);
+ if (keyboard < 100) input_report_key(dev, BTN_Z, data[9]);
input_report_abs(dev, ABS_HAT3Y, data[9]);
/* process input data for mouse event generation */