|
@@ -1,7 +1,7 @@
|
|
|
/*
|
|
|
* USB ATI Remote support
|
|
|
*
|
|
|
- * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi>
|
|
|
+ * Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi>
|
|
|
* Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
|
|
|
* Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
|
|
|
*
|
|
@@ -157,8 +157,20 @@ struct ati_receiver_type {
|
|
|
const char *(*get_default_keymap)(struct usb_interface *interface);
|
|
|
};
|
|
|
|
|
|
+static const char *get_medion_keymap(struct usb_interface *interface)
|
|
|
+{
|
|
|
+ struct usb_device *udev = interface_to_usbdev(interface);
|
|
|
+
|
|
|
+ /* The receiver shipped with the "Digitainer" variant helpfully has
|
|
|
+ * a single additional bit set in its descriptor. */
|
|
|
+ if (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP)
|
|
|
+ return RC_MAP_MEDION_X10_DIGITAINER;
|
|
|
+
|
|
|
+ return RC_MAP_MEDION_X10;
|
|
|
+}
|
|
|
+
|
|
|
static const struct ati_receiver_type type_ati = { .default_keymap = RC_MAP_ATI_X10 };
|
|
|
-static const struct ati_receiver_type type_medion = { .default_keymap = RC_MAP_MEDION_X10 };
|
|
|
+static const struct ati_receiver_type type_medion = { .get_default_keymap = get_medion_keymap };
|
|
|
static const struct ati_receiver_type type_firefly = { .default_keymap = RC_MAP_SNAPSTREAM_FIREFLY };
|
|
|
|
|
|
static struct usb_device_id ati_remote_table[] = {
|
|
@@ -455,6 +467,7 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
int acc;
|
|
|
int remote_num;
|
|
|
unsigned char scancode;
|
|
|
+ u32 wheel_keycode = KEY_RESERVED;
|
|
|
int i;
|
|
|
|
|
|
/*
|
|
@@ -494,26 +507,33 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
*/
|
|
|
scancode = data[2] & 0x7f;
|
|
|
|
|
|
- /* Look up event code index in the mouse translation table. */
|
|
|
- for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
|
|
|
- if (scancode == ati_remote_tbl[i].data) {
|
|
|
- index = i;
|
|
|
- break;
|
|
|
+ dbginfo(&ati_remote->interface->dev,
|
|
|
+ "channel 0x%02x; key data %02x, scancode %02x\n",
|
|
|
+ remote_num, data[2], scancode);
|
|
|
+
|
|
|
+ if (scancode >= 0x70) {
|
|
|
+ /*
|
|
|
+ * This is either a mouse or scrollwheel event, depending on
|
|
|
+ * the remote/keymap.
|
|
|
+ * Get the keycode assigned to scancode 0x78/0x70. If it is
|
|
|
+ * set, assume this is a scrollwheel up/down event.
|
|
|
+ */
|
|
|
+ wheel_keycode = rc_g_keycode_from_table(ati_remote->rdev,
|
|
|
+ scancode & 0x78);
|
|
|
+
|
|
|
+ if (wheel_keycode == KEY_RESERVED) {
|
|
|
+ /* scrollwheel was not mapped, assume mouse */
|
|
|
+
|
|
|
+ /* Look up event code index in the mouse translation table. */
|
|
|
+ for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
|
|
|
+ if (scancode == ati_remote_tbl[i].data) {
|
|
|
+ index = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (index >= 0) {
|
|
|
- dbginfo(&ati_remote->interface->dev,
|
|
|
- "channel 0x%02x; mouse data %02x; index %d; keycode %d\n",
|
|
|
- remote_num, data[2], index, ati_remote_tbl[index].code);
|
|
|
- if (!dev)
|
|
|
- return; /* no mouse device */
|
|
|
- } else
|
|
|
- dbginfo(&ati_remote->interface->dev,
|
|
|
- "channel 0x%02x; key data %02x, scancode %02x\n",
|
|
|
- remote_num, data[2], scancode);
|
|
|
-
|
|
|
-
|
|
|
if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
|
|
|
input_event(dev, ati_remote_tbl[index].type,
|
|
|
ati_remote_tbl[index].code,
|
|
@@ -552,15 +572,29 @@ static void ati_remote_input_report(struct urb *urb)
|
|
|
|
|
|
if (index < 0) {
|
|
|
/* Not a mouse event, hand it to rc-core. */
|
|
|
-
|
|
|
- /*
|
|
|
- * We don't use the rc-core repeat handling yet as
|
|
|
- * it would cause ghost repeats which would be a
|
|
|
- * regression for this driver.
|
|
|
- */
|
|
|
- rc_keydown_notimeout(ati_remote->rdev, scancode,
|
|
|
- data[2]);
|
|
|
- rc_keyup(ati_remote->rdev);
|
|
|
+ int count = 1;
|
|
|
+
|
|
|
+ if (wheel_keycode != KEY_RESERVED) {
|
|
|
+ /*
|
|
|
+ * This is a scrollwheel event, send the
|
|
|
+ * scroll up (0x78) / down (0x70) scancode
|
|
|
+ * repeatedly as many times as indicated by
|
|
|
+ * rest of the scancode.
|
|
|
+ */
|
|
|
+ count = (scancode & 0x07) + 1;
|
|
|
+ scancode &= 0x78;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (count--) {
|
|
|
+ /*
|
|
|
+ * We don't use the rc-core repeat handling yet as
|
|
|
+ * it would cause ghost repeats which would be a
|
|
|
+ * regression for this driver.
|
|
|
+ */
|
|
|
+ rc_keydown_notimeout(ati_remote->rdev, scancode,
|
|
|
+ data[2]);
|
|
|
+ rc_keyup(ati_remote->rdev);
|
|
|
+ }
|
|
|
return;
|
|
|
}
|
|
|
|