diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 79e3edc..17e71e2 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -94,6 +94,7 @@
 #define XTYPE_XBOX360     1
 #define XTYPE_XBOX360W    2
 #define XTYPE_UNKNOWN     3
+#define XTYPE_XBOX360BB   4
 
 static int dpad_to_buttons;
 module_param(dpad_to_buttons, bool, S_IRUGO);
@@ -147,6 +148,7 @@ static const struct xpad_device {
 	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
+	{ 0x045e, 0x02a0, "Microsoft X-Box 360 Big Button IR reciever", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360BB },
 	{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
 };
 
@@ -192,7 +194,9 @@ static const signed short xpad_abs_pad[] = {
 /* Xbox 360 has a vendor-specific class, so we cannot match it with only
  * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
  * match against vendor id as well. Wired Xbox 360 devices have protocol 1,
- * wireless controllers have protocol 129. */
+ * wireless controllers have protocol 129, and big button controllers
+ * have protocol 4.
+ */
 #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
 	.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
 	.idVendor = (vend), \
@@ -201,7 +205,8 @@ static const signed short xpad_abs_pad[] = {
 	.bInterfaceProtocol = (pr)
 #define XPAD_XBOX360_VENDOR(vend) \
 	{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
-	{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
+	{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) },	\
+	{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,4) }
 
 static struct usb_device_id xpad_table [] = {
 	{ USB_INTERFACE_INFO('X', 'B', 0) },	/* X-Box USB-IF not approved class */
@@ -407,6 +412,98 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
 	xpad360_process_packet(xpad, cmd, &data[4]);
 }
 
+/* xpad360bb_momentary_press
+ *
+ * Just a little utility routine, to momentarily press a button.
+ */
+static void xpad360bb_momentary_press(struct input_dev *dev, int button, int val) {
+	input_report_key(dev, button, val);
+	if (val) {
+		input_report_key(dev, button, 0);
+	}
+}
+
+/* 
+ * xpad360bb_process_packet
+ *
+ * Completes a request by converting the data into events for the
+ * input subsystem.  It is a version for the xbox 360 big-button
+ * controller, as shipped with the Scene It series of games.
+ *
+ * This is original reverse-engeneering work.
+ */
+
+static void xpad360bb_process_packet(struct usb_xpad *xpad,
+				     u16 cmd, unsigned char *data) {
+	struct input_dev *dev = xpad->dev;
+	
+	printk("cmd=%d, data=%x %x %x %x %x\n", cmd, 
+	       data[0], data[1], data[2], data[3], data[4]);
+	/* Protocol is as follows:
+	 * cmd=0, data=0 5 ct ab cd
+	 * 0 and 5 seem to be constant.  It might specify the length
+	 * of the report.
+	 * ct specifies what controller, 0=green, 1=red, 2=blue, 3=yellow
+	 * ab is serveral keys for that controller:
+         * 0x01: up.
+	 * 0x02: down.
+	 * 0x04: left.
+	 * 0x08: right.
+	 * 0x10: start.
+	 * 0x20: back.
+	 * cd is several more:
+	 * 0x08: centre (buzzer)
+	 * 0x04: big x (logo, mode)
+	 * 0x10: A
+	 * 0x20: B
+	 * 0x40: X
+	 * 0x80: Y
+	 * 
+	 * ...and that's all the buttons there are.
+	 * 
+	 * Only presses are reported, not releases -- that is, there
+	 * will never be a report with all zeroes.  OTOH, it will
+	 * report multiple times if you hold down a button.  Ideally,
+	 * we'd have some sort of timeout mechanism such that we
+	 * notice that the next repeat event doesn't happen, and thus
+	 * the key must have been released (or we went out of range).
+	 * Instead, for now, we just report everything as a press
+	 * followed immediately by a release, and let the native
+	 * repeat repeat.
+	 */
+
+	/* The code below doesn't allow userspace to tell which
+	 * controler is being used.  FIXME! */
+	
+	/* dpad as four buttons... */
+	xpad360bb_momentary_press(dev, BTN_LEFT,  data[3] & 0x04);
+	xpad360bb_momentary_press(dev, BTN_RIGHT, data[3] & 0x08);
+	xpad360bb_momentary_press(dev, BTN_0,     data[3] & 0x01); /* up */
+	xpad360bb_momentary_press(dev, BTN_1,     data[3] & 0x02); /* down */
+	
+	/* This is the only button that is rather novel vs the normal
+	 * controller.  The corsponding bit for the normal controllers
+	 * isn't used, as far as I can see.  It's like the thumb
+	 * buttons, so call it the right one, randomly.
+	 * (Normally the thumb button goes with an analog stick, not a dpad.)
+	 */
+	xpad360bb_momentary_press(dev, BTN_THUMBR,    data[4] & 0x08);
+
+	/* start/back buttons */
+	xpad360bb_momentary_press(dev, BTN_START, data[3] & 0x10);
+	xpad360bb_momentary_press(dev, BTN_BACK,  data[3] & 0x20);
+
+	/* buttons A,B,X,Y,TL,TR and MODE */
+	xpad360bb_momentary_press(dev, BTN_A,	 data[4] & 0x10);
+	xpad360bb_momentary_press(dev, BTN_B,	 data[4] & 0x20);
+	xpad360bb_momentary_press(dev, BTN_X,	 data[4] & 0x40);
+	xpad360bb_momentary_press(dev, BTN_Y,	 data[4] & 0x80);
+	xpad360bb_momentary_press(dev, BTN_MODE, data[4] & 0x04);
+
+	
+	input_sync(dev);
+}
+
 static void xpad_irq_in(struct urb *urb)
 {
 	struct usb_xpad *xpad = urb->context;
@@ -438,6 +535,9 @@ static void xpad_irq_in(struct urb *urb)
 	case XTYPE_XBOX360W:
 		xpad360w_process_packet(xpad, 0, xpad->idata);
 		break;
+	case XTYPE_XBOX360BB:
+		xpad360bb_process_packet(xpad, 0, xpad->idata);
+		break;
 	default:
 		xpad_process_packet(xpad, 0, xpad->idata);
 	}
@@ -728,6 +828,11 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
 	int i;
 	int error = -ENOMEM;
 
+	printk("xpad_probe vendor=0x%x, product=0x%x\n", 
+	       le16_to_cpu(udev->descriptor.idVendor),
+	       le16_to_cpu(udev->descriptor.idProduct)
+		);
+
 	for (i = 0; xpad_device[i].idVendor; i++) {
 		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
 		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
