aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/rc/ati_remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/rc/ati_remote.c')
-rw-r--r--drivers/media/rc/ati_remote.c146
1 files changed, 109 insertions, 37 deletions
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c
index baf907b3ce76..7be377fc1be8 100644
--- a/drivers/media/rc/ati_remote.c
+++ b/drivers/media/rc/ati_remote.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * USB ATI Remote support 2 * USB ATI Remote support
3 * 3 *
4 * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi> 4 * Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi>
5 * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net> 5 * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
6 * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev 6 * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
7 * 7 *
@@ -151,13 +151,57 @@ MODULE_PARM_DESC(mouse, "Enable mouse device, default = yes");
151#undef err 151#undef err
152#define err(format, arg...) printk(KERN_ERR format , ## arg) 152#define err(format, arg...) printk(KERN_ERR format , ## arg)
153 153
154struct ati_receiver_type {
155 /* either default_keymap or get_default_keymap should be set */
156 const char *default_keymap;
157 const char *(*get_default_keymap)(struct usb_interface *interface);
158};
159
160static const char *get_medion_keymap(struct usb_interface *interface)
161{
162 struct usb_device *udev = interface_to_usbdev(interface);
163
164 /*
165 * There are many different Medion remotes shipped with a receiver
166 * with the same usb id, but the receivers have subtle differences
167 * in the USB descriptors allowing us to detect them.
168 */
169
170 if (udev->manufacturer && udev->product) {
171 if (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP) {
172
173 if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc")
174 && !strcmp(udev->product, "USB Receiver"))
175 return RC_MAP_MEDION_X10_DIGITAINER;
176
177 if (!strcmp(udev->manufacturer, "X10 WTI")
178 && !strcmp(udev->product, "RF receiver"))
179 return RC_MAP_MEDION_X10_OR2X;
180 } else {
181
182 if (!strcmp(udev->manufacturer, "X10 Wireless Technology Inc")
183 && !strcmp(udev->product, "USB Receiver"))
184 return RC_MAP_MEDION_X10;
185 }
186 }
187
188 dev_info(&interface->dev,
189 "Unknown Medion X10 receiver, using default ati_remote Medion keymap\n");
190
191 return RC_MAP_MEDION_X10;
192}
193
194static const struct ati_receiver_type type_ati = { .default_keymap = RC_MAP_ATI_X10 };
195static const struct ati_receiver_type type_medion = { .get_default_keymap = get_medion_keymap };
196static const struct ati_receiver_type type_firefly = { .default_keymap = RC_MAP_SNAPSTREAM_FIREFLY };
197
154static struct usb_device_id ati_remote_table[] = { 198static struct usb_device_id ati_remote_table[] = {
155 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 199 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
156 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 200 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
157 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 201 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
158 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_ATI_X10 }, 202 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_ati },
159 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_MEDION_X10 }, 203 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_medion },
160 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)RC_MAP_SNAPSTREAM_FIREFLY }, 204 { USB_DEVICE(ATI_REMOTE_VENDOR_ID, FIREFLY_REMOTE_PRODUCT_ID), .driver_info = (unsigned long)&type_firefly },
161 {} /* Terminating entry */ 205 {} /* Terminating entry */
162}; 206};
163 207
@@ -445,6 +489,7 @@ static void ati_remote_input_report(struct urb *urb)
445 int acc; 489 int acc;
446 int remote_num; 490 int remote_num;
447 unsigned char scancode; 491 unsigned char scancode;
492 u32 wheel_keycode = KEY_RESERVED;
448 int i; 493 int i;
449 494
450 /* 495 /*
@@ -484,26 +529,33 @@ static void ati_remote_input_report(struct urb *urb)
484 */ 529 */
485 scancode = data[2] & 0x7f; 530 scancode = data[2] & 0x7f;
486 531
487 /* Look up event code index in the mouse translation table. */ 532 dbginfo(&ati_remote->interface->dev,
488 for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { 533 "channel 0x%02x; key data %02x, scancode %02x\n",
489 if (scancode == ati_remote_tbl[i].data) { 534 remote_num, data[2], scancode);
490 index = i; 535
491 break; 536 if (scancode >= 0x70) {
537 /*
538 * This is either a mouse or scrollwheel event, depending on
539 * the remote/keymap.
540 * Get the keycode assigned to scancode 0x78/0x70. If it is
541 * set, assume this is a scrollwheel up/down event.
542 */
543 wheel_keycode = rc_g_keycode_from_table(ati_remote->rdev,
544 scancode & 0x78);
545
546 if (wheel_keycode == KEY_RESERVED) {
547 /* scrollwheel was not mapped, assume mouse */
548
549 /* Look up event code index in the mouse translation table. */
550 for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
551 if (scancode == ati_remote_tbl[i].data) {
552 index = i;
553 break;
554 }
555 }
492 } 556 }
493 } 557 }
494 558
495 if (index >= 0) {
496 dbginfo(&ati_remote->interface->dev,
497 "channel 0x%02x; mouse data %02x; index %d; keycode %d\n",
498 remote_num, data[2], index, ati_remote_tbl[index].code);
499 if (!dev)
500 return; /* no mouse device */
501 } else
502 dbginfo(&ati_remote->interface->dev,
503 "channel 0x%02x; key data %02x, scancode %02x\n",
504 remote_num, data[2], scancode);
505
506
507 if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { 559 if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) {
508 input_event(dev, ati_remote_tbl[index].type, 560 input_event(dev, ati_remote_tbl[index].type,
509 ati_remote_tbl[index].code, 561 ati_remote_tbl[index].code,
@@ -542,15 +594,29 @@ static void ati_remote_input_report(struct urb *urb)
542 594
543 if (index < 0) { 595 if (index < 0) {
544 /* Not a mouse event, hand it to rc-core. */ 596 /* Not a mouse event, hand it to rc-core. */
545 597 int count = 1;
546 /* 598
547 * We don't use the rc-core repeat handling yet as 599 if (wheel_keycode != KEY_RESERVED) {
548 * it would cause ghost repeats which would be a 600 /*
549 * regression for this driver. 601 * This is a scrollwheel event, send the
550 */ 602 * scroll up (0x78) / down (0x70) scancode
551 rc_keydown_notimeout(ati_remote->rdev, scancode, 603 * repeatedly as many times as indicated by
552 data[2]); 604 * rest of the scancode.
553 rc_keyup(ati_remote->rdev); 605 */
606 count = (scancode & 0x07) + 1;
607 scancode &= 0x78;
608 }
609
610 while (count--) {
611 /*
612 * We don't use the rc-core repeat handling yet as
613 * it would cause ghost repeats which would be a
614 * regression for this driver.
615 */
616 rc_keydown_notimeout(ati_remote->rdev, scancode,
617 data[2]);
618 rc_keyup(ati_remote->rdev);
619 }
554 return; 620 return;
555 } 621 }
556 622
@@ -766,6 +832,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
766 struct usb_device *udev = interface_to_usbdev(interface); 832 struct usb_device *udev = interface_to_usbdev(interface);
767 struct usb_host_interface *iface_host = interface->cur_altsetting; 833 struct usb_host_interface *iface_host = interface->cur_altsetting;
768 struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; 834 struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
835 struct ati_receiver_type *type = (struct ati_receiver_type *)id->driver_info;
769 struct ati_remote *ati_remote; 836 struct ati_remote *ati_remote;
770 struct input_dev *input_dev; 837 struct input_dev *input_dev;
771 struct rc_dev *rc_dev; 838 struct rc_dev *rc_dev;
@@ -827,10 +894,15 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
827 snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name), 894 snprintf(ati_remote->mouse_name, sizeof(ati_remote->mouse_name),
828 "%s mouse", ati_remote->rc_name); 895 "%s mouse", ati_remote->rc_name);
829 896
830 if (id->driver_info) 897 rc_dev->map_name = RC_MAP_ATI_X10; /* default map */
831 rc_dev->map_name = (const char *)id->driver_info; 898
832 else 899 /* set default keymap according to receiver model */
833 rc_dev->map_name = RC_MAP_ATI_X10; 900 if (type) {
901 if (type->default_keymap)
902 rc_dev->map_name = type->default_keymap;
903 else if (type->get_default_keymap)
904 rc_dev->map_name = type->get_default_keymap(interface);
905 }
834 906
835 ati_remote_rc_init(ati_remote); 907 ati_remote_rc_init(ati_remote);
836 mutex_init(&ati_remote->open_mutex); 908 mutex_init(&ati_remote->open_mutex);